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

// SPDX-License-Identifier: GPL-2.0-or-later
/* linux/drivers/i2c/busses/i2c-s3c2410.c
 *
 * Copyright (C) 2004,2005,2009 Simtec Electronics
 *	Ben Dooks <[email protected]>
 *
 * S3C2410 I2C Controller
*/

#include <linux/kernel.h>
#include <linux/module.h>

#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/time.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/gpio/consumer.h>
#include <linux/pinctrl/consumer.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>

#include <asm/irq.h>

#include <linux/platform_data/i2c-s3c2410.h>

/* see s3c2410x user guide, v1.1, section 9 (p447) for more info */

#define S3C2410_IICCON
#define S3C2410_IICSTAT
#define S3C2410_IICADD
#define S3C2410_IICDS
#define S3C2440_IICLC

#define S3C2410_IICCON_ACKEN
#define S3C2410_IICCON_TXDIV_16
#define S3C2410_IICCON_TXDIV_512
#define S3C2410_IICCON_IRQEN
#define S3C2410_IICCON_IRQPEND
#define S3C2410_IICCON_SCALE(x)
#define S3C2410_IICCON_SCALEMASK

#define S3C2410_IICSTAT_MASTER_RX
#define S3C2410_IICSTAT_MASTER_TX
#define S3C2410_IICSTAT_SLAVE_RX
#define S3C2410_IICSTAT_SLAVE_TX
#define S3C2410_IICSTAT_MODEMASK

#define S3C2410_IICSTAT_START
#define S3C2410_IICSTAT_BUSBUSY
#define S3C2410_IICSTAT_TXRXEN
#define S3C2410_IICSTAT_ARBITR
#define S3C2410_IICSTAT_ASSLAVE
#define S3C2410_IICSTAT_ADDR0
#define S3C2410_IICSTAT_LASTBIT

#define S3C2410_IICLC_SDA_DELAY0
#define S3C2410_IICLC_SDA_DELAY5
#define S3C2410_IICLC_SDA_DELAY10
#define S3C2410_IICLC_SDA_DELAY15
#define S3C2410_IICLC_SDA_DELAY_MASK

#define S3C2410_IICLC_FILTER_ON

/* Treat S3C2410 as baseline hardware, anything else is supported via quirks */
#define QUIRK_S3C2440
#define QUIRK_HDMIPHY
#define QUIRK_NO_GPIO
#define QUIRK_POLL
#define QUIRK_ATOMIC

/* Max time to wait for bus to become idle after a xfer (in us) */
#define S3C2410_IDLE_TIMEOUT

/* Exynos5 Sysreg offset */
#define EXYNOS5_SYS_I2C_CFG

/* i2c controller state */
enum s3c24xx_i2c_state {};

struct s3c24xx_i2c {};

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

static void i2c_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat);

#ifdef CONFIG_OF
static const struct of_device_id s3c24xx_i2c_match[] =;
MODULE_DEVICE_TABLE(of, s3c24xx_i2c_match);
#endif

/*
 * Get controller type either from device tree or platform device variant.
 */
static inline kernel_ulong_t s3c24xx_get_device_quirks(struct platform_device *pdev)
{}

/*
 * Complete the message and wake up the caller, using the given return code,
 * or zero to mean ok.
 */
static inline void s3c24xx_i2c_master_complete(struct s3c24xx_i2c *i2c, int ret)
{}

static inline void s3c24xx_i2c_disable_ack(struct s3c24xx_i2c *i2c)
{}

static inline void s3c24xx_i2c_enable_ack(struct s3c24xx_i2c *i2c)
{}

/* irq enable/disable functions */
static inline void s3c24xx_i2c_disable_irq(struct s3c24xx_i2c *i2c)
{}

static inline void s3c24xx_i2c_enable_irq(struct s3c24xx_i2c *i2c)
{}

static bool is_ack(struct s3c24xx_i2c *i2c)
{}

/*
 * put the start of a message onto the bus
 */
static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,
				      struct i2c_msg *msg)
{}

static inline void s3c24xx_i2c_stop(struct s3c24xx_i2c *i2c, int ret)
{}

/*
 * helper functions to determine the current state in the set of
 * messages we are sending
 */

/*
 * returns TRUE if the current message is the last in the set
 */
static inline int is_lastmsg(struct s3c24xx_i2c *i2c)
{}

/*
 * returns TRUE if we this is the last byte in the current message
 */
static inline int is_msglast(struct s3c24xx_i2c *i2c)
{}

/*
 * returns TRUE if we reached the end of the current message
 */
static inline int is_msgend(struct s3c24xx_i2c *i2c)
{}

/*
 * process an interrupt and work out what to do
 */
static void i2c_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
{}

/*
 * top level IRQ servicing routine
 */
static irqreturn_t s3c24xx_i2c_irq(int irqno, void *dev_id)
{}

/*
 * Disable the bus so that we won't get any interrupts from now on, or try
 * to drive any lines. This is the default state when we don't have
 * anything to send/receive.
 *
 * If there is an event on the bus, or we have a pre-existing event at
 * kernel boot time, we may not notice the event and the I2C controller
 * will lock the bus with the I2C clock line low indefinitely.
 */
static inline void s3c24xx_i2c_disable_bus(struct s3c24xx_i2c *i2c)
{}


/*
 * get the i2c bus for a master transaction
 */
static int s3c24xx_i2c_set_master(struct s3c24xx_i2c *i2c)
{}

/*
 * wait for the i2c bus to become idle.
 */
static void s3c24xx_i2c_wait_idle(struct s3c24xx_i2c *i2c)
{}

/*
 * this starts an i2c transfer
 */
static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
			      struct i2c_msg *msgs, int num)
{}

/*
 * first port of call from the i2c bus code when an message needs
 * transferring across the i2c bus.
 */
static int s3c24xx_i2c_xfer(struct i2c_adapter *adap,
			struct i2c_msg *msgs, int num)
{}

static int s3c24xx_i2c_xfer_atomic(struct i2c_adapter *adap,
				   struct i2c_msg *msgs, int num)
{}

/* declare our i2c functionality */
static u32 s3c24xx_i2c_func(struct i2c_adapter *adap)
{}

/* i2c bus registration info */
static const struct i2c_algorithm s3c24xx_i2c_algorithm =;

/*
 * return the divisor settings for a given frequency
 */
static int s3c24xx_i2c_calcdivisor(unsigned long clkin, unsigned int wanted,
				   unsigned int *div1, unsigned int *divs)
{}

/*
 * work out a divisor for the user requested frequency setting,
 * either by the requested frequency, or scanning the acceptable
 * range of frequencies until something is found
 */
static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got)
{}

#ifdef CONFIG_OF
static int s3c24xx_i2c_parse_dt_gpio(struct s3c24xx_i2c *i2c)
{}

#else
static int s3c24xx_i2c_parse_dt_gpio(struct s3c24xx_i2c *i2c)
{
	return 0;
}
#endif

/*
 * initialise the controller, set the IO lines and frequency
 */
static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
{}

#ifdef CONFIG_OF
/*
 * Parse the device tree node and retreive the platform data.
 */
static void
s3c24xx_i2c_parse_dt(struct device_node *np, struct s3c24xx_i2c *i2c)
{}
#else
static void
s3c24xx_i2c_parse_dt(struct device_node *np, struct s3c24xx_i2c *i2c) { }
#endif

static int s3c24xx_i2c_probe(struct platform_device *pdev)
{}

static void s3c24xx_i2c_remove(struct platform_device *pdev)
{}

static int s3c24xx_i2c_suspend_noirq(struct device *dev)
{}

static int s3c24xx_i2c_resume_noirq(struct device *dev)
{}

static const struct dev_pm_ops s3c24xx_i2c_dev_pm_ops =;

static struct platform_driver s3c24xx_i2c_driver =;

static int __init i2c_adap_s3c_init(void)
{}
subsys_initcall(i2c_adap_s3c_init);

static void __exit i2c_adap_s3c_exit(void)
{}
module_exit(i2c_adap_s3c_exit);

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();