*/
#include <common.h>
+#include <asm/io.h>
#include <i2c.h>
#include <asm/errno.h>
-/* Data Memory Barrier */
-#define dmb() __asm__ __volatile__ ("dmb" : : : "memory")
-#define SYNCHRONIZE_IO dmb()
-static inline void Xout_le32(u32 *addr, u32 value)
-{
- *(volatile u32 *)addr = value;
- SYNCHRONIZE_IO;
-}
-
-static inline u32 Xin_le32(u32 *addr)
-{
- volatile u32 temp = *(volatile u32 *)addr;
- SYNCHRONIZE_IO;
- return temp;
-}
-
-static inline void Xclrbits_le32(u32 *addr, u32 clear)
-{
- Xout_le32((addr), Xin_le32(addr) & ~(clear));
-}
-
-static inline void Xsetbits_le32(u32 *addr, u32 set)
-{
- Xout_le32((addr), Xin_le32(addr) | (set));
-}
-
struct zynq_i2c_registers {
u32 control;
u32 status;
void i2c_init(int requested_speed, int slaveadd)
{
/* 111MHz / ( (3 * 17) * 22 ) = ~100KHz */
- Xout_le32(&zynq_i2c->control, (16 << ZYNQ_I2C_CONTROL_DIV_B_SHIFT)
- | (2 << ZYNQ_I2C_CONTROL_DIV_A_SHIFT));
+ writel((16 << ZYNQ_I2C_CONTROL_DIV_B_SHIFT) |
+ (2 << ZYNQ_I2C_CONTROL_DIV_A_SHIFT), &zynq_i2c->control);
/* Enable master mode, ack, and 7-bit addressing */
- Xsetbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_MS |
+ setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_MS |
ZYNQ_I2C_CONTROL_ACKEN | ZYNQ_I2C_CONTROL_NEA);
}
{
int int_status;
int status;
- int_status = Xin_le32(&zynq_i2c->interrupt_status);
- status = Xin_le32(&zynq_i2c->status);
+ int_status = readl(&zynq_i2c->interrupt_status);
+ status = readl(&zynq_i2c->status);
if (int_status || status) {
debug("Status: ");
if (int_status & ZYNQ_I2C_INTERRUPT_COMP) debug("COMP ");
if (status & ZYNQ_I2C_STATUS_TXDV) debug("TXDV ");
if (status & ZYNQ_I2C_STATUS_RXOVF) debug("RXOVF ");
if (status & ZYNQ_I2C_STATUS_BA) debug("BA ");
- debug("TS%d ", Xin_le32(&zynq_i2c->transfer_size));
+ debug("TS%d ", readl(&zynq_i2c->transfer_size));
debug("\n");
}
}
int timeout, int_status;
for (timeout = 0; timeout < 100; timeout++) {
udelay(100);
- int_status = Xin_le32(&zynq_i2c->interrupt_status);
+ int_status = readl(&zynq_i2c->interrupt_status);
if (int_status & mask)
break;
}
zynq_i2c_debug_status();
#endif
/* Clear interrupt status flags */
- Xout_le32(&zynq_i2c->interrupt_status, int_status & mask);
+ writel(int_status & mask, &zynq_i2c->interrupt_status);
return int_status & mask;
}
int i2c_probe(u8 dev)
{
/* Attempt to read a byte */
- Xsetbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO |
+ setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO |
ZYNQ_I2C_CONTROL_RW);
- Xclrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
- Xout_le32(&zynq_i2c->interrupt_status, 0xFF);
- Xout_le32(&zynq_i2c->address, dev);
- Xout_le32(&zynq_i2c->transfer_size, 1);
+ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
+ writel(0xFF, &zynq_i2c->interrupt_status);
+ writel(dev, &zynq_i2c->address);
+ writel(1, &zynq_i2c->transfer_size);
return (zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP | ZYNQ_I2C_INTERRUPT_NACK) &
ZYNQ_I2C_INTERRUPT_COMP) ? 0 : ETIMEDOUT;
return -EINVAL;
/* Write the register address */
- Xsetbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO |
+ setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO |
ZYNQ_I2C_CONTROL_HOLD);
/* Temporarily disable restart (by clearing hold)... */
/* It doesn't seem to work. */
- Xclrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_RW |
+ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_RW |
ZYNQ_I2C_CONTROL_HOLD);
- Xout_le32(&zynq_i2c->interrupt_status, 0xFF);
+ writel(0xFF, &zynq_i2c->interrupt_status);
while (alen--)
- Xout_le32(&zynq_i2c->data, addr >> (8*alen));
- Xout_le32(&zynq_i2c->address, dev);
+ writel(addr >> (8*alen), &zynq_i2c->data);
+ writel(dev, &zynq_i2c->address);
/* wait for the address to be sent */
if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) {
/* Release the bus */
- Xclrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
+ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
return ETIMEDOUT;
}
debug("Device acked address\n");
- Xsetbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO |
+ setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO |
ZYNQ_I2C_CONTROL_RW);
/* Start reading data */
- Xout_le32(&zynq_i2c->address, dev);
- Xout_le32(&zynq_i2c->transfer_size, length);
+ writel(dev, &zynq_i2c->address);
+ writel(length, &zynq_i2c->transfer_size);
/* wait for data */
do {
ZYNQ_I2C_INTERRUPT_DATA);
if (!status) {
/* Release the bus */
- Xclrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
+ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
return ETIMEDOUT;
}
- debug("Read %d bytes\n", length - Xin_le32(&zynq_i2c->transfer_size));
- for (; i < length - Xin_le32(&zynq_i2c->transfer_size); i++)
- *(cur_data++) = Xin_le32(&zynq_i2c->data);
- } while (Xin_le32(&zynq_i2c->transfer_size) != 0);
+ debug("Read %d bytes\n",
+ length - readl(&zynq_i2c->transfer_size));
+ for (; i < length - readl(&zynq_i2c->transfer_size); i++)
+ *(cur_data++) = readl(&zynq_i2c->data);
+ } while (readl(&zynq_i2c->transfer_size) != 0);
/* All done... release the bus */
- Xclrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
+ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
#ifdef DEBUG
zynq_i2c_debug_status();
u8 *cur_data = data;
/* Write the register address */
- Xsetbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO |
+ setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO |
ZYNQ_I2C_CONTROL_HOLD);
- Xclrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_RW);
- Xout_le32(&zynq_i2c->interrupt_status, 0xFF);
+ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_RW);
+ writel(0xFF, &zynq_i2c->interrupt_status);
while (alen--)
- Xout_le32(&zynq_i2c->data, addr >> (8*alen));
+ writel(addr >> (8*alen), &zynq_i2c->data);
/* Start the tranfer */
- Xout_le32(&zynq_i2c->address, dev);
+ writel(dev, &zynq_i2c->address);
if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) {
/* Release the bus */
- Xclrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
+ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
return ETIMEDOUT;
}
debug("Device acked address\n");
while (length--) {
- Xout_le32(&zynq_i2c->data, *(cur_data++));
- if (Xin_le32(&zynq_i2c->transfer_size) == ZYNQ_I2C_FIFO_DEPTH) {
+ writel(*(cur_data++), &zynq_i2c->data);
+ if (readl(&zynq_i2c->transfer_size) == ZYNQ_I2C_FIFO_DEPTH) {
if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) {
/* Release the bus */
- Xclrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
+ clrbits_le32(&zynq_i2c->control,
+ ZYNQ_I2C_CONTROL_HOLD);
return ETIMEDOUT;
}
}
}
/* All done... release the bus */
- Xclrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
+ clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
/* wait for the address and data to be sent */
if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) return ETIMEDOUT;
return 0;