162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2009 ST-Ericsson SA 462306a36Sopenharmony_ci * Copyright (C) 2009 STMicroelectronics 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * I2C master mode controller driver, used in Nomadik 8815 762306a36Sopenharmony_ci * and Ux500 platforms. 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> 1062306a36Sopenharmony_ci * Author: Sachin Verma <sachin.verma@st.com> 1162306a36Sopenharmony_ci */ 1262306a36Sopenharmony_ci#include <linux/init.h> 1362306a36Sopenharmony_ci#include <linux/module.h> 1462306a36Sopenharmony_ci#include <linux/amba/bus.h> 1562306a36Sopenharmony_ci#include <linux/slab.h> 1662306a36Sopenharmony_ci#include <linux/interrupt.h> 1762306a36Sopenharmony_ci#include <linux/i2c.h> 1862306a36Sopenharmony_ci#include <linux/err.h> 1962306a36Sopenharmony_ci#include <linux/clk.h> 2062306a36Sopenharmony_ci#include <linux/io.h> 2162306a36Sopenharmony_ci#include <linux/pm_runtime.h> 2262306a36Sopenharmony_ci#include <linux/of.h> 2362306a36Sopenharmony_ci#include <linux/pinctrl/consumer.h> 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#define DRIVER_NAME "nmk-i2c" 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci/* I2C Controller register offsets */ 2862306a36Sopenharmony_ci#define I2C_CR (0x000) 2962306a36Sopenharmony_ci#define I2C_SCR (0x004) 3062306a36Sopenharmony_ci#define I2C_HSMCR (0x008) 3162306a36Sopenharmony_ci#define I2C_MCR (0x00C) 3262306a36Sopenharmony_ci#define I2C_TFR (0x010) 3362306a36Sopenharmony_ci#define I2C_SR (0x014) 3462306a36Sopenharmony_ci#define I2C_RFR (0x018) 3562306a36Sopenharmony_ci#define I2C_TFTR (0x01C) 3662306a36Sopenharmony_ci#define I2C_RFTR (0x020) 3762306a36Sopenharmony_ci#define I2C_DMAR (0x024) 3862306a36Sopenharmony_ci#define I2C_BRCR (0x028) 3962306a36Sopenharmony_ci#define I2C_IMSCR (0x02C) 4062306a36Sopenharmony_ci#define I2C_RISR (0x030) 4162306a36Sopenharmony_ci#define I2C_MISR (0x034) 4262306a36Sopenharmony_ci#define I2C_ICR (0x038) 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci/* Control registers */ 4562306a36Sopenharmony_ci#define I2C_CR_PE (0x1 << 0) /* Peripheral Enable */ 4662306a36Sopenharmony_ci#define I2C_CR_OM (0x3 << 1) /* Operating mode */ 4762306a36Sopenharmony_ci#define I2C_CR_SAM (0x1 << 3) /* Slave addressing mode */ 4862306a36Sopenharmony_ci#define I2C_CR_SM (0x3 << 4) /* Speed mode */ 4962306a36Sopenharmony_ci#define I2C_CR_SGCM (0x1 << 6) /* Slave general call mode */ 5062306a36Sopenharmony_ci#define I2C_CR_FTX (0x1 << 7) /* Flush Transmit */ 5162306a36Sopenharmony_ci#define I2C_CR_FRX (0x1 << 8) /* Flush Receive */ 5262306a36Sopenharmony_ci#define I2C_CR_DMA_TX_EN (0x1 << 9) /* DMA Tx enable */ 5362306a36Sopenharmony_ci#define I2C_CR_DMA_RX_EN (0x1 << 10) /* DMA Rx Enable */ 5462306a36Sopenharmony_ci#define I2C_CR_DMA_SLE (0x1 << 11) /* DMA sync. logic enable */ 5562306a36Sopenharmony_ci#define I2C_CR_LM (0x1 << 12) /* Loopback mode */ 5662306a36Sopenharmony_ci#define I2C_CR_FON (0x3 << 13) /* Filtering on */ 5762306a36Sopenharmony_ci#define I2C_CR_FS (0x3 << 15) /* Force stop enable */ 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci/* Master controller (MCR) register */ 6062306a36Sopenharmony_ci#define I2C_MCR_OP (0x1 << 0) /* Operation */ 6162306a36Sopenharmony_ci#define I2C_MCR_A7 (0x7f << 1) /* 7-bit address */ 6262306a36Sopenharmony_ci#define I2C_MCR_EA10 (0x7 << 8) /* 10-bit Extended address */ 6362306a36Sopenharmony_ci#define I2C_MCR_SB (0x1 << 11) /* Extended address */ 6462306a36Sopenharmony_ci#define I2C_MCR_AM (0x3 << 12) /* Address type */ 6562306a36Sopenharmony_ci#define I2C_MCR_STOP (0x1 << 14) /* Stop condition */ 6662306a36Sopenharmony_ci#define I2C_MCR_LENGTH (0x7ff << 15) /* Transaction length */ 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci/* Status register (SR) */ 6962306a36Sopenharmony_ci#define I2C_SR_OP (0x3 << 0) /* Operation */ 7062306a36Sopenharmony_ci#define I2C_SR_STATUS (0x3 << 2) /* controller status */ 7162306a36Sopenharmony_ci#define I2C_SR_CAUSE (0x7 << 4) /* Abort cause */ 7262306a36Sopenharmony_ci#define I2C_SR_TYPE (0x3 << 7) /* Receive type */ 7362306a36Sopenharmony_ci#define I2C_SR_LENGTH (0x7ff << 9) /* Transfer length */ 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci/* Interrupt mask set/clear (IMSCR) bits */ 7662306a36Sopenharmony_ci#define I2C_IT_TXFE (0x1 << 0) 7762306a36Sopenharmony_ci#define I2C_IT_TXFNE (0x1 << 1) 7862306a36Sopenharmony_ci#define I2C_IT_TXFF (0x1 << 2) 7962306a36Sopenharmony_ci#define I2C_IT_TXFOVR (0x1 << 3) 8062306a36Sopenharmony_ci#define I2C_IT_RXFE (0x1 << 4) 8162306a36Sopenharmony_ci#define I2C_IT_RXFNF (0x1 << 5) 8262306a36Sopenharmony_ci#define I2C_IT_RXFF (0x1 << 6) 8362306a36Sopenharmony_ci#define I2C_IT_RFSR (0x1 << 16) 8462306a36Sopenharmony_ci#define I2C_IT_RFSE (0x1 << 17) 8562306a36Sopenharmony_ci#define I2C_IT_WTSR (0x1 << 18) 8662306a36Sopenharmony_ci#define I2C_IT_MTD (0x1 << 19) 8762306a36Sopenharmony_ci#define I2C_IT_STD (0x1 << 20) 8862306a36Sopenharmony_ci#define I2C_IT_MAL (0x1 << 24) 8962306a36Sopenharmony_ci#define I2C_IT_BERR (0x1 << 25) 9062306a36Sopenharmony_ci#define I2C_IT_MTDWS (0x1 << 28) 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci#define GEN_MASK(val, mask, sb) (((val) << (sb)) & (mask)) 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci/* some bits in ICR are reserved */ 9562306a36Sopenharmony_ci#define I2C_CLEAR_ALL_INTS 0x131f007f 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci/* first three msb bits are reserved */ 9862306a36Sopenharmony_ci#define IRQ_MASK(mask) (mask & 0x1fffffff) 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci/* maximum threshold value */ 10162306a36Sopenharmony_ci#define MAX_I2C_FIFO_THRESHOLD 15 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_cienum i2c_freq_mode { 10462306a36Sopenharmony_ci I2C_FREQ_MODE_STANDARD, /* up to 100 Kb/s */ 10562306a36Sopenharmony_ci I2C_FREQ_MODE_FAST, /* up to 400 Kb/s */ 10662306a36Sopenharmony_ci I2C_FREQ_MODE_HIGH_SPEED, /* up to 3.4 Mb/s */ 10762306a36Sopenharmony_ci I2C_FREQ_MODE_FAST_PLUS, /* up to 1 Mb/s */ 10862306a36Sopenharmony_ci}; 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci/** 11162306a36Sopenharmony_ci * struct i2c_vendor_data - per-vendor variations 11262306a36Sopenharmony_ci * @has_mtdws: variant has the MTDWS bit 11362306a36Sopenharmony_ci * @fifodepth: variant FIFO depth 11462306a36Sopenharmony_ci */ 11562306a36Sopenharmony_cistruct i2c_vendor_data { 11662306a36Sopenharmony_ci bool has_mtdws; 11762306a36Sopenharmony_ci u32 fifodepth; 11862306a36Sopenharmony_ci}; 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_cienum i2c_status { 12162306a36Sopenharmony_ci I2C_NOP, 12262306a36Sopenharmony_ci I2C_ON_GOING, 12362306a36Sopenharmony_ci I2C_OK, 12462306a36Sopenharmony_ci I2C_ABORT 12562306a36Sopenharmony_ci}; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci/* operation */ 12862306a36Sopenharmony_cienum i2c_operation { 12962306a36Sopenharmony_ci I2C_NO_OPERATION = 0xff, 13062306a36Sopenharmony_ci I2C_WRITE = 0x00, 13162306a36Sopenharmony_ci I2C_READ = 0x01 13262306a36Sopenharmony_ci}; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci/** 13562306a36Sopenharmony_ci * struct i2c_nmk_client - client specific data 13662306a36Sopenharmony_ci * @slave_adr: 7-bit slave address 13762306a36Sopenharmony_ci * @count: no. bytes to be transferred 13862306a36Sopenharmony_ci * @buffer: client data buffer 13962306a36Sopenharmony_ci * @xfer_bytes: bytes transferred till now 14062306a36Sopenharmony_ci * @operation: current I2C operation 14162306a36Sopenharmony_ci */ 14262306a36Sopenharmony_cistruct i2c_nmk_client { 14362306a36Sopenharmony_ci unsigned short slave_adr; 14462306a36Sopenharmony_ci unsigned long count; 14562306a36Sopenharmony_ci unsigned char *buffer; 14662306a36Sopenharmony_ci unsigned long xfer_bytes; 14762306a36Sopenharmony_ci enum i2c_operation operation; 14862306a36Sopenharmony_ci}; 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci/** 15162306a36Sopenharmony_ci * struct nmk_i2c_dev - private data structure of the controller. 15262306a36Sopenharmony_ci * @vendor: vendor data for this variant. 15362306a36Sopenharmony_ci * @adev: parent amba device. 15462306a36Sopenharmony_ci * @adap: corresponding I2C adapter. 15562306a36Sopenharmony_ci * @irq: interrupt line for the controller. 15662306a36Sopenharmony_ci * @virtbase: virtual io memory area. 15762306a36Sopenharmony_ci * @clk: hardware i2c block clock. 15862306a36Sopenharmony_ci * @cli: holder of client specific data. 15962306a36Sopenharmony_ci * @clk_freq: clock frequency for the operation mode 16062306a36Sopenharmony_ci * @tft: Tx FIFO Threshold in bytes 16162306a36Sopenharmony_ci * @rft: Rx FIFO Threshold in bytes 16262306a36Sopenharmony_ci * @timeout: Slave response timeout (ms) 16362306a36Sopenharmony_ci * @sm: speed mode 16462306a36Sopenharmony_ci * @stop: stop condition. 16562306a36Sopenharmony_ci * @xfer_complete: acknowledge completion for a I2C message. 16662306a36Sopenharmony_ci * @result: controller propogated result. 16762306a36Sopenharmony_ci */ 16862306a36Sopenharmony_cistruct nmk_i2c_dev { 16962306a36Sopenharmony_ci struct i2c_vendor_data *vendor; 17062306a36Sopenharmony_ci struct amba_device *adev; 17162306a36Sopenharmony_ci struct i2c_adapter adap; 17262306a36Sopenharmony_ci int irq; 17362306a36Sopenharmony_ci void __iomem *virtbase; 17462306a36Sopenharmony_ci struct clk *clk; 17562306a36Sopenharmony_ci struct i2c_nmk_client cli; 17662306a36Sopenharmony_ci u32 clk_freq; 17762306a36Sopenharmony_ci unsigned char tft; 17862306a36Sopenharmony_ci unsigned char rft; 17962306a36Sopenharmony_ci int timeout; 18062306a36Sopenharmony_ci enum i2c_freq_mode sm; 18162306a36Sopenharmony_ci int stop; 18262306a36Sopenharmony_ci struct completion xfer_complete; 18362306a36Sopenharmony_ci int result; 18462306a36Sopenharmony_ci}; 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci/* controller's abort causes */ 18762306a36Sopenharmony_cistatic const char *abort_causes[] = { 18862306a36Sopenharmony_ci "no ack received after address transmission", 18962306a36Sopenharmony_ci "no ack received during data phase", 19062306a36Sopenharmony_ci "ack received after xmission of master code", 19162306a36Sopenharmony_ci "master lost arbitration", 19262306a36Sopenharmony_ci "slave restarts", 19362306a36Sopenharmony_ci "slave reset", 19462306a36Sopenharmony_ci "overflow, maxsize is 2047 bytes", 19562306a36Sopenharmony_ci}; 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_cistatic inline void i2c_set_bit(void __iomem *reg, u32 mask) 19862306a36Sopenharmony_ci{ 19962306a36Sopenharmony_ci writel(readl(reg) | mask, reg); 20062306a36Sopenharmony_ci} 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_cistatic inline void i2c_clr_bit(void __iomem *reg, u32 mask) 20362306a36Sopenharmony_ci{ 20462306a36Sopenharmony_ci writel(readl(reg) & ~mask, reg); 20562306a36Sopenharmony_ci} 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci/** 20862306a36Sopenharmony_ci * flush_i2c_fifo() - This function flushes the I2C FIFO 20962306a36Sopenharmony_ci * @dev: private data of I2C Driver 21062306a36Sopenharmony_ci * 21162306a36Sopenharmony_ci * This function flushes the I2C Tx and Rx FIFOs. It returns 21262306a36Sopenharmony_ci * 0 on successful flushing of FIFO 21362306a36Sopenharmony_ci */ 21462306a36Sopenharmony_cistatic int flush_i2c_fifo(struct nmk_i2c_dev *dev) 21562306a36Sopenharmony_ci{ 21662306a36Sopenharmony_ci#define LOOP_ATTEMPTS 10 21762306a36Sopenharmony_ci int i; 21862306a36Sopenharmony_ci unsigned long timeout; 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci /* 22162306a36Sopenharmony_ci * flush the transmit and receive FIFO. The flushing 22262306a36Sopenharmony_ci * operation takes several cycles before to be completed. 22362306a36Sopenharmony_ci * On the completion, the I2C internal logic clears these 22462306a36Sopenharmony_ci * bits, until then no one must access Tx, Rx FIFO and 22562306a36Sopenharmony_ci * should poll on these bits waiting for the completion. 22662306a36Sopenharmony_ci */ 22762306a36Sopenharmony_ci writel((I2C_CR_FTX | I2C_CR_FRX), dev->virtbase + I2C_CR); 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci for (i = 0; i < LOOP_ATTEMPTS; i++) { 23062306a36Sopenharmony_ci timeout = jiffies + dev->adap.timeout; 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci while (!time_after(jiffies, timeout)) { 23362306a36Sopenharmony_ci if ((readl(dev->virtbase + I2C_CR) & 23462306a36Sopenharmony_ci (I2C_CR_FTX | I2C_CR_FRX)) == 0) 23562306a36Sopenharmony_ci return 0; 23662306a36Sopenharmony_ci } 23762306a36Sopenharmony_ci } 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci dev_err(&dev->adev->dev, 24062306a36Sopenharmony_ci "flushing operation timed out giving up after %d attempts", 24162306a36Sopenharmony_ci LOOP_ATTEMPTS); 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci return -ETIMEDOUT; 24462306a36Sopenharmony_ci} 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci/** 24762306a36Sopenharmony_ci * disable_all_interrupts() - Disable all interrupts of this I2c Bus 24862306a36Sopenharmony_ci * @dev: private data of I2C Driver 24962306a36Sopenharmony_ci */ 25062306a36Sopenharmony_cistatic void disable_all_interrupts(struct nmk_i2c_dev *dev) 25162306a36Sopenharmony_ci{ 25262306a36Sopenharmony_ci u32 mask = IRQ_MASK(0); 25362306a36Sopenharmony_ci writel(mask, dev->virtbase + I2C_IMSCR); 25462306a36Sopenharmony_ci} 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci/** 25762306a36Sopenharmony_ci * clear_all_interrupts() - Clear all interrupts of I2C Controller 25862306a36Sopenharmony_ci * @dev: private data of I2C Driver 25962306a36Sopenharmony_ci */ 26062306a36Sopenharmony_cistatic void clear_all_interrupts(struct nmk_i2c_dev *dev) 26162306a36Sopenharmony_ci{ 26262306a36Sopenharmony_ci u32 mask; 26362306a36Sopenharmony_ci mask = IRQ_MASK(I2C_CLEAR_ALL_INTS); 26462306a36Sopenharmony_ci writel(mask, dev->virtbase + I2C_ICR); 26562306a36Sopenharmony_ci} 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci/** 26862306a36Sopenharmony_ci * init_hw() - initialize the I2C hardware 26962306a36Sopenharmony_ci * @dev: private data of I2C Driver 27062306a36Sopenharmony_ci */ 27162306a36Sopenharmony_cistatic int init_hw(struct nmk_i2c_dev *dev) 27262306a36Sopenharmony_ci{ 27362306a36Sopenharmony_ci int stat; 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci stat = flush_i2c_fifo(dev); 27662306a36Sopenharmony_ci if (stat) 27762306a36Sopenharmony_ci goto exit; 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci /* disable the controller */ 28062306a36Sopenharmony_ci i2c_clr_bit(dev->virtbase + I2C_CR, I2C_CR_PE); 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci disable_all_interrupts(dev); 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci clear_all_interrupts(dev); 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci dev->cli.operation = I2C_NO_OPERATION; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ciexit: 28962306a36Sopenharmony_ci return stat; 29062306a36Sopenharmony_ci} 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci/* enable peripheral, master mode operation */ 29362306a36Sopenharmony_ci#define DEFAULT_I2C_REG_CR ((1 << 1) | I2C_CR_PE) 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci/** 29662306a36Sopenharmony_ci * load_i2c_mcr_reg() - load the MCR register 29762306a36Sopenharmony_ci * @dev: private data of controller 29862306a36Sopenharmony_ci * @flags: message flags 29962306a36Sopenharmony_ci */ 30062306a36Sopenharmony_cistatic u32 load_i2c_mcr_reg(struct nmk_i2c_dev *dev, u16 flags) 30162306a36Sopenharmony_ci{ 30262306a36Sopenharmony_ci u32 mcr = 0; 30362306a36Sopenharmony_ci unsigned short slave_adr_3msb_bits; 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci mcr |= GEN_MASK(dev->cli.slave_adr, I2C_MCR_A7, 1); 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci if (unlikely(flags & I2C_M_TEN)) { 30862306a36Sopenharmony_ci /* 10-bit address transaction */ 30962306a36Sopenharmony_ci mcr |= GEN_MASK(2, I2C_MCR_AM, 12); 31062306a36Sopenharmony_ci /* 31162306a36Sopenharmony_ci * Get the top 3 bits. 31262306a36Sopenharmony_ci * EA10 represents extended address in MCR. This includes 31362306a36Sopenharmony_ci * the extension (MSB bits) of the 7 bit address loaded 31462306a36Sopenharmony_ci * in A7 31562306a36Sopenharmony_ci */ 31662306a36Sopenharmony_ci slave_adr_3msb_bits = (dev->cli.slave_adr >> 7) & 0x7; 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci mcr |= GEN_MASK(slave_adr_3msb_bits, I2C_MCR_EA10, 8); 31962306a36Sopenharmony_ci } else { 32062306a36Sopenharmony_ci /* 7-bit address transaction */ 32162306a36Sopenharmony_ci mcr |= GEN_MASK(1, I2C_MCR_AM, 12); 32262306a36Sopenharmony_ci } 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci /* start byte procedure not applied */ 32562306a36Sopenharmony_ci mcr |= GEN_MASK(0, I2C_MCR_SB, 11); 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci /* check the operation, master read/write? */ 32862306a36Sopenharmony_ci if (dev->cli.operation == I2C_WRITE) 32962306a36Sopenharmony_ci mcr |= GEN_MASK(I2C_WRITE, I2C_MCR_OP, 0); 33062306a36Sopenharmony_ci else 33162306a36Sopenharmony_ci mcr |= GEN_MASK(I2C_READ, I2C_MCR_OP, 0); 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci /* stop or repeated start? */ 33462306a36Sopenharmony_ci if (dev->stop) 33562306a36Sopenharmony_ci mcr |= GEN_MASK(1, I2C_MCR_STOP, 14); 33662306a36Sopenharmony_ci else 33762306a36Sopenharmony_ci mcr &= ~(GEN_MASK(1, I2C_MCR_STOP, 14)); 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci mcr |= GEN_MASK(dev->cli.count, I2C_MCR_LENGTH, 15); 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci return mcr; 34262306a36Sopenharmony_ci} 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci/** 34562306a36Sopenharmony_ci * setup_i2c_controller() - setup the controller 34662306a36Sopenharmony_ci * @dev: private data of controller 34762306a36Sopenharmony_ci */ 34862306a36Sopenharmony_cistatic void setup_i2c_controller(struct nmk_i2c_dev *dev) 34962306a36Sopenharmony_ci{ 35062306a36Sopenharmony_ci u32 brcr1, brcr2; 35162306a36Sopenharmony_ci u32 i2c_clk, div; 35262306a36Sopenharmony_ci u32 ns; 35362306a36Sopenharmony_ci u16 slsu; 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_ci writel(0x0, dev->virtbase + I2C_CR); 35662306a36Sopenharmony_ci writel(0x0, dev->virtbase + I2C_HSMCR); 35762306a36Sopenharmony_ci writel(0x0, dev->virtbase + I2C_TFTR); 35862306a36Sopenharmony_ci writel(0x0, dev->virtbase + I2C_RFTR); 35962306a36Sopenharmony_ci writel(0x0, dev->virtbase + I2C_DMAR); 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ci i2c_clk = clk_get_rate(dev->clk); 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci /* 36462306a36Sopenharmony_ci * set the slsu: 36562306a36Sopenharmony_ci * 36662306a36Sopenharmony_ci * slsu defines the data setup time after SCL clock 36762306a36Sopenharmony_ci * stretching in terms of i2c clk cycles + 1 (zero means 36862306a36Sopenharmony_ci * "wait one cycle"), the needed setup time for the three 36962306a36Sopenharmony_ci * modes are 250ns, 100ns, 10ns respectively. 37062306a36Sopenharmony_ci * 37162306a36Sopenharmony_ci * As the time for one cycle T in nanoseconds is 37262306a36Sopenharmony_ci * T = (1/f) * 1000000000 => 37362306a36Sopenharmony_ci * slsu = cycles / (1000000000 / f) + 1 37462306a36Sopenharmony_ci */ 37562306a36Sopenharmony_ci ns = DIV_ROUND_UP_ULL(1000000000ULL, i2c_clk); 37662306a36Sopenharmony_ci switch (dev->sm) { 37762306a36Sopenharmony_ci case I2C_FREQ_MODE_FAST: 37862306a36Sopenharmony_ci case I2C_FREQ_MODE_FAST_PLUS: 37962306a36Sopenharmony_ci slsu = DIV_ROUND_UP(100, ns); /* Fast */ 38062306a36Sopenharmony_ci break; 38162306a36Sopenharmony_ci case I2C_FREQ_MODE_HIGH_SPEED: 38262306a36Sopenharmony_ci slsu = DIV_ROUND_UP(10, ns); /* High */ 38362306a36Sopenharmony_ci break; 38462306a36Sopenharmony_ci case I2C_FREQ_MODE_STANDARD: 38562306a36Sopenharmony_ci default: 38662306a36Sopenharmony_ci slsu = DIV_ROUND_UP(250, ns); /* Standard */ 38762306a36Sopenharmony_ci break; 38862306a36Sopenharmony_ci } 38962306a36Sopenharmony_ci slsu += 1; 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci dev_dbg(&dev->adev->dev, "calculated SLSU = %04x\n", slsu); 39262306a36Sopenharmony_ci writel(slsu << 16, dev->virtbase + I2C_SCR); 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_ci /* 39562306a36Sopenharmony_ci * The spec says, in case of std. mode the divider is 39662306a36Sopenharmony_ci * 2 whereas it is 3 for fast and fastplus mode of 39762306a36Sopenharmony_ci * operation. TODO - high speed support. 39862306a36Sopenharmony_ci */ 39962306a36Sopenharmony_ci div = (dev->clk_freq > I2C_MAX_STANDARD_MODE_FREQ) ? 3 : 2; 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_ci /* 40262306a36Sopenharmony_ci * generate the mask for baud rate counters. The controller 40362306a36Sopenharmony_ci * has two baud rate counters. One is used for High speed 40462306a36Sopenharmony_ci * operation, and the other is for std, fast mode, fast mode 40562306a36Sopenharmony_ci * plus operation. Currently we do not supprt high speed mode 40662306a36Sopenharmony_ci * so set brcr1 to 0. 40762306a36Sopenharmony_ci */ 40862306a36Sopenharmony_ci brcr1 = 0 << 16; 40962306a36Sopenharmony_ci brcr2 = (i2c_clk/(dev->clk_freq * div)) & 0xffff; 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ci /* set the baud rate counter register */ 41262306a36Sopenharmony_ci writel((brcr1 | brcr2), dev->virtbase + I2C_BRCR); 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ci /* 41562306a36Sopenharmony_ci * set the speed mode. Currently we support 41662306a36Sopenharmony_ci * only standard and fast mode of operation 41762306a36Sopenharmony_ci * TODO - support for fast mode plus (up to 1Mb/s) 41862306a36Sopenharmony_ci * and high speed (up to 3.4 Mb/s) 41962306a36Sopenharmony_ci */ 42062306a36Sopenharmony_ci if (dev->sm > I2C_FREQ_MODE_FAST) { 42162306a36Sopenharmony_ci dev_err(&dev->adev->dev, 42262306a36Sopenharmony_ci "do not support this mode defaulting to std. mode\n"); 42362306a36Sopenharmony_ci brcr2 = i2c_clk / (I2C_MAX_STANDARD_MODE_FREQ * 2) & 0xffff; 42462306a36Sopenharmony_ci writel((brcr1 | brcr2), dev->virtbase + I2C_BRCR); 42562306a36Sopenharmony_ci writel(I2C_FREQ_MODE_STANDARD << 4, 42662306a36Sopenharmony_ci dev->virtbase + I2C_CR); 42762306a36Sopenharmony_ci } 42862306a36Sopenharmony_ci writel(dev->sm << 4, dev->virtbase + I2C_CR); 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci /* set the Tx and Rx FIFO threshold */ 43162306a36Sopenharmony_ci writel(dev->tft, dev->virtbase + I2C_TFTR); 43262306a36Sopenharmony_ci writel(dev->rft, dev->virtbase + I2C_RFTR); 43362306a36Sopenharmony_ci} 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_ci/** 43662306a36Sopenharmony_ci * read_i2c() - Read from I2C client device 43762306a36Sopenharmony_ci * @dev: private data of I2C Driver 43862306a36Sopenharmony_ci * @flags: message flags 43962306a36Sopenharmony_ci * 44062306a36Sopenharmony_ci * This function reads from i2c client device when controller is in 44162306a36Sopenharmony_ci * master mode. There is a completion timeout. If there is no transfer 44262306a36Sopenharmony_ci * before timeout error is returned. 44362306a36Sopenharmony_ci */ 44462306a36Sopenharmony_cistatic int read_i2c(struct nmk_i2c_dev *dev, u16 flags) 44562306a36Sopenharmony_ci{ 44662306a36Sopenharmony_ci int status = 0; 44762306a36Sopenharmony_ci u32 mcr, irq_mask; 44862306a36Sopenharmony_ci unsigned long timeout; 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci mcr = load_i2c_mcr_reg(dev, flags); 45162306a36Sopenharmony_ci writel(mcr, dev->virtbase + I2C_MCR); 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_ci /* load the current CR value */ 45462306a36Sopenharmony_ci writel(readl(dev->virtbase + I2C_CR) | DEFAULT_I2C_REG_CR, 45562306a36Sopenharmony_ci dev->virtbase + I2C_CR); 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_ci /* enable the controller */ 45862306a36Sopenharmony_ci i2c_set_bit(dev->virtbase + I2C_CR, I2C_CR_PE); 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci init_completion(&dev->xfer_complete); 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_ci /* enable interrupts by setting the mask */ 46362306a36Sopenharmony_ci irq_mask = (I2C_IT_RXFNF | I2C_IT_RXFF | 46462306a36Sopenharmony_ci I2C_IT_MAL | I2C_IT_BERR); 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ci if (dev->stop || !dev->vendor->has_mtdws) 46762306a36Sopenharmony_ci irq_mask |= I2C_IT_MTD; 46862306a36Sopenharmony_ci else 46962306a36Sopenharmony_ci irq_mask |= I2C_IT_MTDWS; 47062306a36Sopenharmony_ci 47162306a36Sopenharmony_ci irq_mask = I2C_CLEAR_ALL_INTS & IRQ_MASK(irq_mask); 47262306a36Sopenharmony_ci 47362306a36Sopenharmony_ci writel(readl(dev->virtbase + I2C_IMSCR) | irq_mask, 47462306a36Sopenharmony_ci dev->virtbase + I2C_IMSCR); 47562306a36Sopenharmony_ci 47662306a36Sopenharmony_ci timeout = wait_for_completion_timeout( 47762306a36Sopenharmony_ci &dev->xfer_complete, dev->adap.timeout); 47862306a36Sopenharmony_ci 47962306a36Sopenharmony_ci if (timeout == 0) { 48062306a36Sopenharmony_ci /* Controller timed out */ 48162306a36Sopenharmony_ci dev_err(&dev->adev->dev, "read from slave 0x%x timed out\n", 48262306a36Sopenharmony_ci dev->cli.slave_adr); 48362306a36Sopenharmony_ci status = -ETIMEDOUT; 48462306a36Sopenharmony_ci } 48562306a36Sopenharmony_ci return status; 48662306a36Sopenharmony_ci} 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_cistatic void fill_tx_fifo(struct nmk_i2c_dev *dev, int no_bytes) 48962306a36Sopenharmony_ci{ 49062306a36Sopenharmony_ci int count; 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_ci for (count = (no_bytes - 2); 49362306a36Sopenharmony_ci (count > 0) && 49462306a36Sopenharmony_ci (dev->cli.count != 0); 49562306a36Sopenharmony_ci count--) { 49662306a36Sopenharmony_ci /* write to the Tx FIFO */ 49762306a36Sopenharmony_ci writeb(*dev->cli.buffer, 49862306a36Sopenharmony_ci dev->virtbase + I2C_TFR); 49962306a36Sopenharmony_ci dev->cli.buffer++; 50062306a36Sopenharmony_ci dev->cli.count--; 50162306a36Sopenharmony_ci dev->cli.xfer_bytes++; 50262306a36Sopenharmony_ci } 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci} 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_ci/** 50762306a36Sopenharmony_ci * write_i2c() - Write data to I2C client. 50862306a36Sopenharmony_ci * @dev: private data of I2C Driver 50962306a36Sopenharmony_ci * @flags: message flags 51062306a36Sopenharmony_ci * 51162306a36Sopenharmony_ci * This function writes data to I2C client 51262306a36Sopenharmony_ci */ 51362306a36Sopenharmony_cistatic int write_i2c(struct nmk_i2c_dev *dev, u16 flags) 51462306a36Sopenharmony_ci{ 51562306a36Sopenharmony_ci u32 status = 0; 51662306a36Sopenharmony_ci u32 mcr, irq_mask; 51762306a36Sopenharmony_ci unsigned long timeout; 51862306a36Sopenharmony_ci 51962306a36Sopenharmony_ci mcr = load_i2c_mcr_reg(dev, flags); 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_ci writel(mcr, dev->virtbase + I2C_MCR); 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_ci /* load the current CR value */ 52462306a36Sopenharmony_ci writel(readl(dev->virtbase + I2C_CR) | DEFAULT_I2C_REG_CR, 52562306a36Sopenharmony_ci dev->virtbase + I2C_CR); 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_ci /* enable the controller */ 52862306a36Sopenharmony_ci i2c_set_bit(dev->virtbase + I2C_CR, I2C_CR_PE); 52962306a36Sopenharmony_ci 53062306a36Sopenharmony_ci init_completion(&dev->xfer_complete); 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_ci /* enable interrupts by settings the masks */ 53362306a36Sopenharmony_ci irq_mask = (I2C_IT_TXFOVR | I2C_IT_MAL | I2C_IT_BERR); 53462306a36Sopenharmony_ci 53562306a36Sopenharmony_ci /* Fill the TX FIFO with transmit data */ 53662306a36Sopenharmony_ci fill_tx_fifo(dev, MAX_I2C_FIFO_THRESHOLD); 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_ci if (dev->cli.count != 0) 53962306a36Sopenharmony_ci irq_mask |= I2C_IT_TXFNE; 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_ci /* 54262306a36Sopenharmony_ci * check if we want to transfer a single or multiple bytes, if so 54362306a36Sopenharmony_ci * set the MTDWS bit (Master Transaction Done Without Stop) 54462306a36Sopenharmony_ci * to start repeated start operation 54562306a36Sopenharmony_ci */ 54662306a36Sopenharmony_ci if (dev->stop || !dev->vendor->has_mtdws) 54762306a36Sopenharmony_ci irq_mask |= I2C_IT_MTD; 54862306a36Sopenharmony_ci else 54962306a36Sopenharmony_ci irq_mask |= I2C_IT_MTDWS; 55062306a36Sopenharmony_ci 55162306a36Sopenharmony_ci irq_mask = I2C_CLEAR_ALL_INTS & IRQ_MASK(irq_mask); 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_ci writel(readl(dev->virtbase + I2C_IMSCR) | irq_mask, 55462306a36Sopenharmony_ci dev->virtbase + I2C_IMSCR); 55562306a36Sopenharmony_ci 55662306a36Sopenharmony_ci timeout = wait_for_completion_timeout( 55762306a36Sopenharmony_ci &dev->xfer_complete, dev->adap.timeout); 55862306a36Sopenharmony_ci 55962306a36Sopenharmony_ci if (timeout == 0) { 56062306a36Sopenharmony_ci /* Controller timed out */ 56162306a36Sopenharmony_ci dev_err(&dev->adev->dev, "write to slave 0x%x timed out\n", 56262306a36Sopenharmony_ci dev->cli.slave_adr); 56362306a36Sopenharmony_ci status = -ETIMEDOUT; 56462306a36Sopenharmony_ci } 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_ci return status; 56762306a36Sopenharmony_ci} 56862306a36Sopenharmony_ci 56962306a36Sopenharmony_ci/** 57062306a36Sopenharmony_ci * nmk_i2c_xfer_one() - transmit a single I2C message 57162306a36Sopenharmony_ci * @dev: device with a message encoded into it 57262306a36Sopenharmony_ci * @flags: message flags 57362306a36Sopenharmony_ci */ 57462306a36Sopenharmony_cistatic int nmk_i2c_xfer_one(struct nmk_i2c_dev *dev, u16 flags) 57562306a36Sopenharmony_ci{ 57662306a36Sopenharmony_ci int status; 57762306a36Sopenharmony_ci 57862306a36Sopenharmony_ci if (flags & I2C_M_RD) { 57962306a36Sopenharmony_ci /* read operation */ 58062306a36Sopenharmony_ci dev->cli.operation = I2C_READ; 58162306a36Sopenharmony_ci status = read_i2c(dev, flags); 58262306a36Sopenharmony_ci } else { 58362306a36Sopenharmony_ci /* write operation */ 58462306a36Sopenharmony_ci dev->cli.operation = I2C_WRITE; 58562306a36Sopenharmony_ci status = write_i2c(dev, flags); 58662306a36Sopenharmony_ci } 58762306a36Sopenharmony_ci 58862306a36Sopenharmony_ci if (status || (dev->result)) { 58962306a36Sopenharmony_ci u32 i2c_sr; 59062306a36Sopenharmony_ci u32 cause; 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_ci i2c_sr = readl(dev->virtbase + I2C_SR); 59362306a36Sopenharmony_ci /* 59462306a36Sopenharmony_ci * Check if the controller I2C operation status 59562306a36Sopenharmony_ci * is set to ABORT(11b). 59662306a36Sopenharmony_ci */ 59762306a36Sopenharmony_ci if (((i2c_sr >> 2) & 0x3) == 0x3) { 59862306a36Sopenharmony_ci /* get the abort cause */ 59962306a36Sopenharmony_ci cause = (i2c_sr >> 4) & 0x7; 60062306a36Sopenharmony_ci dev_err(&dev->adev->dev, "%s\n", 60162306a36Sopenharmony_ci cause >= ARRAY_SIZE(abort_causes) ? 60262306a36Sopenharmony_ci "unknown reason" : 60362306a36Sopenharmony_ci abort_causes[cause]); 60462306a36Sopenharmony_ci } 60562306a36Sopenharmony_ci 60662306a36Sopenharmony_ci (void) init_hw(dev); 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_ci status = status ? status : dev->result; 60962306a36Sopenharmony_ci } 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_ci return status; 61262306a36Sopenharmony_ci} 61362306a36Sopenharmony_ci 61462306a36Sopenharmony_ci/** 61562306a36Sopenharmony_ci * nmk_i2c_xfer() - I2C transfer function used by kernel framework 61662306a36Sopenharmony_ci * @i2c_adap: Adapter pointer to the controller 61762306a36Sopenharmony_ci * @msgs: Pointer to data to be written. 61862306a36Sopenharmony_ci * @num_msgs: Number of messages to be executed 61962306a36Sopenharmony_ci * 62062306a36Sopenharmony_ci * This is the function called by the generic kernel i2c_transfer() 62162306a36Sopenharmony_ci * or i2c_smbus...() API calls. Note that this code is protected by the 62262306a36Sopenharmony_ci * semaphore set in the kernel i2c_transfer() function. 62362306a36Sopenharmony_ci * 62462306a36Sopenharmony_ci * NOTE: 62562306a36Sopenharmony_ci * READ TRANSFER : We impose a restriction of the first message to be the 62662306a36Sopenharmony_ci * index message for any read transaction. 62762306a36Sopenharmony_ci * - a no index is coded as '0', 62862306a36Sopenharmony_ci * - 2byte big endian index is coded as '3' 62962306a36Sopenharmony_ci * !!! msg[0].buf holds the actual index. 63062306a36Sopenharmony_ci * This is compatible with generic messages of smbus emulator 63162306a36Sopenharmony_ci * that send a one byte index. 63262306a36Sopenharmony_ci * eg. a I2C transation to read 2 bytes from index 0 63362306a36Sopenharmony_ci * idx = 0; 63462306a36Sopenharmony_ci * msg[0].addr = client->addr; 63562306a36Sopenharmony_ci * msg[0].flags = 0x0; 63662306a36Sopenharmony_ci * msg[0].len = 1; 63762306a36Sopenharmony_ci * msg[0].buf = &idx; 63862306a36Sopenharmony_ci * 63962306a36Sopenharmony_ci * msg[1].addr = client->addr; 64062306a36Sopenharmony_ci * msg[1].flags = I2C_M_RD; 64162306a36Sopenharmony_ci * msg[1].len = 2; 64262306a36Sopenharmony_ci * msg[1].buf = rd_buff 64362306a36Sopenharmony_ci * i2c_transfer(adap, msg, 2); 64462306a36Sopenharmony_ci * 64562306a36Sopenharmony_ci * WRITE TRANSFER : The I2C standard interface interprets all data as payload. 64662306a36Sopenharmony_ci * If you want to emulate an SMBUS write transaction put the 64762306a36Sopenharmony_ci * index as first byte(or first and second) in the payload. 64862306a36Sopenharmony_ci * eg. a I2C transation to write 2 bytes from index 1 64962306a36Sopenharmony_ci * wr_buff[0] = 0x1; 65062306a36Sopenharmony_ci * wr_buff[1] = 0x23; 65162306a36Sopenharmony_ci * wr_buff[2] = 0x46; 65262306a36Sopenharmony_ci * msg[0].flags = 0x0; 65362306a36Sopenharmony_ci * msg[0].len = 3; 65462306a36Sopenharmony_ci * msg[0].buf = wr_buff; 65562306a36Sopenharmony_ci * i2c_transfer(adap, msg, 1); 65662306a36Sopenharmony_ci * 65762306a36Sopenharmony_ci * To read or write a block of data (multiple bytes) using SMBUS emulation 65862306a36Sopenharmony_ci * please use the i2c_smbus_read_i2c_block_data() 65962306a36Sopenharmony_ci * or i2c_smbus_write_i2c_block_data() API 66062306a36Sopenharmony_ci */ 66162306a36Sopenharmony_cistatic int nmk_i2c_xfer(struct i2c_adapter *i2c_adap, 66262306a36Sopenharmony_ci struct i2c_msg msgs[], int num_msgs) 66362306a36Sopenharmony_ci{ 66462306a36Sopenharmony_ci int status = 0; 66562306a36Sopenharmony_ci int i; 66662306a36Sopenharmony_ci struct nmk_i2c_dev *dev = i2c_get_adapdata(i2c_adap); 66762306a36Sopenharmony_ci int j; 66862306a36Sopenharmony_ci 66962306a36Sopenharmony_ci pm_runtime_get_sync(&dev->adev->dev); 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_ci /* Attempt three times to send the message queue */ 67262306a36Sopenharmony_ci for (j = 0; j < 3; j++) { 67362306a36Sopenharmony_ci /* setup the i2c controller */ 67462306a36Sopenharmony_ci setup_i2c_controller(dev); 67562306a36Sopenharmony_ci 67662306a36Sopenharmony_ci for (i = 0; i < num_msgs; i++) { 67762306a36Sopenharmony_ci dev->cli.slave_adr = msgs[i].addr; 67862306a36Sopenharmony_ci dev->cli.buffer = msgs[i].buf; 67962306a36Sopenharmony_ci dev->cli.count = msgs[i].len; 68062306a36Sopenharmony_ci dev->stop = (i < (num_msgs - 1)) ? 0 : 1; 68162306a36Sopenharmony_ci dev->result = 0; 68262306a36Sopenharmony_ci 68362306a36Sopenharmony_ci status = nmk_i2c_xfer_one(dev, msgs[i].flags); 68462306a36Sopenharmony_ci if (status != 0) 68562306a36Sopenharmony_ci break; 68662306a36Sopenharmony_ci } 68762306a36Sopenharmony_ci if (status == 0) 68862306a36Sopenharmony_ci break; 68962306a36Sopenharmony_ci } 69062306a36Sopenharmony_ci 69162306a36Sopenharmony_ci pm_runtime_put_sync(&dev->adev->dev); 69262306a36Sopenharmony_ci 69362306a36Sopenharmony_ci /* return the no. messages processed */ 69462306a36Sopenharmony_ci if (status) 69562306a36Sopenharmony_ci return status; 69662306a36Sopenharmony_ci else 69762306a36Sopenharmony_ci return num_msgs; 69862306a36Sopenharmony_ci} 69962306a36Sopenharmony_ci 70062306a36Sopenharmony_ci/** 70162306a36Sopenharmony_ci * disable_interrupts() - disable the interrupts 70262306a36Sopenharmony_ci * @dev: private data of controller 70362306a36Sopenharmony_ci * @irq: interrupt number 70462306a36Sopenharmony_ci */ 70562306a36Sopenharmony_cistatic int disable_interrupts(struct nmk_i2c_dev *dev, u32 irq) 70662306a36Sopenharmony_ci{ 70762306a36Sopenharmony_ci irq = IRQ_MASK(irq); 70862306a36Sopenharmony_ci writel(readl(dev->virtbase + I2C_IMSCR) & ~(I2C_CLEAR_ALL_INTS & irq), 70962306a36Sopenharmony_ci dev->virtbase + I2C_IMSCR); 71062306a36Sopenharmony_ci return 0; 71162306a36Sopenharmony_ci} 71262306a36Sopenharmony_ci 71362306a36Sopenharmony_ci/** 71462306a36Sopenharmony_ci * i2c_irq_handler() - interrupt routine 71562306a36Sopenharmony_ci * @irq: interrupt number 71662306a36Sopenharmony_ci * @arg: data passed to the handler 71762306a36Sopenharmony_ci * 71862306a36Sopenharmony_ci * This is the interrupt handler for the i2c driver. Currently 71962306a36Sopenharmony_ci * it handles the major interrupts like Rx & Tx FIFO management 72062306a36Sopenharmony_ci * interrupts, master transaction interrupts, arbitration and 72162306a36Sopenharmony_ci * bus error interrupts. The rest of the interrupts are treated as 72262306a36Sopenharmony_ci * unhandled. 72362306a36Sopenharmony_ci */ 72462306a36Sopenharmony_cistatic irqreturn_t i2c_irq_handler(int irq, void *arg) 72562306a36Sopenharmony_ci{ 72662306a36Sopenharmony_ci struct nmk_i2c_dev *dev = arg; 72762306a36Sopenharmony_ci u32 tft, rft; 72862306a36Sopenharmony_ci u32 count; 72962306a36Sopenharmony_ci u32 misr, src; 73062306a36Sopenharmony_ci 73162306a36Sopenharmony_ci /* load Tx FIFO and Rx FIFO threshold values */ 73262306a36Sopenharmony_ci tft = readl(dev->virtbase + I2C_TFTR); 73362306a36Sopenharmony_ci rft = readl(dev->virtbase + I2C_RFTR); 73462306a36Sopenharmony_ci 73562306a36Sopenharmony_ci /* read interrupt status register */ 73662306a36Sopenharmony_ci misr = readl(dev->virtbase + I2C_MISR); 73762306a36Sopenharmony_ci 73862306a36Sopenharmony_ci src = __ffs(misr); 73962306a36Sopenharmony_ci switch ((1 << src)) { 74062306a36Sopenharmony_ci 74162306a36Sopenharmony_ci /* Transmit FIFO nearly empty interrupt */ 74262306a36Sopenharmony_ci case I2C_IT_TXFNE: 74362306a36Sopenharmony_ci { 74462306a36Sopenharmony_ci if (dev->cli.operation == I2C_READ) { 74562306a36Sopenharmony_ci /* 74662306a36Sopenharmony_ci * in read operation why do we care for writing? 74762306a36Sopenharmony_ci * so disable the Transmit FIFO interrupt 74862306a36Sopenharmony_ci */ 74962306a36Sopenharmony_ci disable_interrupts(dev, I2C_IT_TXFNE); 75062306a36Sopenharmony_ci } else { 75162306a36Sopenharmony_ci fill_tx_fifo(dev, (MAX_I2C_FIFO_THRESHOLD - tft)); 75262306a36Sopenharmony_ci /* 75362306a36Sopenharmony_ci * if done, close the transfer by disabling the 75462306a36Sopenharmony_ci * corresponding TXFNE interrupt 75562306a36Sopenharmony_ci */ 75662306a36Sopenharmony_ci if (dev->cli.count == 0) 75762306a36Sopenharmony_ci disable_interrupts(dev, I2C_IT_TXFNE); 75862306a36Sopenharmony_ci } 75962306a36Sopenharmony_ci } 76062306a36Sopenharmony_ci break; 76162306a36Sopenharmony_ci 76262306a36Sopenharmony_ci /* 76362306a36Sopenharmony_ci * Rx FIFO nearly full interrupt. 76462306a36Sopenharmony_ci * This is set when the numer of entries in Rx FIFO is 76562306a36Sopenharmony_ci * greater or equal than the threshold value programmed 76662306a36Sopenharmony_ci * in RFT 76762306a36Sopenharmony_ci */ 76862306a36Sopenharmony_ci case I2C_IT_RXFNF: 76962306a36Sopenharmony_ci for (count = rft; count > 0; count--) { 77062306a36Sopenharmony_ci /* Read the Rx FIFO */ 77162306a36Sopenharmony_ci *dev->cli.buffer = readb(dev->virtbase + I2C_RFR); 77262306a36Sopenharmony_ci dev->cli.buffer++; 77362306a36Sopenharmony_ci } 77462306a36Sopenharmony_ci dev->cli.count -= rft; 77562306a36Sopenharmony_ci dev->cli.xfer_bytes += rft; 77662306a36Sopenharmony_ci break; 77762306a36Sopenharmony_ci 77862306a36Sopenharmony_ci /* Rx FIFO full */ 77962306a36Sopenharmony_ci case I2C_IT_RXFF: 78062306a36Sopenharmony_ci for (count = MAX_I2C_FIFO_THRESHOLD; count > 0; count--) { 78162306a36Sopenharmony_ci *dev->cli.buffer = readb(dev->virtbase + I2C_RFR); 78262306a36Sopenharmony_ci dev->cli.buffer++; 78362306a36Sopenharmony_ci } 78462306a36Sopenharmony_ci dev->cli.count -= MAX_I2C_FIFO_THRESHOLD; 78562306a36Sopenharmony_ci dev->cli.xfer_bytes += MAX_I2C_FIFO_THRESHOLD; 78662306a36Sopenharmony_ci break; 78762306a36Sopenharmony_ci 78862306a36Sopenharmony_ci /* Master Transaction Done with/without stop */ 78962306a36Sopenharmony_ci case I2C_IT_MTD: 79062306a36Sopenharmony_ci case I2C_IT_MTDWS: 79162306a36Sopenharmony_ci if (dev->cli.operation == I2C_READ) { 79262306a36Sopenharmony_ci while (!(readl(dev->virtbase + I2C_RISR) 79362306a36Sopenharmony_ci & I2C_IT_RXFE)) { 79462306a36Sopenharmony_ci if (dev->cli.count == 0) 79562306a36Sopenharmony_ci break; 79662306a36Sopenharmony_ci *dev->cli.buffer = 79762306a36Sopenharmony_ci readb(dev->virtbase + I2C_RFR); 79862306a36Sopenharmony_ci dev->cli.buffer++; 79962306a36Sopenharmony_ci dev->cli.count--; 80062306a36Sopenharmony_ci dev->cli.xfer_bytes++; 80162306a36Sopenharmony_ci } 80262306a36Sopenharmony_ci } 80362306a36Sopenharmony_ci 80462306a36Sopenharmony_ci disable_all_interrupts(dev); 80562306a36Sopenharmony_ci clear_all_interrupts(dev); 80662306a36Sopenharmony_ci 80762306a36Sopenharmony_ci if (dev->cli.count) { 80862306a36Sopenharmony_ci dev->result = -EIO; 80962306a36Sopenharmony_ci dev_err(&dev->adev->dev, 81062306a36Sopenharmony_ci "%lu bytes still remain to be xfered\n", 81162306a36Sopenharmony_ci dev->cli.count); 81262306a36Sopenharmony_ci (void) init_hw(dev); 81362306a36Sopenharmony_ci } 81462306a36Sopenharmony_ci complete(&dev->xfer_complete); 81562306a36Sopenharmony_ci 81662306a36Sopenharmony_ci break; 81762306a36Sopenharmony_ci 81862306a36Sopenharmony_ci /* Master Arbitration lost interrupt */ 81962306a36Sopenharmony_ci case I2C_IT_MAL: 82062306a36Sopenharmony_ci dev->result = -EIO; 82162306a36Sopenharmony_ci (void) init_hw(dev); 82262306a36Sopenharmony_ci 82362306a36Sopenharmony_ci i2c_set_bit(dev->virtbase + I2C_ICR, I2C_IT_MAL); 82462306a36Sopenharmony_ci complete(&dev->xfer_complete); 82562306a36Sopenharmony_ci 82662306a36Sopenharmony_ci break; 82762306a36Sopenharmony_ci 82862306a36Sopenharmony_ci /* 82962306a36Sopenharmony_ci * Bus Error interrupt. 83062306a36Sopenharmony_ci * This happens when an unexpected start/stop condition occurs 83162306a36Sopenharmony_ci * during the transaction. 83262306a36Sopenharmony_ci */ 83362306a36Sopenharmony_ci case I2C_IT_BERR: 83462306a36Sopenharmony_ci dev->result = -EIO; 83562306a36Sopenharmony_ci /* get the status */ 83662306a36Sopenharmony_ci if (((readl(dev->virtbase + I2C_SR) >> 2) & 0x3) == I2C_ABORT) 83762306a36Sopenharmony_ci (void) init_hw(dev); 83862306a36Sopenharmony_ci 83962306a36Sopenharmony_ci i2c_set_bit(dev->virtbase + I2C_ICR, I2C_IT_BERR); 84062306a36Sopenharmony_ci complete(&dev->xfer_complete); 84162306a36Sopenharmony_ci 84262306a36Sopenharmony_ci break; 84362306a36Sopenharmony_ci 84462306a36Sopenharmony_ci /* 84562306a36Sopenharmony_ci * Tx FIFO overrun interrupt. 84662306a36Sopenharmony_ci * This is set when a write operation in Tx FIFO is performed and 84762306a36Sopenharmony_ci * the Tx FIFO is full. 84862306a36Sopenharmony_ci */ 84962306a36Sopenharmony_ci case I2C_IT_TXFOVR: 85062306a36Sopenharmony_ci dev->result = -EIO; 85162306a36Sopenharmony_ci (void) init_hw(dev); 85262306a36Sopenharmony_ci 85362306a36Sopenharmony_ci dev_err(&dev->adev->dev, "Tx Fifo Over run\n"); 85462306a36Sopenharmony_ci complete(&dev->xfer_complete); 85562306a36Sopenharmony_ci 85662306a36Sopenharmony_ci break; 85762306a36Sopenharmony_ci 85862306a36Sopenharmony_ci /* unhandled interrupts by this driver - TODO*/ 85962306a36Sopenharmony_ci case I2C_IT_TXFE: 86062306a36Sopenharmony_ci case I2C_IT_TXFF: 86162306a36Sopenharmony_ci case I2C_IT_RXFE: 86262306a36Sopenharmony_ci case I2C_IT_RFSR: 86362306a36Sopenharmony_ci case I2C_IT_RFSE: 86462306a36Sopenharmony_ci case I2C_IT_WTSR: 86562306a36Sopenharmony_ci case I2C_IT_STD: 86662306a36Sopenharmony_ci dev_err(&dev->adev->dev, "unhandled Interrupt\n"); 86762306a36Sopenharmony_ci break; 86862306a36Sopenharmony_ci default: 86962306a36Sopenharmony_ci dev_err(&dev->adev->dev, "spurious Interrupt..\n"); 87062306a36Sopenharmony_ci break; 87162306a36Sopenharmony_ci } 87262306a36Sopenharmony_ci 87362306a36Sopenharmony_ci return IRQ_HANDLED; 87462306a36Sopenharmony_ci} 87562306a36Sopenharmony_ci 87662306a36Sopenharmony_cistatic int nmk_i2c_suspend_late(struct device *dev) 87762306a36Sopenharmony_ci{ 87862306a36Sopenharmony_ci int ret; 87962306a36Sopenharmony_ci 88062306a36Sopenharmony_ci ret = pm_runtime_force_suspend(dev); 88162306a36Sopenharmony_ci if (ret) 88262306a36Sopenharmony_ci return ret; 88362306a36Sopenharmony_ci 88462306a36Sopenharmony_ci pinctrl_pm_select_sleep_state(dev); 88562306a36Sopenharmony_ci return 0; 88662306a36Sopenharmony_ci} 88762306a36Sopenharmony_ci 88862306a36Sopenharmony_cistatic int nmk_i2c_resume_early(struct device *dev) 88962306a36Sopenharmony_ci{ 89062306a36Sopenharmony_ci return pm_runtime_force_resume(dev); 89162306a36Sopenharmony_ci} 89262306a36Sopenharmony_ci 89362306a36Sopenharmony_cistatic int nmk_i2c_runtime_suspend(struct device *dev) 89462306a36Sopenharmony_ci{ 89562306a36Sopenharmony_ci struct amba_device *adev = to_amba_device(dev); 89662306a36Sopenharmony_ci struct nmk_i2c_dev *nmk_i2c = amba_get_drvdata(adev); 89762306a36Sopenharmony_ci 89862306a36Sopenharmony_ci clk_disable_unprepare(nmk_i2c->clk); 89962306a36Sopenharmony_ci pinctrl_pm_select_idle_state(dev); 90062306a36Sopenharmony_ci return 0; 90162306a36Sopenharmony_ci} 90262306a36Sopenharmony_ci 90362306a36Sopenharmony_cistatic int nmk_i2c_runtime_resume(struct device *dev) 90462306a36Sopenharmony_ci{ 90562306a36Sopenharmony_ci struct amba_device *adev = to_amba_device(dev); 90662306a36Sopenharmony_ci struct nmk_i2c_dev *nmk_i2c = amba_get_drvdata(adev); 90762306a36Sopenharmony_ci int ret; 90862306a36Sopenharmony_ci 90962306a36Sopenharmony_ci ret = clk_prepare_enable(nmk_i2c->clk); 91062306a36Sopenharmony_ci if (ret) { 91162306a36Sopenharmony_ci dev_err(dev, "can't prepare_enable clock\n"); 91262306a36Sopenharmony_ci return ret; 91362306a36Sopenharmony_ci } 91462306a36Sopenharmony_ci 91562306a36Sopenharmony_ci pinctrl_pm_select_default_state(dev); 91662306a36Sopenharmony_ci 91762306a36Sopenharmony_ci ret = init_hw(nmk_i2c); 91862306a36Sopenharmony_ci if (ret) { 91962306a36Sopenharmony_ci clk_disable_unprepare(nmk_i2c->clk); 92062306a36Sopenharmony_ci pinctrl_pm_select_idle_state(dev); 92162306a36Sopenharmony_ci } 92262306a36Sopenharmony_ci 92362306a36Sopenharmony_ci return ret; 92462306a36Sopenharmony_ci} 92562306a36Sopenharmony_ci 92662306a36Sopenharmony_cistatic const struct dev_pm_ops nmk_i2c_pm = { 92762306a36Sopenharmony_ci LATE_SYSTEM_SLEEP_PM_OPS(nmk_i2c_suspend_late, nmk_i2c_resume_early) 92862306a36Sopenharmony_ci RUNTIME_PM_OPS(nmk_i2c_runtime_suspend, nmk_i2c_runtime_resume, NULL) 92962306a36Sopenharmony_ci}; 93062306a36Sopenharmony_ci 93162306a36Sopenharmony_cistatic unsigned int nmk_i2c_functionality(struct i2c_adapter *adap) 93262306a36Sopenharmony_ci{ 93362306a36Sopenharmony_ci return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR; 93462306a36Sopenharmony_ci} 93562306a36Sopenharmony_ci 93662306a36Sopenharmony_cistatic const struct i2c_algorithm nmk_i2c_algo = { 93762306a36Sopenharmony_ci .master_xfer = nmk_i2c_xfer, 93862306a36Sopenharmony_ci .functionality = nmk_i2c_functionality 93962306a36Sopenharmony_ci}; 94062306a36Sopenharmony_ci 94162306a36Sopenharmony_cistatic void nmk_i2c_of_probe(struct device_node *np, 94262306a36Sopenharmony_ci struct nmk_i2c_dev *nmk) 94362306a36Sopenharmony_ci{ 94462306a36Sopenharmony_ci /* Default to 100 kHz if no frequency is given in the node */ 94562306a36Sopenharmony_ci if (of_property_read_u32(np, "clock-frequency", &nmk->clk_freq)) 94662306a36Sopenharmony_ci nmk->clk_freq = I2C_MAX_STANDARD_MODE_FREQ; 94762306a36Sopenharmony_ci 94862306a36Sopenharmony_ci /* This driver only supports 'standard' and 'fast' modes of operation. */ 94962306a36Sopenharmony_ci if (nmk->clk_freq <= I2C_MAX_STANDARD_MODE_FREQ) 95062306a36Sopenharmony_ci nmk->sm = I2C_FREQ_MODE_STANDARD; 95162306a36Sopenharmony_ci else 95262306a36Sopenharmony_ci nmk->sm = I2C_FREQ_MODE_FAST; 95362306a36Sopenharmony_ci nmk->tft = 1; /* Tx FIFO threshold */ 95462306a36Sopenharmony_ci nmk->rft = 8; /* Rx FIFO threshold */ 95562306a36Sopenharmony_ci nmk->timeout = 200; /* Slave response timeout(ms) */ 95662306a36Sopenharmony_ci} 95762306a36Sopenharmony_ci 95862306a36Sopenharmony_cistatic int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id) 95962306a36Sopenharmony_ci{ 96062306a36Sopenharmony_ci int ret = 0; 96162306a36Sopenharmony_ci struct device_node *np = adev->dev.of_node; 96262306a36Sopenharmony_ci struct nmk_i2c_dev *dev; 96362306a36Sopenharmony_ci struct i2c_adapter *adap; 96462306a36Sopenharmony_ci struct i2c_vendor_data *vendor = id->data; 96562306a36Sopenharmony_ci u32 max_fifo_threshold = (vendor->fifodepth / 2) - 1; 96662306a36Sopenharmony_ci 96762306a36Sopenharmony_ci dev = devm_kzalloc(&adev->dev, sizeof(*dev), GFP_KERNEL); 96862306a36Sopenharmony_ci if (!dev) 96962306a36Sopenharmony_ci return -ENOMEM; 97062306a36Sopenharmony_ci 97162306a36Sopenharmony_ci dev->vendor = vendor; 97262306a36Sopenharmony_ci dev->adev = adev; 97362306a36Sopenharmony_ci nmk_i2c_of_probe(np, dev); 97462306a36Sopenharmony_ci 97562306a36Sopenharmony_ci if (dev->tft > max_fifo_threshold) { 97662306a36Sopenharmony_ci dev_warn(&adev->dev, "requested TX FIFO threshold %u, adjusted down to %u\n", 97762306a36Sopenharmony_ci dev->tft, max_fifo_threshold); 97862306a36Sopenharmony_ci dev->tft = max_fifo_threshold; 97962306a36Sopenharmony_ci } 98062306a36Sopenharmony_ci 98162306a36Sopenharmony_ci if (dev->rft > max_fifo_threshold) { 98262306a36Sopenharmony_ci dev_warn(&adev->dev, "requested RX FIFO threshold %u, adjusted down to %u\n", 98362306a36Sopenharmony_ci dev->rft, max_fifo_threshold); 98462306a36Sopenharmony_ci dev->rft = max_fifo_threshold; 98562306a36Sopenharmony_ci } 98662306a36Sopenharmony_ci 98762306a36Sopenharmony_ci amba_set_drvdata(adev, dev); 98862306a36Sopenharmony_ci 98962306a36Sopenharmony_ci dev->virtbase = devm_ioremap(&adev->dev, adev->res.start, 99062306a36Sopenharmony_ci resource_size(&adev->res)); 99162306a36Sopenharmony_ci if (!dev->virtbase) 99262306a36Sopenharmony_ci return -ENOMEM; 99362306a36Sopenharmony_ci 99462306a36Sopenharmony_ci dev->irq = adev->irq[0]; 99562306a36Sopenharmony_ci ret = devm_request_irq(&adev->dev, dev->irq, i2c_irq_handler, 0, 99662306a36Sopenharmony_ci DRIVER_NAME, dev); 99762306a36Sopenharmony_ci if (ret) 99862306a36Sopenharmony_ci return dev_err_probe(&adev->dev, ret, 99962306a36Sopenharmony_ci "cannot claim the irq %d\n", dev->irq); 100062306a36Sopenharmony_ci 100162306a36Sopenharmony_ci dev->clk = devm_clk_get_enabled(&adev->dev, NULL); 100262306a36Sopenharmony_ci if (IS_ERR(dev->clk)) 100362306a36Sopenharmony_ci return dev_err_probe(&adev->dev, PTR_ERR(dev->clk), 100462306a36Sopenharmony_ci "could enable i2c clock\n"); 100562306a36Sopenharmony_ci 100662306a36Sopenharmony_ci init_hw(dev); 100762306a36Sopenharmony_ci 100862306a36Sopenharmony_ci adap = &dev->adap; 100962306a36Sopenharmony_ci adap->dev.of_node = np; 101062306a36Sopenharmony_ci adap->dev.parent = &adev->dev; 101162306a36Sopenharmony_ci adap->owner = THIS_MODULE; 101262306a36Sopenharmony_ci adap->class = I2C_CLASS_DEPRECATED; 101362306a36Sopenharmony_ci adap->algo = &nmk_i2c_algo; 101462306a36Sopenharmony_ci adap->timeout = msecs_to_jiffies(dev->timeout); 101562306a36Sopenharmony_ci snprintf(adap->name, sizeof(adap->name), 101662306a36Sopenharmony_ci "Nomadik I2C at %pR", &adev->res); 101762306a36Sopenharmony_ci 101862306a36Sopenharmony_ci i2c_set_adapdata(adap, dev); 101962306a36Sopenharmony_ci 102062306a36Sopenharmony_ci dev_info(&adev->dev, 102162306a36Sopenharmony_ci "initialize %s on virtual base %p\n", 102262306a36Sopenharmony_ci adap->name, dev->virtbase); 102362306a36Sopenharmony_ci 102462306a36Sopenharmony_ci ret = i2c_add_adapter(adap); 102562306a36Sopenharmony_ci if (ret) 102662306a36Sopenharmony_ci return ret; 102762306a36Sopenharmony_ci 102862306a36Sopenharmony_ci pm_runtime_put(&adev->dev); 102962306a36Sopenharmony_ci 103062306a36Sopenharmony_ci return 0; 103162306a36Sopenharmony_ci} 103262306a36Sopenharmony_ci 103362306a36Sopenharmony_cistatic void nmk_i2c_remove(struct amba_device *adev) 103462306a36Sopenharmony_ci{ 103562306a36Sopenharmony_ci struct nmk_i2c_dev *dev = amba_get_drvdata(adev); 103662306a36Sopenharmony_ci 103762306a36Sopenharmony_ci i2c_del_adapter(&dev->adap); 103862306a36Sopenharmony_ci flush_i2c_fifo(dev); 103962306a36Sopenharmony_ci disable_all_interrupts(dev); 104062306a36Sopenharmony_ci clear_all_interrupts(dev); 104162306a36Sopenharmony_ci /* disable the controller */ 104262306a36Sopenharmony_ci i2c_clr_bit(dev->virtbase + I2C_CR, I2C_CR_PE); 104362306a36Sopenharmony_ci} 104462306a36Sopenharmony_ci 104562306a36Sopenharmony_cistatic struct i2c_vendor_data vendor_stn8815 = { 104662306a36Sopenharmony_ci .has_mtdws = false, 104762306a36Sopenharmony_ci .fifodepth = 16, /* Guessed from TFTR/RFTR = 7 */ 104862306a36Sopenharmony_ci}; 104962306a36Sopenharmony_ci 105062306a36Sopenharmony_cistatic struct i2c_vendor_data vendor_db8500 = { 105162306a36Sopenharmony_ci .has_mtdws = true, 105262306a36Sopenharmony_ci .fifodepth = 32, /* Guessed from TFTR/RFTR = 15 */ 105362306a36Sopenharmony_ci}; 105462306a36Sopenharmony_ci 105562306a36Sopenharmony_cistatic const struct amba_id nmk_i2c_ids[] = { 105662306a36Sopenharmony_ci { 105762306a36Sopenharmony_ci .id = 0x00180024, 105862306a36Sopenharmony_ci .mask = 0x00ffffff, 105962306a36Sopenharmony_ci .data = &vendor_stn8815, 106062306a36Sopenharmony_ci }, 106162306a36Sopenharmony_ci { 106262306a36Sopenharmony_ci .id = 0x00380024, 106362306a36Sopenharmony_ci .mask = 0x00ffffff, 106462306a36Sopenharmony_ci .data = &vendor_db8500, 106562306a36Sopenharmony_ci }, 106662306a36Sopenharmony_ci {}, 106762306a36Sopenharmony_ci}; 106862306a36Sopenharmony_ci 106962306a36Sopenharmony_ciMODULE_DEVICE_TABLE(amba, nmk_i2c_ids); 107062306a36Sopenharmony_ci 107162306a36Sopenharmony_cistatic struct amba_driver nmk_i2c_driver = { 107262306a36Sopenharmony_ci .drv = { 107362306a36Sopenharmony_ci .owner = THIS_MODULE, 107462306a36Sopenharmony_ci .name = DRIVER_NAME, 107562306a36Sopenharmony_ci .pm = pm_ptr(&nmk_i2c_pm), 107662306a36Sopenharmony_ci }, 107762306a36Sopenharmony_ci .id_table = nmk_i2c_ids, 107862306a36Sopenharmony_ci .probe = nmk_i2c_probe, 107962306a36Sopenharmony_ci .remove = nmk_i2c_remove, 108062306a36Sopenharmony_ci}; 108162306a36Sopenharmony_ci 108262306a36Sopenharmony_cistatic int __init nmk_i2c_init(void) 108362306a36Sopenharmony_ci{ 108462306a36Sopenharmony_ci return amba_driver_register(&nmk_i2c_driver); 108562306a36Sopenharmony_ci} 108662306a36Sopenharmony_ci 108762306a36Sopenharmony_cistatic void __exit nmk_i2c_exit(void) 108862306a36Sopenharmony_ci{ 108962306a36Sopenharmony_ci amba_driver_unregister(&nmk_i2c_driver); 109062306a36Sopenharmony_ci} 109162306a36Sopenharmony_ci 109262306a36Sopenharmony_cisubsys_initcall(nmk_i2c_init); 109362306a36Sopenharmony_cimodule_exit(nmk_i2c_exit); 109462306a36Sopenharmony_ci 109562306a36Sopenharmony_ciMODULE_AUTHOR("Sachin Verma"); 109662306a36Sopenharmony_ciMODULE_AUTHOR("Srinidhi KASAGAR"); 109762306a36Sopenharmony_ciMODULE_DESCRIPTION("Nomadik/Ux500 I2C driver"); 109862306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 1099