Lines Matching refs:i2c
55 static void meson_i2c_reset_tokens(struct meson_i2c *i2c) in meson_i2c_reset_tokens() argument
57 i2c->tokens[0] = 0; in meson_i2c_reset_tokens()
58 i2c->tokens[1] = 0; in meson_i2c_reset_tokens()
59 i2c->num_tokens = 0; in meson_i2c_reset_tokens()
62 static void meson_i2c_add_token(struct meson_i2c *i2c, int token) in meson_i2c_add_token() argument
64 if (i2c->num_tokens < 8) in meson_i2c_add_token()
65 i2c->tokens[0] |= (token & 0xf) << (i2c->num_tokens * 4); in meson_i2c_add_token()
67 i2c->tokens[1] |= (token & 0xf) << ((i2c->num_tokens % 8) * 4); in meson_i2c_add_token()
69 i2c->num_tokens++; in meson_i2c_add_token()
76 static void meson_i2c_get_data(struct meson_i2c *i2c, u8 *buf, int len) in meson_i2c_get_data() argument
81 rdata0 = readl(&i2c->regs->tok_rdata0); in meson_i2c_get_data()
82 rdata1 = readl(&i2c->regs->tok_rdata1); in meson_i2c_get_data()
97 static void meson_i2c_put_data(struct meson_i2c *i2c, u8 *buf, int len) in meson_i2c_put_data() argument
108 writel(wdata0, &i2c->regs->tok_wdata0); in meson_i2c_put_data()
109 writel(wdata1, &i2c->regs->tok_wdata1); in meson_i2c_put_data()
119 static void meson_i2c_prepare_xfer(struct meson_i2c *i2c) in meson_i2c_prepare_xfer() argument
121 bool write = !(i2c->msg->flags & I2C_M_RD); in meson_i2c_prepare_xfer()
124 i2c->count = min(i2c->msg->len - i2c->pos, 8u); in meson_i2c_prepare_xfer()
126 for (i = 0; i + 1 < i2c->count; i++) in meson_i2c_prepare_xfer()
127 meson_i2c_add_token(i2c, TOKEN_DATA); in meson_i2c_prepare_xfer()
129 if (i2c->count) { in meson_i2c_prepare_xfer()
130 if (write || i2c->pos + i2c->count < i2c->msg->len) in meson_i2c_prepare_xfer()
131 meson_i2c_add_token(i2c, TOKEN_DATA); in meson_i2c_prepare_xfer()
133 meson_i2c_add_token(i2c, TOKEN_DATA_LAST); in meson_i2c_prepare_xfer()
137 meson_i2c_put_data(i2c, i2c->msg->buf + i2c->pos, i2c->count); in meson_i2c_prepare_xfer()
139 if (i2c->last && i2c->pos + i2c->count >= i2c->msg->len) in meson_i2c_prepare_xfer()
140 meson_i2c_add_token(i2c, TOKEN_STOP); in meson_i2c_prepare_xfer()
142 writel(i2c->tokens[0], &i2c->regs->tok_list0); in meson_i2c_prepare_xfer()
143 writel(i2c->tokens[1], &i2c->regs->tok_list1); in meson_i2c_prepare_xfer()
146 static void meson_i2c_do_start(struct meson_i2c *i2c, struct i2c_msg *msg) in meson_i2c_do_start() argument
153 writel(msg->addr << 1, &i2c->regs->slave_addr); in meson_i2c_do_start()
154 meson_i2c_add_token(i2c, TOKEN_START); in meson_i2c_do_start()
155 meson_i2c_add_token(i2c, token); in meson_i2c_do_start()
158 static int meson_i2c_xfer_msg(struct meson_i2c *i2c, struct i2c_msg *msg, in meson_i2c_xfer_msg() argument
167 i2c->msg = msg; in meson_i2c_xfer_msg()
168 i2c->last = last; in meson_i2c_xfer_msg()
169 i2c->pos = 0; in meson_i2c_xfer_msg()
170 i2c->count = 0; in meson_i2c_xfer_msg()
172 meson_i2c_reset_tokens(i2c); in meson_i2c_xfer_msg()
173 meson_i2c_do_start(i2c, msg); in meson_i2c_xfer_msg()
176 meson_i2c_prepare_xfer(i2c); in meson_i2c_xfer_msg()
179 setbits_le32(&i2c->regs->ctrl, REG_CTRL_START); in meson_i2c_xfer_msg()
181 while (readl(&i2c->regs->ctrl) & REG_CTRL_STATUS) { in meson_i2c_xfer_msg()
183 clrbits_le32(&i2c->regs->ctrl, REG_CTRL_START); in meson_i2c_xfer_msg()
189 meson_i2c_reset_tokens(i2c); in meson_i2c_xfer_msg()
190 clrbits_le32(&i2c->regs->ctrl, REG_CTRL_START); in meson_i2c_xfer_msg()
192 if (readl(&i2c->regs->ctrl) & REG_CTRL_ERROR) { in meson_i2c_xfer_msg()
197 if ((msg->flags & I2C_M_RD) && i2c->count) { in meson_i2c_xfer_msg()
198 meson_i2c_get_data(i2c, i2c->msg->buf + i2c->pos, in meson_i2c_xfer_msg()
199 i2c->count); in meson_i2c_xfer_msg()
201 i2c->pos += i2c->count; in meson_i2c_xfer_msg()
202 } while (i2c->pos < msg->len); in meson_i2c_xfer_msg()
210 struct meson_i2c *i2c = dev_get_priv(bus); in meson_i2c_xfer() local
214 ret = meson_i2c_xfer_msg(i2c, msg + i, i == nmsgs - 1); in meson_i2c_xfer()
224 struct meson_i2c *i2c = dev_get_priv(bus); in meson_i2c_set_bus_speed() local
228 clk_rate = clk_get_rate(&i2c->clk); in meson_i2c_set_bus_speed()
240 clrsetbits_le32(&i2c->regs->ctrl, REG_CTRL_CLKDIV_MASK, in meson_i2c_set_bus_speed()
243 clrsetbits_le32(&i2c->regs->ctrl, REG_CTRL_CLKDIVEXT_MASK, in meson_i2c_set_bus_speed()
253 struct meson_i2c *i2c = dev_get_priv(bus); in meson_i2c_probe() local
256 ret = clk_get_by_index(bus, 0, &i2c->clk); in meson_i2c_probe()
260 ret = clk_enable(&i2c->clk); in meson_i2c_probe()
264 i2c->regs = dev_read_addr_ptr(bus); in meson_i2c_probe()
265 clrbits_le32(&i2c->regs->ctrl, REG_CTRL_START); in meson_i2c_probe()