#include <linux/module.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/completion.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/slab.h>
#include <linux/platform_data/i2c-omap.h>
#include <linux/pm_runtime.h>
#include <linux/pinctrl/consumer.h>
#include <linux/property.h>
#define OMAP_I2C_OMAP1_REV_2 …
#define OMAP_I2C_REV_ON_2430 …
#define OMAP_I2C_REV_ON_3430_3530 …
#define OMAP_I2C_REV_ON_3630 …
#define OMAP_I2C_REV_ON_4430_PLUS …
#define OMAP_I2C_TIMEOUT …
#define OMAP_I2C_PM_TIMEOUT …
#define OMAP_I2C_BUS_FREE_TIMEOUT …
enum { … };
#define OMAP_I2C_IE_XDR …
#define OMAP_I2C_IE_RDR …
#define OMAP_I2C_IE_XRDY …
#define OMAP_I2C_IE_RRDY …
#define OMAP_I2C_IE_ARDY …
#define OMAP_I2C_IE_NACK …
#define OMAP_I2C_IE_AL …
#define OMAP_I2C_STAT_XDR …
#define OMAP_I2C_STAT_RDR …
#define OMAP_I2C_STAT_BB …
#define OMAP_I2C_STAT_ROVR …
#define OMAP_I2C_STAT_XUDF …
#define OMAP_I2C_STAT_AAS …
#define OMAP_I2C_STAT_BF …
#define OMAP_I2C_STAT_XRDY …
#define OMAP_I2C_STAT_RRDY …
#define OMAP_I2C_STAT_ARDY …
#define OMAP_I2C_STAT_NACK …
#define OMAP_I2C_STAT_AL …
#define OMAP_I2C_WE_XDR_WE …
#define OMAP_I2C_WE_RDR_WE …
#define OMAP_I2C_WE_AAS_WE …
#define OMAP_I2C_WE_BF_WE …
#define OMAP_I2C_WE_STC_WE …
#define OMAP_I2C_WE_GC_WE …
#define OMAP_I2C_WE_DRDY_WE …
#define OMAP_I2C_WE_ARDY_WE …
#define OMAP_I2C_WE_NACK_WE …
#define OMAP_I2C_WE_AL_WE …
#define OMAP_I2C_WE_ALL …
#define OMAP_I2C_BUF_RDMA_EN …
#define OMAP_I2C_BUF_RXFIF_CLR …
#define OMAP_I2C_BUF_XDMA_EN …
#define OMAP_I2C_BUF_TXFIF_CLR …
#define OMAP_I2C_CON_EN …
#define OMAP_I2C_CON_BE …
#define OMAP_I2C_CON_OPMODE_HS …
#define OMAP_I2C_CON_STB …
#define OMAP_I2C_CON_MST …
#define OMAP_I2C_CON_TRX …
#define OMAP_I2C_CON_XA …
#define OMAP_I2C_CON_RM …
#define OMAP_I2C_CON_STP …
#define OMAP_I2C_CON_STT …
#define OMAP_I2C_SCLL_HSSCLL …
#define OMAP_I2C_SCLH_HSSCLH …
#define OMAP_I2C_SYSTEST_ST_EN …
#define OMAP_I2C_SYSTEST_FREE …
#define OMAP_I2C_SYSTEST_TMODE_MASK …
#define OMAP_I2C_SYSTEST_TMODE_SHIFT …
#define OMAP_I2C_SYSTEST_SCL_I_FUNC …
#define OMAP_I2C_SYSTEST_SCL_O_FUNC …
#define OMAP_I2C_SYSTEST_SDA_I_FUNC …
#define OMAP_I2C_SYSTEST_SDA_O_FUNC …
#define OMAP_I2C_SYSTEST_SCL_I …
#define OMAP_I2C_SYSTEST_SCL_O …
#define OMAP_I2C_SYSTEST_SDA_I …
#define OMAP_I2C_SYSTEST_SDA_O …
#define SYSS_RESETDONE_MASK …
#define SYSC_CLOCKACTIVITY_MASK …
#define SYSC_SIDLEMODE_MASK …
#define SYSC_ENAWAKEUP_MASK …
#define SYSC_SOFTRESET_MASK …
#define SYSC_AUTOIDLE_MASK …
#define SYSC_IDLEMODE_SMART …
#define SYSC_CLOCKACTIVITY_FCLK …
#define I2C_OMAP_ERRATA_I207 …
#define I2C_OMAP_ERRATA_I462 …
#define OMAP_I2C_IP_V2_INTERRUPTS_MASK …
struct omap_i2c_dev { … };
static const u8 reg_map_ip_v1[] = …;
static const u8 reg_map_ip_v2[] = …;
static int omap_i2c_xfer_data(struct omap_i2c_dev *omap);
static inline void omap_i2c_write_reg(struct omap_i2c_dev *omap,
int reg, u16 val)
{ … }
static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *omap, int reg)
{ … }
static void __omap_i2c_init(struct omap_i2c_dev *omap)
{ … }
static int omap_i2c_reset(struct omap_i2c_dev *omap)
{ … }
static int omap_i2c_init(struct omap_i2c_dev *omap)
{ … }
static int omap_i2c_recover_bus(struct omap_i2c_dev *omap)
{ … }
static int omap_i2c_wait_for_bb(struct omap_i2c_dev *omap)
{ … }
static int omap_i2c_wait_for_bb_valid(struct omap_i2c_dev *omap)
{ … }
static void omap_i2c_resize_fifo(struct omap_i2c_dev *omap, u8 size, bool is_rx)
{ … }
static void omap_i2c_wait(struct omap_i2c_dev *omap)
{ … }
static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
struct i2c_msg *msg, int stop, bool polling)
{ … }
static int
omap_i2c_xfer_common(struct i2c_adapter *adap, struct i2c_msg msgs[], int num,
bool polling)
{ … }
static int
omap_i2c_xfer_irq(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
{ … }
static int
omap_i2c_xfer_polling(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
{ … }
static u32
omap_i2c_func(struct i2c_adapter *adap)
{ … }
static inline void
omap_i2c_complete_cmd(struct omap_i2c_dev *omap, u16 err)
{ … }
static inline void
omap_i2c_ack_stat(struct omap_i2c_dev *omap, u16 stat)
{ … }
static inline void i2c_omap_errata_i207(struct omap_i2c_dev *omap, u16 stat)
{ … }
#ifdef CONFIG_ARCH_OMAP15XX
static irqreturn_t
omap_i2c_omap1_isr(int this_irq, void *dev_id)
{
struct omap_i2c_dev *omap = dev_id;
u16 iv, w;
if (pm_runtime_suspended(omap->dev))
return IRQ_NONE;
iv = omap_i2c_read_reg(omap, OMAP_I2C_IV_REG);
switch (iv) {
case 0x00:
break;
case 0x01:
dev_err(omap->dev, "Arbitration lost\n");
omap_i2c_complete_cmd(omap, OMAP_I2C_STAT_AL);
break;
case 0x02:
omap_i2c_complete_cmd(omap, OMAP_I2C_STAT_NACK);
omap_i2c_write_reg(omap, OMAP_I2C_CON_REG, OMAP_I2C_CON_STP);
break;
case 0x03:
omap_i2c_complete_cmd(omap, 0);
break;
case 0x04:
if (omap->buf_len) {
w = omap_i2c_read_reg(omap, OMAP_I2C_DATA_REG);
*omap->buf++ = w;
omap->buf_len--;
if (omap->buf_len) {
*omap->buf++ = w >> 8;
omap->buf_len--;
}
} else
dev_err(omap->dev, "RRDY IRQ while no data requested\n");
break;
case 0x05:
if (omap->buf_len) {
w = *omap->buf++;
omap->buf_len--;
if (omap->buf_len) {
w |= *omap->buf++ << 8;
omap->buf_len--;
}
omap_i2c_write_reg(omap, OMAP_I2C_DATA_REG, w);
} else
dev_err(omap->dev, "XRDY IRQ while no data to send\n");
break;
default:
return IRQ_NONE;
}
return IRQ_HANDLED;
}
#else
#define omap_i2c_omap1_isr …
#endif
static int errata_omap3_i462(struct omap_i2c_dev *omap)
{ … }
static void omap_i2c_receive_data(struct omap_i2c_dev *omap, u8 num_bytes,
bool is_rdr)
{ … }
static int omap_i2c_transmit_data(struct omap_i2c_dev *omap, u8 num_bytes,
bool is_xdr)
{ … }
static irqreturn_t
omap_i2c_isr(int irq, void *dev_id)
{ … }
static int omap_i2c_xfer_data(struct omap_i2c_dev *omap)
{ … }
static irqreturn_t
omap_i2c_isr_thread(int this_irq, void *dev_id)
{ … }
static const struct i2c_algorithm omap_i2c_algo = …;
static const struct i2c_adapter_quirks omap_i2c_quirks = …;
#ifdef CONFIG_OF
static struct omap_i2c_bus_platform_data omap2420_pdata = …;
static struct omap_i2c_bus_platform_data omap2430_pdata = …;
static struct omap_i2c_bus_platform_data omap3_pdata = …;
static struct omap_i2c_bus_platform_data omap4_pdata = …;
static const struct of_device_id omap_i2c_of_match[] = …;
MODULE_DEVICE_TABLE(of, omap_i2c_of_match);
#endif
#define OMAP_I2C_SCHEME(rev) …
#define OMAP_I2C_REV_SCHEME_0_MAJOR(rev) …
#define OMAP_I2C_REV_SCHEME_0_MINOR(rev) …
#define OMAP_I2C_REV_SCHEME_1_MAJOR(rev) …
#define OMAP_I2C_REV_SCHEME_1_MINOR(rev) …
#define OMAP_I2C_SCHEME_0 …
#define OMAP_I2C_SCHEME_1 …
static int omap_i2c_get_scl(struct i2c_adapter *adap)
{ … }
static int omap_i2c_get_sda(struct i2c_adapter *adap)
{ … }
static void omap_i2c_set_scl(struct i2c_adapter *adap, int val)
{ … }
static void omap_i2c_prepare_recovery(struct i2c_adapter *adap)
{ … }
static void omap_i2c_unprepare_recovery(struct i2c_adapter *adap)
{ … }
static struct i2c_bus_recovery_info omap_i2c_bus_recovery_info = …;
static int
omap_i2c_probe(struct platform_device *pdev)
{ … }
static void omap_i2c_remove(struct platform_device *pdev)
{ … }
static int omap_i2c_runtime_suspend(struct device *dev)
{ … }
static int omap_i2c_runtime_resume(struct device *dev)
{ … }
static int omap_i2c_suspend(struct device *dev)
{ … }
static int omap_i2c_resume(struct device *dev)
{ … }
static const struct dev_pm_ops omap_i2c_pm_ops = …;
static struct platform_driver omap_i2c_driver = …;
static int __init
omap_i2c_init_driver(void)
{ … }
subsys_initcall(omap_i2c_init_driver);
static void __exit omap_i2c_exit_driver(void)
{ … }
module_exit(omap_i2c_exit_driver);
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;
MODULE_ALIAS(…) …;