// SPDX-License-Identifier: GPL-2.0-only
/*
* i2c-xiic.c
* Copyright (c) 2002-2007 Xilinx Inc.
* Copyright (c) 2009-2010 Intel Corporation
*
* This code was implemented by Mocean Laboratories AB when porting linux
* to the automotive development board Russellville. The copyright holder
* as seen in the header is Intel corporation.
* Mocean Laboratories forked off the GNU/Linux platform work into a
* separate company called Pelagicore AB, which committed the code to the
* kernel.
*/
/* Supports:
* Xilinx IIC
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/completion.h>
#include <linux/platform_data/i2c-xiic.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/clk.h>
#include <linux/pm_runtime.h>
#define DRIVER_NAME "xiic-i2c"
#define DYNAMIC_MODE_READ_BROKEN_BIT BIT(0)
#define SMBUS_BLOCK_READ_MIN_LEN 3
enum xilinx_i2c_state {
STATE_DONE,
STATE_ERROR,
STATE_START
};
enum xiic_endian {
LITTLE,
BIG
};
enum i2c_scl_freq {
REG_VALUES_100KHZ = 0,
REG_VALUES_400KHZ = 1,
REG_VALUES_1MHZ = 2
};
/**
* struct xiic_i2c - Internal representation of the XIIC I2C bus
* @dev: Pointer to device structure
* @base: Memory base of the HW registers
* @completion: Completion for callers
* @adap: Kernel adapter representation
* @tx_msg: Messages from above to be sent
* @lock: Mutual exclusion
* @tx_pos: Current pos in TX message
* @nmsgs: Number of messages in tx_msg
* @rx_msg: Current RX message
* @rx_pos: Position within current RX message
* @endianness: big/little-endian byte order
* @clk: Pointer to AXI4-lite input clock
* @state: See STATE_
* @singlemaster: Indicates bus is single master
* @dynamic: Mode of controller
* @prev_msg_tx: Previous message is Tx
* @quirks: To hold platform specific bug info
* @smbus_block_read: Flag to handle block read
* @input_clk: Input clock to I2C controller
* @i2c_clk: I2C SCL frequency
*/
struct xiic_i2c {
struct device *dev;
void __iomem *base;
struct completion completion;
struct i2c_adapter adap;
struct i2c_msg *tx_msg;
struct mutex lock;
unsigned int tx_pos;
unsigned int nmsgs;
struct i2c_msg *rx_msg;
int rx_pos;
enum xiic_endian endianness;
struct clk *clk;
enum xilinx_i2c_state state;
bool singlemaster;
bool dynamic;
bool prev_msg_tx;
u32 quirks;
bool smbus_block_read;
unsigned long input_clk;
unsigned int i2c_clk;
};
struct xiic_version_data {
u32 quirks;
};
/**
* struct timing_regs - AXI I2C timing registers that depend on I2C spec
* @tsusta: setup time for a repeated START condition
* @tsusto: setup time for a STOP condition