/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
+#define S5J_DEFAULT_I2CXFER_CLOCK 100*1000 /* 100Khz */
+#define S5J_DEFAULT_I2CSLAVE_ADDR 0x22
+#define S5J_DEFAULT_I2C_TIMEOUT 10000
-/* Interrupt wait timeout in seconds and milliseconds */
-
-#if !defined(CONFIG_S5J_I2C_TIMEOSEC) && !defined(CONFIG_S5J_I2C_TIMEOMS)
-#define CONFIG_S5J_I2C_TIMEOSEC 0
-#define CONFIG_S5J_I2C_TIMEOMS 500 /* Default is 500 milliseconds */
-#elif !defined(CONFIG_S5J_I2C_TIMEOSEC)
-#define CONFIG_S5J_I2C_TIMEOSEC 0 /* User provided milliseconds */
-#elif !defined(CONFIG_S5J_I2C_TIMEOMS)
-#define CONFIG_S5J_I2C_TIMEOMS 0 /* User provided seconds */
-#endif
-
-/* Interrupt wait time timeout in system timer ticks */
-
-#ifndef CONFIG_S5J_I2C_TIMEOTICKS
-#define CONFIG_S5J_I2C_TIMEOTICKS \
-(SEC2TICK(CONFIG_S5J_I2C_TIMEOSEC) + MSEC2TICK(CONFIG_S5J_I2C_TIMEOMS))
-#endif
-
-#ifndef CONFIG_S5J_I2C_DYNTIMEO_STARTSTOP
-#define CONFIG_S5J_I2C_DYNTIMEO_STARTSTOP TICK2USEC(CONFIG_S5J_I2C_TIMEOTICKS)
-#endif
-
-/* Debug ****************************************************************************/
-/* CONFIG_DEBUG_I2C + CONFIG_DEBUG enables general I2C debug output. */
-
-#ifdef CONFIG_DEBUG_I2C
-#define i2cdbg dbg
-#define i2cvdbg vdbg
-#else
-#define i2cdbg(x...)
-#define i2cvdbg(x...)
-#endif
-
+#define HSI2C_INT_XFER_DONE (HSI2C_INT_XFER_DONE_NOACK_MANUAL | HSI2C_INT_XFER_DONE_MANUAL)
/************************************************************************************
* Private Types
************************************************************************************/
-/* Interrupt state */
-enum s5j_intstate_e {
- INTSTATE_IDLE = 0, /* No I2C activity */
- INTSTATE_WAITING, /* Waiting for data transfer to complete */
- INTSTATE_DONE /* Interrupt activity complete */
-};
-/* I2C Device hardware configuration */
-struct s5j_i2c_config_s {
- uintptr_t base; /* I2C base address */
- uint32_t scl_pin; /* GPIO configuration for SCL as SCL */
- uint32_t sda_pin; /* GPIO configuration for SDA as SDA */
- int (*isr)(int, void *); /* Interrupt handler */
- uint32_t irq; /* IRQ number */
- uint8_t devno; /* I2Cn where n = devno */
-};
-
-/* I2C Device Private Data */
-
-struct s5j_i2c_priv_s {
- const struct i2c_ops_s *ops; /* Standard I2C operations */
- const struct s5j_i2c_config_s *config; /* Port configuration */
- sem_t exclsem; /* Mutual exclusion semaphore */
-#ifndef CONFIG_I2C_POLLED
- sem_t waitsem; /* Interrupt wait semaphore */
-#endif
- uint8_t refs; /* Reference count */
- volatile uint8_t intstate; /* Interrupt handshake (see enum s5j_intstate_e) */
-
- int state;
- int clock;
- int xfer_speed;
- u32 master;
- u32 mode;
- u32 slave_addr;
- u32 addrlen;
- u32 timeout;
- char name[48];
-
- u32 initialized;
- u32 retries;
- /* master data */
- uint8_t msgc; /* Message count */
- struct i2c_msg_s *msgv; /* Message list */
- uint8_t *mptr; /* Current message buffer */
- int mcnt; /* Current message length */
- uint16_t mflags; /* Current message flags */
-
- struct i2c_msg_s *msg;
-
- /* interrupt */
- struct slave_data *slave_test_data;
- struct master_data *master_test_data;
-
-};
-
struct s5j_i2c_priv_s *g_s5j_i2c_priv[2] = { NULL };
/************************************************************************************
- * Private Function Prototypes
- ************************************************************************************/
-static inline void s5j_i2c_sem_post(struct s5j_i2c_priv_s *priv);
-static inline void s5j_i2c_sem_init(struct s5j_i2c_priv_s *priv);
-static inline void s5j_i2c_sem_destroy(struct s5j_i2c_priv_s *priv);
-static int s5j_i2c_interrupt(struct s5j_i2c_priv_s *priv, uint32_t status);
-static int s5j_i2c0_interrupt(int irq, void *context);
-static int s5j_i2c1_interrupt(int irq, void *context);
-static int s5j_i2c2_interrupt(int irq, void *context);
-static int s5j_i2c3_interrupt(int irq, void *context);
-static int s5j_i2c_initialize(struct s5j_i2c_priv_s *priv, uint32_t frequency);
-static int s5j_i2c_uninitialize(struct s5j_i2c_priv_s *priv);
-
-int s5j_i2c_setownaddress(FAR struct i2c_dev_s *dev, int addr, int nbits);
-uint32_t s5j_i2c_setclock(struct i2c_dev_s *dev, uint32_t frequency);
-
-int s5j_i2c_write(FAR struct i2c_dev_s *dev, FAR const uint8_t *buffer, int buflen);
-int s5j_i2c_read(FAR struct i2c_dev_s *dev, FAR uint8_t *buffer, int buflen);
-int s5j_i2c_transfer(struct i2c_dev_s *dev, struct i2c_msg_s *msgv, int msgc);
-#ifdef CONFIG_I2C_RESET
-int s5j_i2c_reset(FAR struct i2c_dev_s *dev);
-#endif
-
-/************************************************************************************
* Private Data
************************************************************************************/
/* I2C Interface */
-#if 0
-static const struct i2c_ops_s s5j_i2c_ops = {
- .transfer = s5j_i2c_transfer,
-#ifdef CONFIG_I2C_RESET
- .reset = s5j_i2c_reset,
-#endif
-};
-
-static const struct i2c_slaveops_s s5j_i2c_slave_ops = {
- .setownaddress = 0, /* s5j_i2c_setownaddress, */
- .write = 0,
- .read = 0,
- .registercallback = 0, /* hsi2c_master_handler, */
-};
-
-struct i2c_slaveops_s {
- int (*setownaddress)(FAR struct i2c_slave_s *dev, int addr, int nbits);
- int (*write)(FAR struct i2c_slave_s *dev, FAR const uint8_t *buffer, int buflen);
- int (*read)(FAR struct i2c_slave_s *dev, FAR uint8_t *buffer, int buflen);
- int (*registercallback)(FAR struct i2c_slave_s *dev, int (*callback)(FAR void *arg), FAR void *arg);
-};
-#else
static const struct i2c_ops_s s5j_i2c_ops = {
.setfrequency = s5j_i2c_setclock,
.setaddress = s5j_i2c_setownaddress,
.registercallback = NULL,
#endif
};
-#endif
+
static const struct s5j_i2c_config_s s5j_i2c0_config = {
.base = S5J_HSI2C0_BASE,
.scl_pin = s5j_gpio(GPA1, 0),
};
static struct s5j_i2c_priv_s s5j_i2c0_priv = {
- .xfer_speed = 100000,
+ .xfer_speed = S5J_DEFAULT_I2CXFER_CLOCK,
.master = I2C_MASTER,
.mode = I2C_POLLING,
- .slave_addr = 0x22,
+ .slave_addr = S5J_DEFAULT_I2CSLAVE_ADDR,
.addrlen = 7,
- .timeout = 10000,
- .name = "master_test",
+ .timeout = S5J_DEFAULT_I2C_TIMEOUT,
+ .name = "s5j_i2c0",
.initialized = 0,
.retries = 3,
};
};
static struct s5j_i2c_priv_s s5j_i2c1_priv = {
- .xfer_speed = 100000,
+ .xfer_speed = S5J_DEFAULT_I2CXFER_CLOCK,
.master = I2C_MASTER,
.mode = I2C_POLLING,
- .slave_addr = 0x22,
+ .slave_addr = S5J_DEFAULT_I2CSLAVE_ADDR,
.addrlen = 7,
- .timeout = 10000,
- .name = "slave_test",
+ .timeout = S5J_DEFAULT_I2C_TIMEOUT,
+ .name = "s5j_i2c1",
.initialized = 0,
.retries = 3,
};
.sda_pin = s5j_gpio(GPG0, 1),
.isr = s5j_i2c2_interrupt,
.irq = IRQ_HSI2C_2,
- .devno = 1,
+ .devno = 2,
};
static struct s5j_i2c_priv_s s5j_i2c2_priv = {
- .xfer_speed = 100000,
- .master = I2C_SLAVE_MODE,
+ .xfer_speed = S5J_DEFAULT_I2CXFER_CLOCK,
+ .master = I2C_MASTER,
.mode = I2C_POLLING,
- .slave_addr = 0x22,
+ .slave_addr = S5J_DEFAULT_I2CSLAVE_ADDR,
.addrlen = 7,
- .timeout = 10000,
- .name = "slave_test",
+ .timeout = S5J_DEFAULT_I2C_TIMEOUT,
+ .name = "s5j_i2c2",
.initialized = 0,
.retries = 3,
};
.sda_pin = s5j_gpio(GPG0, 3),
.isr = s5j_i2c3_interrupt,
.irq = IRQ_HSI2C_3,
- .devno = 1,
+ .devno = 3,
};
static struct s5j_i2c_priv_s s5j_i2c3_priv = {
- .xfer_speed = 100000,
- .master = I2C_SLAVE_MODE,
+ .xfer_speed = S5J_DEFAULT_I2CXFER_CLOCK,
+ .master = I2C_MASTER,
.mode = I2C_POLLING,
- .slave_addr = 0x22,
+ .slave_addr = S5J_DEFAULT_I2CSLAVE_ADDR,
.addrlen = 7,
- .timeout = 10000,
- .name = "slave_test",
+ .timeout = S5J_DEFAULT_I2C_TIMEOUT,
+ .name = "s5j_i2c3",
.initialized = 0,
.retries = 3,
};
/************************************************************************************
* Private Functions
************************************************************************************/
-static void hsi2c_set_hs_timing(uint32_t base, u32 nClkDiv, u32 tSTART_SU, u32 tSTART_HD, u32 tSTOP_SU, u32 tSDA_SU, u32 tDATA_SU, u32 tDATA_HD, u32 tSCL_L, u32 tSCL_H, u32 tSR_RELEASE)
+static void hsi2c_set_hs_timing(unsigned int base, unsigned int nClkDiv, unsigned int tSTART_SU, unsigned int tSTART_HD, unsigned int tSTOP_SU, unsigned int tSDA_SU, unsigned int tDATA_SU, unsigned int tDATA_HD, unsigned int tSCL_L, unsigned int tSCL_H, unsigned int tSR_RELEASE)
{
tSTART_SU &= 0xFF;
tSTART_HD &= 0xFF;
tDATA_SU &= 0xFF;
tSCL_L &= 0xFF;
tSCL_H &= 0xFF;
- /* HW_REG32(base, I2C_TIMING_HS2) = (tDATA_SU << 24) | (tSCL_L << 8) | (tSCL_H << 0); */
__raw_writel(((tDATA_SU << 24) | (tSCL_L << 8) | (tSCL_H << 0)), base + I2C_TIMING_HS2);
nClkDiv &= 0xFF;
tSR_RELEASE &= 0xFF;
- /* HW_REG32(base, I2C_TIMING_HS3) = (nClkDiv << 16) | (tSR_RELEASE << 0); */
__raw_writel(((nClkDiv << 16) | (tSR_RELEASE << 0)), base + I2C_TIMING_HS3);
tDATA_HD &= 0xFFFF;
- /* HW_REG32(base, I2C_TIMING_SLA) = (tDATA_HD << 0); */
__raw_writel(tDATA_HD, base + I2C_TIMING_SLA);
}
-static void hsi2c_set_fs_timing(uint32_t base, u32 nClkDiv, u32 tSTART_SU, u32 tSTART_HD, u32 tSTOP_SU, u32 tDATA_SU, u32 tDATA_HD, u32 tSCL_L, u32 tSCL_H, u32 tSR_RELEASE)
+static void hsi2c_set_fs_timing(unsigned int base, unsigned int nClkDiv, unsigned int tSTART_SU, unsigned int tSTART_HD, unsigned int tSTOP_SU, unsigned int tDATA_SU, unsigned int tDATA_HD, unsigned int tSCL_L, unsigned int tSCL_H, unsigned int tSR_RELEASE)
{
tSTART_SU &= 0xFF;
tSTART_HD &= 0xFF;
tSTOP_SU &= 0xFF;
- /* HW_REG32(base, I2C_TIMING_FS1) = (tSTART_SU << 24) | (tSTART_HD << 16) | (tSTOP_SU << 8); */
__raw_writel(((tSTART_SU << 24) | (tSTART_HD << 16) | (tSTOP_SU << 8)), base + I2C_TIMING_FS1);
tDATA_SU &= 0xFF;
tSCL_L &= 0xFF;
tSCL_H &= 0xFF;
- /* HW_REG32(base, I2C_TIMING_FS2) = (tDATA_SU << 24) | (tSCL_L << 8) | (tSCL_H << 0); */
__raw_writel(((tDATA_SU << 24) | (tSCL_L << 8) | (tSCL_H << 0)), base + I2C_TIMING_FS2);
nClkDiv &= 0xFF;
tSR_RELEASE &= 0xFF;
- /* HW_REG32(base, I2C_TIMING_FS3) = (nClkDiv << 16) | (tSR_RELEASE << 0); */
__raw_writel(((nClkDiv << 16) | (tSR_RELEASE << 0)), base + I2C_TIMING_FS3);
tDATA_HD &= 0xFFFF;
- /* HW_REG32(base, I2C_TIMING_SLA) = (0 << 0); */
__raw_writel(tDATA_HD, base + I2C_TIMING_SLA);
}
-static void hsi2c_calculate_timing(uint32_t base, u32 nPclk, u32 nOpClk)
+static void hsi2c_calculate_timing(unsigned int base, unsigned int nPclk, unsigned int nOpClk)
{
- u32 nClkDiv;
- u32 tFTL_CYCLE_SCL;
+ unsigned int nClkDiv;
+ unsigned int tFTL_CYCLE_SCL;
s32 i;
s32 uTemp0;
s32 uTemp1;
HW_REG32(base, I2C_CONF) &= ~(0x7 << 13);
HW_REG32(base, I2C_CONF) &= ~(0x7 << 16);
- /* HW_REG32(base, I2C_CONF) |= (0xa << 13); */
- /* HW_REG32(base, I2C_CONF) |= (0xa << 16); */
tFTL_CYCLE_SCL = (HW_REG32(base, I2C_CONF) >> 16) & 0x7;
uTemp0 = (float)(nPclk / nOpClk) - (tFTL_CYCLE_SCL + 3) * 2;
}
}
- u32 tSCL_H;
+ unsigned int tSCL_H;
nClkDiv = i;
if (nOpClk > I2C_SPEED_400KHZ) {
tSCL_H = ((uTemp2 + 10) / 3) - 5;
} else {
tSCL_H = uTemp2 / 2;
}
- u32 tSCL_L = uTemp2 - tSCL_H;
+ unsigned int tSCL_L = uTemp2 - tSCL_H;
- u32 tSTART_SU = tSCL_L;
- u32 tSTART_HD = tSCL_L;
- u32 tSTOP_SU = tSCL_L;
- u32 tSDA_SU = tSCL_L;
- u32 tDATA_SU = tSCL_L;
- u32 tDATA_HD = tSCL_L / 2;
- u32 tSR_RELEASE = uTemp2;
+ unsigned int tSTART_SU = tSCL_L;
+ unsigned int tSTART_HD = tSCL_L;
+ unsigned int tSTOP_SU = tSCL_L;
+ unsigned int tSDA_SU = tSCL_L;
+ unsigned int tDATA_SU = tSCL_L;
+ unsigned int tDATA_HD = tSCL_L / 2;
+ unsigned int tSR_RELEASE = uTemp2;
if (nOpClk > I2C_SPEED_400KHZ) {
hsi2c_set_fs_timing(base, 1, 38, 38, 38, 19, 19, 38, 38, 76); /* 400Khz setting for Extened ID */
}
}
-static void hsi2c_conf(uint32_t base, u32 nOpClk)
+static void hsi2c_conf(unsigned int base, unsigned int nOpClk)
{
- u32 val;
+ unsigned int val;
val = __raw_readl(base + I2C_CONF);
val &= ~(3 << 30);
__raw_writel(val, base + I2C_CONF);
}
-static void hsi2c_enable_int(uint32_t base, u32 bit)
+static void hsi2c_enable_int(unsigned int base, unsigned int bit)
{
- u32 val;
-
+ unsigned int val;
val = __raw_readl(base + INT_EN);
val |= bit;
__raw_writel(val, base + INT_EN);
}
-static void hsi2c_disable_int(uint32_t base, u32 bit)
+static void hsi2c_disable_int(unsigned int base, unsigned int bit)
{
- u32 val;
+ unsigned int val;
val = __raw_readl(base + INT_EN);
val &= ~bit;
__raw_writel(val, base + INT_EN);
}
-static void hsi2c_clear_int(uint32_t base, u32 bit)
+static void hsi2c_clear_int(unsigned int base, unsigned int bit)
{
__raw_writel(bit, base + INT_STAT);
}
-static u32 hsi2c_read_int_status(uint32_t base)
+static unsigned int hsi2c_read_int_status(unsigned int base)
{
return __raw_readl(base + INT_STAT) & __raw_readl(base + INT_EN);
}
-static void hsi2c_set_slave_addr(uint32_t base, u16 addr, u32 is_master)
+static void hsi2c_set_slave_addr(unsigned int base, u16 addr, unsigned int is_master)
{
- u32 val;
+ unsigned int val;
addr &= 0x3FF;
__raw_writel(val, base + I2C_ADDR);
}
-/* -- new stuffs -- */
-
-#define HSI2C_INT_XFER_DONE (HSI2C_INT_XFER_DONE_NOACK_MANUAL | HSI2C_INT_XFER_DONE_MANUAL)
-
static int hsi2c_manual_fast_init(struct s5j_i2c_priv_s *priv)
{
- u32 val;
- uint32_t base = priv->config->base;
+ unsigned int val;
+ unsigned int base = priv->config->base;
hsi2c_conf(base, priv->xfer_speed);
hsi2c_calculate_timing(base, priv->clock, priv->xfer_speed);
hsi2c_enable_int(base, HSI2C_INT_XFER_DONE_MANUAL | HSI2C_INT_XFER_DONE_NOACK_MANUAL);
priv->initialized = 1;
- /* Manual, fast mode */
+
val = __raw_readl(base + I2C_CONF);
val &= ~((1 << 31) | (1 << 29));
__raw_writel(val, base + I2C_CONF);
- /* Interrupt */
hsi2c_enable_int(base, HSI2C_INT_XFER_DONE);
return 0;
}
-/* Manual i2c master operation */
-
static int hsi2c_wait_xfer_done(struct s5j_i2c_priv_s *priv)
{
int val;
int timeout = priv->timeout;
- uint32_t base = priv->config->base;
+ unsigned int base = priv->config->base;
while (timeout-- > 0) {
val = __raw_readl(base + INT_STAT) & HSI2C_INT_XFER_DONE_MANUAL;
int val;
int timeout = priv->timeout;
- uint32_t base = priv->config->base;
+ unsigned int base = priv->config->base;
while (timeout-- > 0) {
val = __raw_readl(base + INT_STAT) & HSI2C_INT_XFER_DONE_NOACK_MANUAL;
// dbg("S ");
- __raw_writel(0x88, priv->config->base + CTL); /* workround ctrl 0bit write 1 */
+ __raw_writel(0x88, priv->config->base + CTL);
__raw_writel(I2C_START, priv->config->base + I2C_MANUAL_CMD);
static void hsi2c_repstart(struct s5j_i2c_priv_s *priv)
{
- dbg("Sr ");
+// dbg("Sr ");
__raw_writel(I2C_RESTART, priv->config->base + I2C_MANUAL_CMD);
}
static int hsi2c_outb(struct s5j_i2c_priv_s *priv, u8 data)
{
- u32 val;
+ unsigned int val;
int ret;
- val = ((u32) data) << 24 | I2C_SEND_DATA;
+ val = ((unsigned int)data) << 24 | I2C_SEND_DATA;
__raw_writel(val, priv->config->base + I2C_MANUAL_CMD);
ret = hsi2c_wait_xfer_done(priv);
static int hsi2c_inb(struct s5j_i2c_priv_s *priv, bool is_ack)
{
- u32 val = I2C_READ_DATA;
+ unsigned int val = I2C_READ_DATA;
u8 data;
int ret;
- uint32_t base = priv->config->base;
+ unsigned int base = priv->config->base;
/* Looks awkward, but if I2C_RX_ACK is set, ACK is NOT generated */
-// udelay(1000);
if (!is_ack) {
val |= I2C_RX_ACK;
}
ret = hsi2c_wait_xfer_done(priv);
if (ret < 0) {
- return ret; /* timeout */
+ return ret; /* timeout */
}
data = (__raw_readl(base + I2C_MANUAL_CMD) >> 16) & 0xff;
-
// dbg("[0x%02X] %s ", data, is_ack ? "A" : "NA");
return data;
static int do_address(struct s5j_i2c_priv_s *priv, struct i2c_msg_s *msg)
{
- /* struct hsi2c_adapter *i2c = container_of(i2c_adap, struct hsi2c_adapter, adapter); */
unsigned short flags = msg->flags;
unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK;
u8 addr;
dbg("%s: died at extended address\n", priv->name);
return -ENXIO;
}
+
/* the remaining 8 bit address */
ret = hsi2c_outb(priv, msg->addr & 0xff);
if ((ret != 1) && !nak_ok) {
dbg("%s: died at 2nd address\n", priv->name);
return -ENXIO;
}
+
if (flags & I2C_M_READ) {
hsi2c_repstart(priv);
hsi2c_wait_xfer_done(priv);
if (flags & I2C_M_READ) {
addr |= 0x1;
}
- /* if (flags & I2C_M_REV_DIR_ADDR) */
- /* addr ^= 0x1; */
ret = try_address(priv, addr, retries);
if ((ret != 1) && !nak_ok) {
return 0;
}
-void hsi2c_run_auto_mode(uint32_t base, int on)
+static void hsi2c_run_auto_mode(unsigned int base, int on)
{
- u32 val = __raw_readl(base + I2C_AUTO_CONF);
+ unsigned int val = __raw_readl(base + I2C_AUTO_CONF);
if (on) {
val |= (1 << 31);
__raw_writel(val, base + I2C_AUTO_CONF);
}
-void hsi2c_tx_fifo_reset(uint32_t base, int resetb)
+static void hsi2c_tx_fifo_reset(unsigned int base, int resetb)
{
- u32 val = __raw_readl(base + FIFO_CTL);
+ unsigned int val = __raw_readl(base + FIFO_CTL);
if (resetb) {
val |= (1 << 3);
__raw_writel(val, base + FIFO_CTL);
}
-static void hsi2c_set_auto_config(uint32_t base, u32 stop, u32 tx, u32 len)
+static void hsi2c_set_auto_config(unsigned int base, unsigned int stop, unsigned int tx, unsigned int len)
{
-
- u32 val = __raw_readl(base + I2C_AUTO_CONF);
+ unsigned int val = __raw_readl(base + I2C_AUTO_CONF);
if (stop) {
val |= (1 << 17);
__raw_writel(val, base + I2C_AUTO_CONF);
}
-static void hsi2c_set_trans_mode(uint32_t base, u32 master, u32 tx)
+static void hsi2c_set_trans_mode(unsigned int base, unsigned int master, unsigned int tx)
{
- u32 val = __raw_readl(base + CTL);
+ unsigned int val = __raw_readl(base + CTL);
- val |= (1 << 0); //workround ctrl 0bit write 1 */
+ val |= (1 << 0); /* ctrl 0 bit write 1 */
if (master) {
val |= (1 << 3);
}
-static void hsi2c_set_hwacg_mode(uint32_t base, u32 slave)
+static void hsi2c_set_hwacg_mode(unsigned int base, unsigned int slave)
{
- u32 val = __raw_readl(base + CTL);
+ unsigned int val = __raw_readl(base + CTL);
val &= ~(0x3 << 24);
__raw_writel(val, base + CTL);
}
-int hsi2c_master_handler(void *args)
+static int hsi2c_master_handler(void *args)
{
struct s5j_i2c_priv_s *priv = args;
- u32 int_status;
+ unsigned int int_status;
int off = priv->master_test_data->cur_msg, buf_off = priv->master_test_data->buf_count;
int trans_count = priv->master_test_data->num;
struct i2c_msg_s *msg = &priv->master_test_data->msg[off];
- uint32_t base = priv->config->base;
+ unsigned int base = priv->config->base;
int_status = hsi2c_read_int_status(base);
if (int_status & HSI2C_INT_TX_ALMOST_EMPTY) {
return 0;
}
-int hsi2c_slave_handler(void *args)
+static int hsi2c_slave_handler(void *args)
{
struct s5j_i2c_priv_s *priv = args;
- u32 int_status;
- u32 val;
- uint32_t base = priv->config->base;
+ unsigned int int_status;
+ unsigned int val;
+ unsigned int base = priv->config->base;
int_status = hsi2c_read_int_status(base);
if (int_status & HSI2C_INT_SLAVE_ADDR_MATCH) {
val = __raw_readl(base + I2C_TRANS_STATUS);
}
hsi2c_clear_int(base, HSI2C_INT_SLAVE_ADDR_MATCH);
- }
-// int_status = hsi2c_read_int_status(base); /*added to slave tx mode*/
- else if (int_status & HSI2C_INT_RX_ALMOST_FULL) {
+ } else if (int_status & HSI2C_INT_RX_ALMOST_FULL) {
if (priv->slave_test_data->status == SLAVE_GET_REG) {
priv->slave_test_data->current_reg = __raw_readl(base + RXDATA);
priv->slave_test_data->status = SLAVE_GET_DATA;
return 0;
}
-static int hsi2c_xfer_interrupt(struct s5j_i2c_priv_s *priv, struct i2c_msg_s msg[], int num)
-{
- uint32_t base = priv->config->base;
- /* save parameters in master_test_data for interrupt mode test */
- priv->master_test_data->msg = msg;
- priv->master_test_data->num = num;
- priv->master_test_data->cur_msg = 0;
- priv->master_test_data->buf_count = 0;
-
- if (num == 1) {
- hsi2c_set_auto_config(base, 1, 1, msg->length);
- } else {
- hsi2c_set_auto_config(base, 0, 1, msg->length);
- }
-
- hsi2c_set_trans_mode(base, 1, 1);
-
- hsi2c_disable_int(base, HSI2C_INT_ALL);
- hsi2c_enable_int(base, HSI2C_INT_TRANSFER_DONE_AUTO | HSI2C_INT_TRANS_ABORT_AUTO);
- hsi2c_enable_int(base, HSI2C_INT_NO_DEV_ACK_AUTO | HSI2C_INT_NO_DEV_AUTO);
- hsi2c_enable_int(base, HSI2C_INT_TX_ALMOST_EMPTY | HSI2C_INT_RX_ALMOST_FULL);
- if ((priv->master == I2C_SLAVE_MODE) || (priv->mode == I2C_INTERRUPT)) {
- irq_attach(priv->config->irq, priv->config->isr);
- }
- hsi2c_run_auto_mode(base, 1);
-
- /* wait_for_complete(&priv->master_test_data->done); */
-
- return num;
-}
-
-static void hsi2c_set_auto_mode(uint32_t base)
+static void hsi2c_set_auto_mode(unsigned int base)
{
- u32 val;
+ unsigned int val;
val = __raw_readl(base + I2C_CONF);
val |= (1 << 31);
__raw_writel(val, base + I2C_CONF);
}
-static void hsi2c_set_fifo_level(uint32_t base)
+static void hsi2c_set_fifo_level(unsigned int base)
{
__raw_writel(0x10013, base + FIFO_CTL);
}
-static void hsi2c_master_setup(struct s5j_i2c_priv_s *priv, u32 mode, u32 speed, u32 slave_addr)
+static void hsi2c_master_setup(struct s5j_i2c_priv_s *priv, unsigned int mode, unsigned int speed, unsigned int slave_addr)
{
if (priv->mode == I2C_POLLING) {
priv->xfer_speed = speed;
hsi2c_calculate_timing(priv->config->base, priv->clock, speed);
- } else if (priv->mode == I2C_INTERRUPT) {
+ }
+#ifdef CONFIG_S5J_I2C_INTERRUPT_MODE
+ else if (priv->mode == I2C_INTERRUPT) {
priv->master_test_data = (struct master_data *)malloc(sizeof(struct master_data));
/* complete_init(&priv->master_test_data->done); */
hsi2c_set_trans_mode(priv->config->base, 1, 1); /* set master mode */
hsi2c_set_auto_mode(priv->config->base);
hsi2c_set_fifo_level(priv->config->base);
}
+#endif
}
-static void hsi2c_slave_setup(struct s5j_i2c_priv_s *priv, u32 mode, u32 speed, u32 slave_addr)
+static void hsi2c_slave_setup(struct s5j_i2c_priv_s *priv, unsigned int mode, unsigned int speed, unsigned int slave_addr)
{
priv->slave_test_data = (struct slave_data *)malloc(sizeof(struct slave_data));
hsi2c_set_auto_config(priv->config->base, 0, 0, 0);
hsi2c_set_trans_mode(priv->config->base, 0, 0);
+#ifdef CONFIG_S5J_I2C_INTERRUPT_MODE
if ((priv->master == I2C_SLAVE_MODE) || (priv->mode == I2C_INTERRUPT)) {
irq_attach(priv->config->irq, priv->config->isr);
}
+#endif
}
static void hsi2c_master_cleanup(struct s5j_i2c_priv_s *priv)
{
+#ifdef CONFIG_S5J_I2C_INTERRUPT_MODE
if (priv->mode == I2C_INTERRUPT) {
- /* FreeHwMemP(priv->master_test_data); */
free(priv->master_test_data);
priv->master_test_data = NULL;
- assert(1);
- //irq_detach((xcpt_t)priv->config->isr);
-
+ irq_detach(priv->config->irq);
}
-
+#endif
}
static void hsi2c_slave_cleanup(struct s5j_i2c_priv_s *priv)
/* FreeHwMemP(priv->slave_test_data); */
free(priv->slave_test_data);
priv->slave_test_data = NULL;
+#ifdef CONFIG_S5J_I2C_INTERRUPT_MODE
if ((priv->master == I2C_SLAVE_MODE) || (priv->mode = I2C_INTERRUPT)) {
irq_detach(priv->config->irq);
}
+#endif
}
-static int hsi2c_setup(struct s5j_i2c_priv_s *priv, u32 master, u32 mode, u32 speed, u32 slave_addr)
+static int hsi2c_setup(struct s5j_i2c_priv_s *priv, unsigned int master, unsigned int mode, unsigned int speed, unsigned int slave_addr)
{
- /* struct hsi2c_adapter *i2c = container_of(adapter, struct hsi2c_adapter, adapter); */
-
priv->master = master;
priv->mode = mode;
priv->xfer_speed = speed;
static int hsi2c_cleanup(struct s5j_i2c_priv_s *priv)
{
- /* struct hsi2c_adapter *i2c = container_of(adapter, struct hsi2c_adapter, adapter); */
-
if (priv->master == I2C_MASTER) {
hsi2c_master_cleanup(priv);
} else if (priv->master == I2C_SLAVE_MODE) {
__raw_writel(0x80000000, priv->config->base + CTL);
udelay(10);
+
__raw_writel(0x0, priv->config->base + CTL);
udelay(100);
- /* hsi2c_manual_fast_init(i2c); */
-
return 0;
}
-/************************************************************************************
- * Name: s5j_i2c_sem_wait
- *
- * Description:
- * Take the exclusive access, waiting as necessary
- *
- ************************************************************************************/
-
static inline void s5j_i2c_sem_wait(struct s5j_i2c_priv_s *priv)
{
while (sem_wait(&priv->exclsem) != 0) {
}
}
-/************************************************************************************
- * Name: s5j_i2c_sem_post
- *
- * Description:
- * Release the mutual exclusion semaphore
- *
- ************************************************************************************/
-
static inline void s5j_i2c_sem_post(struct s5j_i2c_priv_s *priv)
{
sem_post(&priv->exclsem);
}
-/************************************************************************************
- * Name: s5j_i2c_sem_init
- *
- * Description:
- * Initialize semaphores
- *
- ************************************************************************************/
-
static inline void s5j_i2c_sem_init(struct s5j_i2c_priv_s *priv)
{
sem_init(&priv->exclsem, 0, 1);
#endif
}
-/************************************************************************************
- * Name: s5j_i2c_sem_destroy
- *
- * Description:
- * Destroy semaphores.
- *
- ************************************************************************************/
-
static inline void s5j_i2c_sem_destroy(struct s5j_i2c_priv_s *priv)
{
sem_destroy(&priv->exclsem);
#endif
}
-/************************************************************************************
- * Name: s5j_i2c_interrupt
- *
- * Description:
- * Common Interrupt Service Routine
- *
- ************************************************************************************/
-
-/************************************************************************************
- * Name: s5j_i2c0_interrupt
- *
- * Description:
- * I2C0 interrupt service routine
- *
- ************************************************************************************/
-
static int s5j_i2c0_interrupt(int irq, void *context)
{
-#if 0
struct s5j_i2c_priv_s *priv;
- uint32_t status;
/* Read the masked interrupt status */
-
priv = &s5j_i2c0_priv;
- status = s5j_i2c_getreg(priv, S5J_I2CM_MIS_OFFSET);
/* Let the common interrupt handler do the rest of the work */
-
- return s5j_i2c_interrupt(priv, status);
-#endif
- return 0;
+ return hsi2c_master_handler(priv);
}
-/************************************************************************************
- * Name: s5j_i2c1_interrupt
- *
- * Description:
- * I2C1 interrupt service routine
- *
- ************************************************************************************/
-
static int s5j_i2c1_interrupt(int irq, void *context)
{
struct s5j_i2c_priv_s *priv;
/* Read the masked interrupt status */
priv = &s5j_i2c1_priv;
-
/* Let the common interrupt handler do the rest of the work */
- return hsi2c_slave_handler(priv);
+ return hsi2c_master_handler(priv);
}
-/************************************************************************************
- * Name: s5j_i2c2_interrupt
- *
- * Description:
- * I2C2 interrupt service routine
- *
- ************************************************************************************/
-
static int s5j_i2c2_interrupt(int irq, void *context)
{
struct s5j_i2c_priv_s *priv;
/* Let the common interrupt handler do the rest of the work */
- return hsi2c_slave_handler(priv);
+ return hsi2c_master_handler(priv);
}
-/************************************************************************************
- * Name: s5j_i2c2_interrupt
- *
- * Description:
- * I2C2 interrupt service routine
- *
- ************************************************************************************/
-
static int s5j_i2c3_interrupt(int irq, void *context)
{
struct s5j_i2c_priv_s *priv;
/* Let the common interrupt handler do the rest of the work */
- return hsi2c_slave_handler(priv);
+ return hsi2c_master_handler(priv);
}
-/************************************************************************************
- * Name: s5j_i2c_initialize
- *
- * Description:
- * Setup the I2C hardware, ready for operation with defaults
- *
- ************************************************************************************/
-
-static int s5j_i2c_initialize(struct s5j_i2c_priv_s *priv, uint32_t frequency)
+static int s5j_i2c_initialize(struct s5j_i2c_priv_s *priv, unsigned int frequency)
{
const struct s5j_i2c_config_s *config = priv->config;
int ret;
- // i2cvdbg("I2C%d: refs=%d\n", config->devno, priv->refs);
-
- /* Configure pins */
-
- // i2cvdbg("I2C%d: SCL=%08x SDA=%08x\n",
- // config->devno, config->scl_pin, config->sda_pin);
-
ret = gpio_cfg_pin(config->scl_pin, GPIO_FUNC(2));
- gpio_set_pull(config->scl_pin, GPIO_PULL_UP);
+ gpio_set_pull(config->scl_pin, GPIO_PULL_NONE);
if (ret < 0) {
- i2cvdbg("I2C%d: s5j_configgpio(%08x) failed: %d\n", config->scl_pin, ret);
+ dbg("I2C%d: s5j_configgpio(%08x) failed: %d\n", config->scl_pin, ret);
return ret;
}
ret = gpio_cfg_pin(config->sda_pin, GPIO_FUNC(2));
- gpio_set_pull(config->sda_pin, GPIO_PULL_UP);
+ gpio_set_pull(config->sda_pin, GPIO_PULL_NONE);
if (ret < 0) {
- i2cvdbg("I2C%d: s5j_configgpio(%08x) failed: %d\n", config->sda_pin, ret);
-
+ dbg("I2C%d: s5j_configgpio(%08x) failed: %d\n", config->sda_pin, ret);
return ret;
}
/* Configure the the initial I2C clock frequency. */
priv->xfer_speed = frequency;
hsi2c_setup(priv, priv->master, priv->mode, priv->xfer_speed, priv->slave_addr);
- /* hsi2c_manual_fast_init(priv); */
- /* s5j_i2c_setclock(priv, frequency); */
/* Attach interrupt handlers and enable interrupts at the NVIC (still
* disabled at the source).
*/
+#ifdef CONFIG_S5J_I2C_INTERRUPT_MODE
if ((priv->master == I2C_SLAVE_MODE) || (priv->mode == I2C_INTERRUPT)) {
irq_attach(config->irq, config->isr);
up_enable_irq(config->irq);
}
+#endif
return OK;
}
-/************************************************************************************
- * Name: s5j_i2c_uninitialize
- *
- * Description:
- * Shutdown the I2C hardware
- *
- ************************************************************************************/
-
static int s5j_i2c_uninitialize(struct s5j_i2c_priv_s *priv)
{
- i2cvdbg("I2C%d: refs=%d\n", priv->config->devno, priv->refs);
+ dbg("I2C%d: refs=%d\n", priv->config->devno, priv->refs);
/* Disable I2C */
gpio_cfg_pin(priv->config->sda_pin, GPIO_FUNC(0));
/* Disable and detach interrupts */
+#ifdef CONFIG_S5J_I2C_INTERRUPT_MODE
if ((priv->master == I2C_SLAVE_MODE) || (priv->mode == I2C_INTERRUPT)) {
up_disable_irq(priv->config->irq);
irq_detach(priv->config->irq);
}
+#endif
return OK;
}
/************************************************************************************
* Public Functions
************************************************************************************/
-
/**
*
* @brief i2c clock setting
* @param struct i2c_dev_s *dev : pointer to i2c_dev_s
- * @param uint32_t frequency : ex ) 100000 == 100khz
+ * @param unsigned int frequency : ex ) 100000 == 100khz
* @return void
* @note
*/
-uint32_t s5j_i2c_setclock(FAR struct i2c_dev_s *dev, uint32_t frequency)
+unsigned int s5j_i2c_setclock(FAR struct i2c_dev_s *dev, unsigned int frequency)
{
struct s5j_i2c_priv_s *priv = (struct s5j_i2c_priv_s *)dev;
- i2cvdbg("I2C%d: frequency: %u\n", priv->config->devno, frequency);
+ dbg("I2C%d: frequency: %u\n", priv->config->devno, frequency);
/* Has the I2C bus frequency changed? */
int nak_ok;
int start = 1;
int stop = 1;
- uint32_t base = priv->config->base;
+ unsigned int base = priv->config->base;
- i2cvdbg("I2C%d: msgc=%d\n", priv->config->devno, msgc);
+ dbg("I2C%d: msgc=%d\n", priv->config->devno, msgc);
- /* s5j_i2c_sem_wait(priv); Ensure that address or flags don't change meanwhile */
+ s5j_i2c_sem_wait(priv); /* Ensure that address or flags don't change meanwhile */
- if (((msgv->flags & I2C_M_READ) != 1) && (msgv->length == 1) && (msgc == 1)) { //register address write for read --> no stop
+ /*
+ register address write for read, write with count 1,
+ i2c_read is expected from writing with count '1',
+ no stop for next transfer
+ */
+ if (((msgv->flags & I2C_M_READ) != 1) && (msgv->length == 1) && (msgc == 1)) {
stop = 0;
}
- if ((msgv->flags & I2C_M_READ) && (msgc == 1)) { //read
+
+ if ((msgv->flags & I2C_M_READ) && (msgc == 1)) {
start = 0;
}
-// stop=1;
-// start=1;
priv->mcnt = 0;
priv->mptr = NULL;
priv->msgv = msgv;
priv->msgc = msgc;
-// s5j_i2c_setclock(priv, msgv->frequency);
-
/* todo: initialization */
/* dbg("%s: ", priv->adapter.name); */
if (start) {
if (pmsg->flags & I2C_M_READ) {
/* read bytes into buffer */
ret = readbytes(priv, pmsg);
-#if 0
- if (ret >= 1) {
- dbg("%s: read %d byte%s\n", i2c->adapter.name, ret, ret == 1 ? "" : "s");
- }
-#endif
if (ret < pmsg->length) {
if (ret >= 0) {
return -EIO;
} else {
/* write bytes from buffer */
ret = sendbytes(priv, pmsg);
-#if 0
- if (ret >= 1) {
- dbg("%s: wrote %d byte%s\n", i2c->adapter.name, ret, ret == 1 ? "" : "s");
- }
-#endif
if (ret < pmsg->length) {
if (ret >= 0) {
ret = -EIO;
if (stop) {
hsi2c_stop(priv);
}
-// lldbg("\nhsi2c_stop");
+
+ s5j_i2c_sem_post(priv); /* Ensure that address or flags don't change meanwhile */
return ret;
}
/* Setup for the transfer */
msg.addr = priv->slave_addr, msg.flags = (flags | I2C_M_READ);
- msg.buffer = (FAR uint8_t *)buffer;
+ msg.buffer = (FAR uint8_t *) buffer;
msg.length = buflen;
/* Then perform the transfer
msg.addr = priv->slave_addr;
msg.flags = (priv->addrlen == 10) ? I2C_M_TEN : 0;
- msg.buffer = (FAR uint8_t *)buffer; /* Override const */
+ msg.buffer = (FAR uint8_t *) buffer; /* Override const */
msg.length = buflen;
/* Then perform the transfer
struct s5j_i2c_priv_s *priv = (struct s5j_i2c_priv_s *)dev;
unsigned int clock_count;
unsigned int stretch_count;
- uint32_t scl_gpio;
- uint32_t sda_gpio;
+ unsigned int scl_gpio;
+ unsigned int sda_gpio;
int ret = ERROR;
DEBUGASSERT(priv && priv->config);
- i2cvdbg("I2C%d:\n", priv->config->devno);
+ dbg("I2C%d:\n", priv->config->devno);
/* Our caller must own a ref */
out:
/* Release the port for re-use by other clients */
-
s5j_i2c_sem_post(priv);
return ret;
}
struct s5j_i2c_priv_s *priv = NULL;
const struct s5j_i2c_config_s *config;
int flags;
- /* Get I2C private structure */
+ /* Get I2C private structure */
if (g_s5j_i2c_priv[port] != NULL) {
return (FAR struct i2c_dev_s *)g_s5j_i2c_priv[port];
}
priv->clock = cal_clk_getrate(gate_hsi2c1);
break;
+ case 2:
+ priv = &s5j_i2c2_priv;
+ config = &s5j_i2c2_config;
+ cal_clk_enable(gate_hsi2c2);
+ priv->clock = cal_clk_getrate(gate_hsi2c2);
+ break;
+
+ case 3:
+ priv = &s5j_i2c3_priv;
+ config = &s5j_i2c3_config;
+ cal_clk_enable(gate_hsi2c3);
+ priv->clock = cal_clk_getrate(gate_hsi2c3);
+ break;
+
default:
- i2cdbg("I2C%d: ERROR: Not supported\n", port);
+ dbg("I2C%d: ERROR: Not supported\n", port);
return NULL;
}
* power-up hardware and configure GPIOs.
*/
- flags = irqsave();
+ flags = irqsave();;
priv->refs++;
if (priv->refs == 1) {
}
g_s5j_i2c_priv[port] = priv;
-
irqrestore(flags);
+
return (FAR struct i2c_dev_s *)priv;
}
DEBUGASSERT(priv && priv->config && priv->refs > 0);
- i2cvdbg("I2C%d: Uninitialize\n", priv->config->devno);
+ dbg("I2C%d: Uninitialize\n", priv->config->devno);
/* Decrement reference count and check for underflow */
#define I2C_MASTER 0
#define I2C_SLAVE_MODE 1
#define I2C_POLLING 0
-#define I2C_INTERRUPT 1
+/* #define I2C_INTERRUPT 1 */
enum slave_status {
SLAVE_IDLE,
/* struct completion done; */
};
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
+/* I2C Device hardware configuration */
+struct s5j_i2c_config_s {
+ uintptr_t base; /* I2C base address */
+ unsigned int scl_pin; /* GPIO configuration for SCL as SCL */
+ unsigned int sda_pin; /* GPIO configuration for SDA as SDA */
+ int (*isr)(int, void *); /* Interrupt handler */
+ unsigned int irq; /* IRQ number */
+ uint8_t devno; /* I2Cn where n = devno */
+};
-/****************************************************************************
- * Name: s5j_i2cbus_initialize
- *
- * Description:
- * Initialize the selected I2C port. And return a unique instance of struct
- * struct i2c_master_s. This function may be called to obtain multiple
- * instances of the interface, each of which may be set up with a
- * different frequency and slave address.
- *
- * Input Parameter:
- * Port number (for hardware that has multiple I2C interfaces)
- *
- * Returned Value:
- * Valid I2C device structure reference on succcess; a NULL on failure
- *
- ****************************************************************************/
+/* I2C Device Private Data */
+struct s5j_i2c_priv_s {
+ const struct i2c_ops_s *ops; /* Standard I2C operations */
+ const struct s5j_i2c_config_s *config; /* Port configuration */
+ sem_t exclsem; /* Mutual exclusion semaphore */
+#ifndef CONFIG_I2C_POLLED
+ sem_t waitsem; /* Interrupt wait semaphore */
+#endif
+ uint8_t refs; /* Reference count */
+ volatile uint8_t intstate; /* Interrupt handshake (see enum s5j_intstate_e) */
+
+ int state;
+ int clock;
+ int xfer_speed;
+ unsigned int master;
+ unsigned int mode;
+ unsigned int slave_addr;
+ unsigned int addrlen;
+ unsigned int timeout;
+ char name[16];
+
+ unsigned int initialized;
+ unsigned int retries;
+ /* master data */
+ uint8_t msgc; /* Message count */
+ struct i2c_msg_s *msgv; /* Message list */
+ uint8_t *mptr; /* Current message buffer */
+ int mcnt; /* Current message length */
+ uint16_t mflags; /* Current message flags */
+
+ struct i2c_msg_s *msg;
+
+ /* interrupt */
+ struct slave_data *slave_test_data;
+ struct master_data *master_test_data;
+
+};
+
+/************************************************************************************
+ * Private Function Prototypes
+ ************************************************************************************/
+static void hsi2c_set_hs_timing(unsigned int base, unsigned int nClkDiv, unsigned int tSTART_SU, unsigned int tSTART_HD, unsigned int tSTOP_SU, unsigned int tSDA_SU, unsigned int tDATA_SU, unsigned int tDATA_HD, unsigned int tSCL_L, unsigned int tSCL_H, unsigned int tSR_RELEASE);
+static void hsi2c_set_fs_timing(unsigned int base, unsigned int nClkDiv, unsigned int tSTART_SU, unsigned int tSTART_HD, unsigned int tSTOP_SU, unsigned int tDATA_SU, unsigned int tDATA_HD, unsigned int tSCL_L, unsigned int tSCL_H, unsigned int tSR_RELEASE);
+
+static void hsi2c_calculate_timing(unsigned int base, unsigned int nPclk, unsigned int nOpClk);
+static void hsi2c_conf(unsigned int base, unsigned int nOpClk);
+static void hsi2c_enable_int(unsigned int base, unsigned int bit);
+static void hsi2c_disable_int(unsigned int base, unsigned int bit);
+static void hsi2c_clear_int(unsigned int base, unsigned int bit);
+static unsigned int hsi2c_read_int_status(unsigned int base);
+static void hsi2c_set_slave_addr(unsigned int base, u16 addr, unsigned int is_master);
+static int hsi2c_manual_fast_init(struct s5j_i2c_priv_s *priv);
+static int hsi2c_wait_xfer_done(struct s5j_i2c_priv_s *priv);
+static int hsi2c_wait_xfer_noack(struct s5j_i2c_priv_s *priv);
+static void hsi2c_start(struct s5j_i2c_priv_s *priv);
+static void hsi2c_stop(struct s5j_i2c_priv_s *priv);
+static void hsi2c_repstart(struct s5j_i2c_priv_s *priv);
+static int hsi2c_outb(struct s5j_i2c_priv_s *priv, u8 data);
+static int hsi2c_inb(struct s5j_i2c_priv_s *priv, bool is_ack);
+static int sendbytes(struct s5j_i2c_priv_s *priv, struct i2c_msg_s *msg);
+static int readbytes(struct s5j_i2c_priv_s *priv, struct i2c_msg_s *msg);
+static int try_address(struct s5j_i2c_priv_s *priv, u8 addr, int retries);
+static int do_address(struct s5j_i2c_priv_s *priv, struct i2c_msg_s *msg);
+static void hsi2c_run_auto_mode(unsigned int base, int on);
+static void hsi2c_tx_fifo_reset(unsigned int base, int resetb);
+static void hsi2c_set_auto_config(unsigned int base, unsigned int stop, unsigned int tx, unsigned int len);
+static void hsi2c_set_trans_mode(unsigned int base, unsigned int master, unsigned int tx);
+static void hsi2c_set_hwacg_mode(unsigned int base, unsigned int slave);
+static int hsi2c_master_handler(void *args);
+static int hsi2c_slave_handler(void *args);
+static void hsi2c_set_auto_mode(unsigned int base);
+static void hsi2c_set_fifo_level(unsigned int base);
+static void hsi2c_master_setup(struct s5j_i2c_priv_s *priv, unsigned int mode, unsigned int speed, unsigned int slave_addr);
+static void hsi2c_slave_setup(struct s5j_i2c_priv_s *priv, unsigned int mode, unsigned int speed, unsigned int slave_addr);
+static void hsi2c_master_cleanup(struct s5j_i2c_priv_s *priv);
+static void hsi2c_slave_cleanup(struct s5j_i2c_priv_s *priv);
+static int hsi2c_setup(struct s5j_i2c_priv_s *priv, unsigned int master, unsigned int mode, unsigned int speed, unsigned int slave_addr);
+static int hsi2c_cleanup(struct s5j_i2c_priv_s *priv);
+static inline void s5j_i2c_sem_wait(struct s5j_i2c_priv_s *priv);
+static inline void s5j_i2c_sem_post(struct s5j_i2c_priv_s *priv);
+static inline void s5j_i2c_sem_init(struct s5j_i2c_priv_s *priv);
+static inline void s5j_i2c_sem_destroy(struct s5j_i2c_priv_s *priv);
+static int s5j_i2c_interrupt(struct s5j_i2c_priv_s *priv, unsigned int status);
+static int s5j_i2c0_interrupt(int irq, void *context);
+static int s5j_i2c1_interrupt(int irq, void *context);
+static int s5j_i2c2_interrupt(int irq, void *context);
+static int s5j_i2c3_interrupt(int irq, void *context);
+static int s5j_i2c_initialize(struct s5j_i2c_priv_s *priv, unsigned int frequency);
+static int s5j_i2c_uninitialize(struct s5j_i2c_priv_s *priv);
-struct i2c_dev_s *up_i2cinitialize(int port);
/****************************************************************************
- * Name: s5j_i2cbus_uninitialize
- *
- * Description:
- * De-initialize the selected I2C port, and power down the device.
- *
- * Input Parameter:
- * Device structure as returned by the tiva_i2cbus_initialize()
- *
- * Returned Value:
- * OK on success, ERROR when internal reference count mismatch or dev
- * points to invalid hardware device.
- *
+ * Public Function Prototypes
****************************************************************************/
-
+unsigned int s5j_i2c_setclock(struct i2c_dev_s *dev, unsigned int frequency);
+int s5j_i2c_setownaddress(FAR struct i2c_dev_s *dev, int addr, int nbits);
+int s5j_i2c_transfer(struct i2c_dev_s *dev, struct i2c_msg_s *msgv, int msgc);
+int s5j_i2c_read(FAR struct i2c_dev_s *dev, FAR uint8_t *buffer, int buflen);
+int s5j_i2c_write(FAR struct i2c_dev_s *dev, FAR const uint8_t *buffer, int buflen);
+#ifdef CONFIG_I2C_RESET
+int s5j_i2c_reset(FAR struct i2c_dev_s *dev);
+#endif
+struct i2c_dev_s *up_i2cinitialize(int port);
int s5j_i2cbus_uninitialize(FAR struct i2c_dev_s *dev);
-
void s5j_i2c_register(int bus);
-
#endif /* __ARCH_ARM_SRC_S5J_I2C_H */