• Home
  • Raw
  • Download

Lines Matching refs:i2c

98 static void meson_i2c_set_mask(struct meson_i2c *i2c, int reg, u32 mask,  in meson_i2c_set_mask()  argument
103 data = readl(i2c->regs + reg); in meson_i2c_set_mask()
106 writel(data, i2c->regs + reg); in meson_i2c_set_mask()
109 static void meson_i2c_reset_tokens(struct meson_i2c *i2c) in meson_i2c_reset_tokens() argument
111 i2c->tokens[0] = 0; in meson_i2c_reset_tokens()
112 i2c->tokens[1] = 0; in meson_i2c_reset_tokens()
113 i2c->num_tokens = 0; in meson_i2c_reset_tokens()
116 static void meson_i2c_add_token(struct meson_i2c *i2c, int token) in meson_i2c_add_token() argument
118 if (i2c->num_tokens < 8) in meson_i2c_add_token()
119 i2c->tokens[0] |= (token & 0xf) << (i2c->num_tokens * 4); in meson_i2c_add_token()
121 i2c->tokens[1] |= (token & 0xf) << ((i2c->num_tokens % 8) * 4); in meson_i2c_add_token()
123 i2c->num_tokens++; in meson_i2c_add_token()
126 static void meson_i2c_set_clk_div(struct meson_i2c *i2c, unsigned int freq) in meson_i2c_set_clk_div() argument
128 unsigned long clk_rate = clk_get_rate(i2c->clk); in meson_i2c_set_clk_div()
135 dev_err(i2c->dev, "requested bus frequency too low\n"); in meson_i2c_set_clk_div()
139 meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_CLKDIV_MASK, in meson_i2c_set_clk_div()
142 meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_CLKDIVEXT_MASK, in meson_i2c_set_clk_div()
145 dev_dbg(i2c->dev, "%s: clk %lu, freq %u, div %u\n", __func__, in meson_i2c_set_clk_div()
149 static void meson_i2c_get_data(struct meson_i2c *i2c, char *buf, int len) in meson_i2c_get_data() argument
154 rdata0 = readl(i2c->regs + REG_TOK_RDATA0); in meson_i2c_get_data()
155 rdata1 = readl(i2c->regs + REG_TOK_RDATA1); in meson_i2c_get_data()
157 dev_dbg(i2c->dev, "%s: data %08x %08x len %d\n", __func__, in meson_i2c_get_data()
167 static void meson_i2c_put_data(struct meson_i2c *i2c, char *buf, int len) in meson_i2c_put_data() argument
178 writel(wdata0, i2c->regs + REG_TOK_WDATA0); in meson_i2c_put_data()
179 writel(wdata1, i2c->regs + REG_TOK_WDATA1); in meson_i2c_put_data()
181 dev_dbg(i2c->dev, "%s: data %08x %08x len %d\n", __func__, in meson_i2c_put_data()
185 static void meson_i2c_prepare_xfer(struct meson_i2c *i2c) in meson_i2c_prepare_xfer() argument
187 bool write = !(i2c->msg->flags & I2C_M_RD); in meson_i2c_prepare_xfer()
190 i2c->count = min(i2c->msg->len - i2c->pos, 8); in meson_i2c_prepare_xfer()
192 for (i = 0; i < i2c->count - 1; i++) in meson_i2c_prepare_xfer()
193 meson_i2c_add_token(i2c, TOKEN_DATA); in meson_i2c_prepare_xfer()
195 if (i2c->count) { in meson_i2c_prepare_xfer()
196 if (write || i2c->pos + i2c->count < i2c->msg->len) in meson_i2c_prepare_xfer()
197 meson_i2c_add_token(i2c, TOKEN_DATA); in meson_i2c_prepare_xfer()
199 meson_i2c_add_token(i2c, TOKEN_DATA_LAST); in meson_i2c_prepare_xfer()
203 meson_i2c_put_data(i2c, i2c->msg->buf + i2c->pos, i2c->count); in meson_i2c_prepare_xfer()
205 if (i2c->last && i2c->pos + i2c->count >= i2c->msg->len) in meson_i2c_prepare_xfer()
206 meson_i2c_add_token(i2c, TOKEN_STOP); in meson_i2c_prepare_xfer()
208 writel(i2c->tokens[0], i2c->regs + REG_TOK_LIST0); in meson_i2c_prepare_xfer()
209 writel(i2c->tokens[1], i2c->regs + REG_TOK_LIST1); in meson_i2c_prepare_xfer()
214 struct meson_i2c *i2c = dev_id; in meson_i2c_irq() local
217 spin_lock(&i2c->lock); in meson_i2c_irq()
219 meson_i2c_reset_tokens(i2c); in meson_i2c_irq()
220 meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_START, 0); in meson_i2c_irq()
221 ctrl = readl(i2c->regs + REG_CTRL); in meson_i2c_irq()
223 dev_dbg(i2c->dev, "irq: state %d, pos %d, count %d, ctrl %08x\n", in meson_i2c_irq()
224 i2c->state, i2c->pos, i2c->count, ctrl); in meson_i2c_irq()
226 if (i2c->state == STATE_IDLE) { in meson_i2c_irq()
227 spin_unlock(&i2c->lock); in meson_i2c_irq()
238 dev_dbg(i2c->dev, "error bit set\n"); in meson_i2c_irq()
239 i2c->error = -ENXIO; in meson_i2c_irq()
240 i2c->state = STATE_IDLE; in meson_i2c_irq()
241 complete(&i2c->done); in meson_i2c_irq()
245 if (i2c->state == STATE_READ && i2c->count) in meson_i2c_irq()
246 meson_i2c_get_data(i2c, i2c->msg->buf + i2c->pos, i2c->count); in meson_i2c_irq()
248 i2c->pos += i2c->count; in meson_i2c_irq()
250 if (i2c->pos >= i2c->msg->len) { in meson_i2c_irq()
251 i2c->state = STATE_IDLE; in meson_i2c_irq()
252 complete(&i2c->done); in meson_i2c_irq()
257 meson_i2c_prepare_xfer(i2c); in meson_i2c_irq()
258 meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_START, REG_CTRL_START); in meson_i2c_irq()
260 spin_unlock(&i2c->lock); in meson_i2c_irq()
265 static void meson_i2c_do_start(struct meson_i2c *i2c, struct i2c_msg *msg) in meson_i2c_do_start() argument
272 writel(msg->addr << 1, i2c->regs + REG_SLAVE_ADDR); in meson_i2c_do_start()
273 meson_i2c_add_token(i2c, TOKEN_START); in meson_i2c_do_start()
274 meson_i2c_add_token(i2c, token); in meson_i2c_do_start()
277 static int meson_i2c_xfer_msg(struct meson_i2c *i2c, struct i2c_msg *msg, in meson_i2c_xfer_msg() argument
283 i2c->msg = msg; in meson_i2c_xfer_msg()
284 i2c->last = last; in meson_i2c_xfer_msg()
285 i2c->pos = 0; in meson_i2c_xfer_msg()
286 i2c->count = 0; in meson_i2c_xfer_msg()
287 i2c->error = 0; in meson_i2c_xfer_msg()
289 meson_i2c_reset_tokens(i2c); in meson_i2c_xfer_msg()
292 meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_ACK_IGNORE, flags); in meson_i2c_xfer_msg()
295 meson_i2c_do_start(i2c, msg); in meson_i2c_xfer_msg()
297 i2c->state = (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; in meson_i2c_xfer_msg()
298 meson_i2c_prepare_xfer(i2c); in meson_i2c_xfer_msg()
299 reinit_completion(&i2c->done); in meson_i2c_xfer_msg()
302 meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_START, REG_CTRL_START); in meson_i2c_xfer_msg()
305 time_left = wait_for_completion_timeout(&i2c->done, time_left); in meson_i2c_xfer_msg()
312 spin_lock_irqsave(&i2c->lock, flags); in meson_i2c_xfer_msg()
315 meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_START, 0); in meson_i2c_xfer_msg()
318 i2c->state = STATE_IDLE; in meson_i2c_xfer_msg()
322 if (i2c->error) in meson_i2c_xfer_msg()
323 ret = i2c->error; in meson_i2c_xfer_msg()
325 spin_unlock_irqrestore(&i2c->lock, flags); in meson_i2c_xfer_msg()
333 struct meson_i2c *i2c = adap->algo_data; in meson_i2c_xfer() local
336 clk_enable(i2c->clk); in meson_i2c_xfer()
339 ret = meson_i2c_xfer_msg(i2c, msgs + i, i == num - 1); in meson_i2c_xfer()
344 clk_disable(i2c->clk); in meson_i2c_xfer()
362 struct meson_i2c *i2c; in meson_i2c_probe() local
367 i2c = devm_kzalloc(&pdev->dev, sizeof(struct meson_i2c), GFP_KERNEL); in meson_i2c_probe()
368 if (!i2c) in meson_i2c_probe()
373 i2c->dev = &pdev->dev; in meson_i2c_probe()
374 platform_set_drvdata(pdev, i2c); in meson_i2c_probe()
376 spin_lock_init(&i2c->lock); in meson_i2c_probe()
377 init_completion(&i2c->done); in meson_i2c_probe()
379 i2c->clk = devm_clk_get(&pdev->dev, NULL); in meson_i2c_probe()
380 if (IS_ERR(i2c->clk)) { in meson_i2c_probe()
382 return PTR_ERR(i2c->clk); in meson_i2c_probe()
386 i2c->regs = devm_ioremap_resource(&pdev->dev, mem); in meson_i2c_probe()
387 if (IS_ERR(i2c->regs)) in meson_i2c_probe()
388 return PTR_ERR(i2c->regs); in meson_i2c_probe()
396 ret = devm_request_irq(&pdev->dev, irq, meson_i2c_irq, 0, NULL, i2c); in meson_i2c_probe()
402 ret = clk_prepare(i2c->clk); in meson_i2c_probe()
408 strlcpy(i2c->adap.name, "Meson I2C adapter", in meson_i2c_probe()
409 sizeof(i2c->adap.name)); in meson_i2c_probe()
410 i2c->adap.owner = THIS_MODULE; in meson_i2c_probe()
411 i2c->adap.algo = &meson_i2c_algorithm; in meson_i2c_probe()
412 i2c->adap.dev.parent = &pdev->dev; in meson_i2c_probe()
413 i2c->adap.dev.of_node = np; in meson_i2c_probe()
414 i2c->adap.algo_data = i2c; in meson_i2c_probe()
420 meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_START, 0); in meson_i2c_probe()
422 ret = i2c_add_adapter(&i2c->adap); in meson_i2c_probe()
424 clk_unprepare(i2c->clk); in meson_i2c_probe()
428 meson_i2c_set_clk_div(i2c, timings.bus_freq_hz); in meson_i2c_probe()
435 struct meson_i2c *i2c = platform_get_drvdata(pdev); in meson_i2c_remove() local
437 i2c_del_adapter(&i2c->adap); in meson_i2c_remove()
438 clk_unprepare(i2c->clk); in meson_i2c_remove()