linux/drivers/i2c/busses/i2c-pxa.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 *  i2c_adap_pxa.c
 *
 *  I2C adapter for the PXA I2C bus access.
 *
 *  Copyright (C) 2002 Intrinsyc Software Inc.
 *  Copyright (C) 2004-2005 Deep Blue Solutions Ltd.
 *
 *  History:
 *    Apr 2002: Initial version [CS]
 *    Jun 2002: Properly separated algo/adap [FB]
 *    Jan 2003: Fixed several bugs concerning interrupt handling [Kai-Uwe Bloem]
 *    Jan 2003: added limited signal handling [Kai-Uwe Bloem]
 *    Sep 2004: Major rework to ensure efficient bus handling [RMK]
 *    Dec 2004: Added support for PXA27x and slave device probing [Liam Girdwood]
 *    Feb 2005: Rework slave mode handling [RMK]
 */
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/platform_data/i2c-pxa.h>
#include <linux/property.h>
#include <linux/slab.h>

/* I2C register field definitions */
#define IBMR_SDAS
#define IBMR_SCLS

#define ICR_START
#define ICR_STOP
#define ICR_ACKNAK
#define ICR_TB
#define ICR_MA
#define ICR_SCLE
#define ICR_IUE
#define ICR_GCD
#define ICR_ITEIE
#define ICR_IRFIE
#define ICR_BEIE
#define ICR_SSDIE
#define ICR_ALDIE
#define ICR_SADIE
#define ICR_UR
#define ICR_FM
#define ICR_HS
#define ICR_A3700_FM
#define ICR_A3700_HS
#define ICR_GPIOEN

#define ISR_RWM
#define ISR_ACKNAK
#define ISR_UB
#define ISR_IBB
#define ISR_SSD
#define ISR_ALD
#define ISR_ITE
#define ISR_IRF
#define ISR_GCAD
#define ISR_SAD
#define ISR_BED

#define ILCR_SLV_SHIFT
#define ILCR_SLV_MASK
#define ILCR_FLV_SHIFT
#define ILCR_FLV_MASK
#define ILCR_HLVL_SHIFT
#define ILCR_HLVL_MASK
#define ILCR_HLVH_SHIFT
#define ILCR_HLVH_MASK

#define IWCR_CNT_SHIFT
#define IWCR_CNT_MASK
#define IWCR_HS_CNT1_SHIFT
#define IWCR_HS_CNT1_MASK
#define IWCR_HS_CNT2_SHIFT
#define IWCR_HS_CNT2_MASK

/* need a longer timeout if we're dealing with the fact we may well be
 * looking at a multi-master environment
 */
#define DEF_TIMEOUT

#define NO_SLAVE
#define BUS_ERROR
#define XFER_NAKED
#define I2C_RETRY

/* ICR initialize bit values
 *
 * 15 FM     0 (100 kHz operation)
 * 14 UR     0 (No unit reset)
 * 13 SADIE  0 (Disables the unit from interrupting on slave addresses
 *              matching its slave address)
 * 12 ALDIE  0 (Disables the unit from interrupt when it loses arbitration
 *              in master mode)
 * 11 SSDIE  0 (Disables interrupts from a slave stop detected, in slave mode)
 * 10 BEIE   1 (Enable interrupts from detected bus errors, no ACK sent)
 *  9 IRFIE  1 (Enable interrupts from full buffer received)
 *  8 ITEIE  1 (Enables the I2C unit to interrupt when transmit buffer empty)
 *  7 GCD    1 (Disables i2c unit response to general call messages as a slave)
 *  6 IUE    0 (Disable unit until we change settings)
 *  5 SCLE   1 (Enables the i2c clock output for master mode (drives SCL)
 *  4 MA     0 (Only send stop with the ICR stop bit)
 *  3 TB     0 (We are not transmitting a byte initially)
 *  2 ACKNAK 0 (Send an ACK after the unit receives a byte)
 *  1 STOP   0 (Do not send a STOP)
 *  0 START  0 (Do not send a START)
 */
#define I2C_ICR_INIT

/* I2C status register init values
 *
 * 10 BED    1 (Clear bus error detected)
 *  9 SAD    1 (Clear slave address detected)
 *  7 IRF    1 (Clear IDBR Receive Full)
 *  6 ITE    1 (Clear IDBR Transmit Empty)
 *  5 ALD    1 (Clear Arbitration Loss Detected)
 *  4 SSD    1 (Clear Slave Stop Detected)
 */
#define I2C_ISR_INIT

struct pxa_reg_layout {};

enum pxa_i2c_types {};

/* I2C register layout definitions */
static struct pxa_reg_layout pxa_reg_layout[] =;

static const struct of_device_id i2c_pxa_dt_ids[] =;
MODULE_DEVICE_TABLE(of, i2c_pxa_dt_ids);

static const struct platform_device_id i2c_pxa_id_table[] =;
MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table);

struct pxa_i2c {};

#define _IBMR(i2c)
#define _IDBR(i2c)
#define _ICR(i2c)
#define _ISR(i2c)
#define _ISAR(i2c)
#define _ILCR(i2c)
#define _IWCR(i2c)

/*
 * I2C Slave mode address
 */
#define I2C_PXA_SLAVE_ADDR

#ifdef DEBUG

struct bits {};
#define PXA_BIT(m, s, u)

static inline void
decode_bits(const char *prefix, const struct bits *bits, int num, u32 val)
{}

static const struct bits isr_bits[] =;

static void decode_ISR(unsigned int val)
{}

#ifdef CONFIG_I2C_PXA_SLAVE
static const struct bits icr_bits[] =;

static void decode_ICR(unsigned int val)
{}
#endif

static unsigned int i2c_debug =;

static void i2c_pxa_show_state(struct pxa_i2c *i2c, int lno, const char *fname)
{}

#define show_state(i2c)

static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why)
{}

#else /* ifdef DEBUG */

#define i2c_debug

#define show_state
#define decode_ISR
#define decode_ICR
#define i2c_pxa_scream_blue_murder

#endif /* ifdef DEBUG / else */

static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret);

static inline int i2c_pxa_is_slavemode(struct pxa_i2c *i2c)
{}

static void i2c_pxa_abort(struct pxa_i2c *i2c)
{}

static int i2c_pxa_wait_bus_not_busy(struct pxa_i2c *i2c)
{}

static int i2c_pxa_wait_master(struct pxa_i2c *i2c)
{}

static int i2c_pxa_set_master(struct pxa_i2c *i2c)
{}

#ifdef CONFIG_I2C_PXA_SLAVE
static int i2c_pxa_wait_slave(struct pxa_i2c *i2c)
{}

/*
 * clear the hold on the bus, and take of anything else
 * that has been configured
 */
static void i2c_pxa_set_slave(struct pxa_i2c *i2c, int errcode)
{}
#else
#define i2c_pxa_set_slave
#endif

static void i2c_pxa_do_reset(struct pxa_i2c *i2c)
{}

static void i2c_pxa_enable(struct pxa_i2c *i2c)
{}

static void i2c_pxa_reset(struct pxa_i2c *i2c)
{}


#ifdef CONFIG_I2C_PXA_SLAVE
/*
 * PXA I2C Slave mode
 */

static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr)
{}

static void i2c_pxa_slave_rxfull(struct pxa_i2c *i2c, u32 isr)
{}

static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
{}

static void i2c_pxa_slave_stop(struct pxa_i2c *i2c)
{}

static int i2c_pxa_slave_reg(struct i2c_client *slave)
{}

static int i2c_pxa_slave_unreg(struct i2c_client *slave)
{}
#else
static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr)
{
	if (isr & ISR_BED) {
		/* what should we do here? */
	} else {
		writel(0, _IDBR(i2c));
		writel(readl(_ICR(i2c)) | ICR_TB, _ICR(i2c));
	}
}

static void i2c_pxa_slave_rxfull(struct pxa_i2c *i2c, u32 isr)
{
	writel(readl(_ICR(i2c)) | ICR_TB | ICR_ACKNAK, _ICR(i2c));
}

static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
{
	int timeout;

	/*
	 * slave could interrupt in the middle of us generating a
	 * start condition... if this happens, we'd better back off
	 * and stop holding the poor thing up
	 */
	writel(readl(_ICR(i2c)) & ~(ICR_START|ICR_STOP), _ICR(i2c));
	writel(readl(_ICR(i2c)) | ICR_TB | ICR_ACKNAK, _ICR(i2c));

	timeout = 0x10000;

	while (1) {
		if ((readl(_IBMR(i2c)) & IBMR_SCLS) == IBMR_SCLS)
			break;

		timeout--;

		if (timeout <= 0) {
			dev_err(&i2c->adap.dev, "timeout waiting for SCL high\n");
			break;
		}
	}

	writel(readl(_ICR(i2c)) & ~ICR_SCLE, _ICR(i2c));
}

static void i2c_pxa_slave_stop(struct pxa_i2c *i2c)
{
	if (i2c->msg)
		i2c_pxa_master_complete(i2c, I2C_RETRY);
}
#endif

/*
 * PXA I2C Master mode
 */

static inline void i2c_pxa_start_message(struct pxa_i2c *i2c)
{}

static inline void i2c_pxa_stop_message(struct pxa_i2c *i2c)
{}

/*
 * PXA I2C send master code
 * 1. Load master code to IDBR and send it.
 *    Note for HS mode, set ICR [GPIOEN].
 * 2. Wait until win arbitration.
 */
static int i2c_pxa_send_mastercode(struct pxa_i2c *i2c)
{}

/*
 * i2c_pxa_master_complete - complete the message and wake up.
 */
static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret)
{}

static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr)
{}

static void i2c_pxa_irq_rxfull(struct pxa_i2c *i2c, u32 isr)
{}

#define VALID_INT_SOURCE
static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id)
{}

/*
 * We are protected by the adapter bus mutex.
 */
static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
{}

static int i2c_pxa_internal_xfer(struct pxa_i2c *i2c,
				 struct i2c_msg *msgs, int num,
				 int (*xfer)(struct pxa_i2c *,
					     struct i2c_msg *, int num))
{}

static int i2c_pxa_xfer(struct i2c_adapter *adap,
			struct i2c_msg msgs[], int num)
{}

static u32 i2c_pxa_functionality(struct i2c_adapter *adap)
{}

static const struct i2c_algorithm i2c_pxa_algorithm =;

/* Non-interrupt mode support */
static int i2c_pxa_pio_set_master(struct pxa_i2c *i2c)
{}

static int i2c_pxa_do_pio_xfer(struct pxa_i2c *i2c,
			       struct i2c_msg *msg, int num)
{}

static int i2c_pxa_pio_xfer(struct i2c_adapter *adap,
			    struct i2c_msg msgs[], int num)
{}

static const struct i2c_algorithm i2c_pxa_pio_algorithm =;

static int i2c_pxa_probe_dt(struct platform_device *pdev, struct pxa_i2c *i2c,
			    enum pxa_i2c_types *i2c_types)
{}

static int i2c_pxa_probe_pdata(struct platform_device *pdev,
			       struct pxa_i2c *i2c,
			       enum pxa_i2c_types *i2c_types)
{}

static void i2c_pxa_prepare_recovery(struct i2c_adapter *adap)
{}

static void i2c_pxa_unprepare_recovery(struct i2c_adapter *adap)
{}

static int i2c_pxa_init_recovery(struct pxa_i2c *i2c)
{}

static int i2c_pxa_probe(struct platform_device *dev)
{}

static void i2c_pxa_remove(struct platform_device *dev)
{}

static int i2c_pxa_suspend_noirq(struct device *dev)
{}

static int i2c_pxa_resume_noirq(struct device *dev)
{}

static const struct dev_pm_ops i2c_pxa_dev_pm_ops =;

static struct platform_driver i2c_pxa_driver =;

static int __init i2c_adap_pxa_init(void)
{}

static void __exit i2c_adap_pxa_exit(void)
{}

MODULE_DESCRIPTION();
MODULE_LICENSE();

subsys_initcall(i2c_adap_pxa_init);
module_exit(i2c_adap_pxa_exit);