Lines Matching refs:i2c

7  #include <linux/i2c.h>
13 /* spacemit i2c registers */
56 #define SPACEMIT_SR_IBB BIT(16) /* i2c bus busy */
83 /* i2c bus recover timeout: us */
98 /* i2c-spacemit driver's main struct */
123 static void spacemit_i2c_enable(struct spacemit_i2c_dev *i2c)
127 val = readl(i2c->base + SPACEMIT_ICR);
129 writel(val, i2c->base + SPACEMIT_ICR);
132 static void spacemit_i2c_disable(struct spacemit_i2c_dev *i2c)
136 val = readl(i2c->base + SPACEMIT_ICR);
138 writel(val, i2c->base + SPACEMIT_ICR);
141 static void spacemit_i2c_reset(struct spacemit_i2c_dev *i2c)
143 writel(SPACEMIT_CR_UR, i2c->base + SPACEMIT_ICR);
145 writel(0, i2c->base + SPACEMIT_ICR);
148 static int spacemit_i2c_handle_err(struct spacemit_i2c_dev *i2c)
150 dev_dbg(i2c->dev, "i2c error status: 0x%08x\n", i2c->status);
152 if (i2c->status & (SPACEMIT_SR_BED | SPACEMIT_SR_ALD)) {
153 spacemit_i2c_reset(i2c);
157 return i2c->status & SPACEMIT_SR_ACKNAK ? -ENXIO : -EIO;
160 static void spacemit_i2c_conditionally_reset_bus(struct spacemit_i2c_dev *i2c)
165 status = readl(i2c->base + SPACEMIT_IBMR);
169 spacemit_i2c_reset(i2c);
173 status = readl(i2c->base + SPACEMIT_IBMR);
175 dev_warn_ratelimited(i2c->dev, "unit reset failed\n");
178 static int spacemit_i2c_wait_bus_idle(struct spacemit_i2c_dev *i2c)
183 val = readl(i2c->base + SPACEMIT_ISR);
187 ret = readl_poll_timeout(i2c->base + SPACEMIT_ISR,
191 spacemit_i2c_reset(i2c);
196 static void spacemit_i2c_check_bus_release(struct spacemit_i2c_dev *i2c)
199 if (readl(i2c->base + SPACEMIT_ISR) & SPACEMIT_SR_EBB) {
200 spacemit_i2c_conditionally_reset_bus(i2c);
205 static void spacemit_i2c_init(struct spacemit_i2c_dev *i2c)
227 if (i2c->clock_freq == SPACEMIT_I2C_MAX_FAST_MODE_FREQ)
239 writel(val, i2c->base + SPACEMIT_ICR);
243 spacemit_i2c_clear_int_status(struct spacemit_i2c_dev *i2c, u32 mask)
245 writel(mask & SPACEMIT_I2C_INT_STATUS_MASK, i2c->base + SPACEMIT_ISR);
248 static void spacemit_i2c_start(struct spacemit_i2c_dev *i2c)
251 struct i2c_msg *cur_msg = i2c->msgs + i2c->msg_idx;
253 i2c->read = !!(cur_msg->flags & I2C_M_RD);
255 i2c->state = SPACEMIT_STATE_START;
261 writel(target_addr_rw, i2c->base + SPACEMIT_IDBR);
264 val = readl(i2c->base + SPACEMIT_ICR);
267 writel(val, i2c->base + SPACEMIT_ICR);
270 static void spacemit_i2c_stop(struct spacemit_i2c_dev *i2c)
274 val = readl(i2c->base + SPACEMIT_ICR);
277 if (i2c->read)
280 writel(val, i2c->base + SPACEMIT_ICR);
283 static int spacemit_i2c_xfer_msg(struct spacemit_i2c_dev *i2c)
288 for (i2c->msg_idx = 0; i2c->msg_idx < i2c->msg_num; i2c->msg_idx++) {
289 msg = &i2c->msgs[i2c->msg_idx];
290 i2c->msg_buf = msg->buf;
291 i2c->unprocessed = msg->len;
292 i2c->status = 0;
294 reinit_completion(&i2c->complete);
296 spacemit_i2c_start(i2c);
298 time_left = wait_for_completion_timeout(&i2c->complete,
299 i2c->adapt.timeout);
301 dev_err(i2c->dev, "msg completion timeout\n");
302 spacemit_i2c_conditionally_reset_bus(i2c);
303 spacemit_i2c_reset(i2c);
307 if (i2c->status & SPACEMIT_SR_ERR)
308 return spacemit_i2c_handle_err(i2c);
314 static bool spacemit_i2c_is_last_msg(struct spacemit_i2c_dev *i2c)
316 if (i2c->msg_idx != i2c->msg_num - 1)
319 if (i2c->read)
320 return i2c->unprocessed == 1;
322 return !i2c->unprocessed;
325 static void spacemit_i2c_handle_write(struct spacemit_i2c_dev *i2c)
328 if (i2c->status & SPACEMIT_SR_MSD)
331 if (i2c->unprocessed) {
332 writel(*i2c->msg_buf++, i2c->base + SPACEMIT_IDBR);
333 i2c->unprocessed--;
338 i2c->state = SPACEMIT_STATE_IDLE;
339 complete(&i2c->complete);
342 static void spacemit_i2c_handle_read(struct spacemit_i2c_dev *i2c)
344 if (i2c->unprocessed) {
345 *i2c->msg_buf++ = readl(i2c->base + SPACEMIT_IDBR);
346 i2c->unprocessed--;
350 if (i2c->status & (SPACEMIT_SR_MSD | SPACEMIT_SR_ACKNAK))
354 if (i2c->unprocessed)
358 i2c->state = SPACEMIT_STATE_IDLE;
359 complete(&i2c->complete);
362 static void spacemit_i2c_handle_start(struct spacemit_i2c_dev *i2c)
364 i2c->state = i2c->read ? SPACEMIT_STATE_READ : SPACEMIT_STATE_WRITE;
365 if (i2c->state == SPACEMIT_STATE_WRITE)
366 spacemit_i2c_handle_write(i2c);
369 static void spacemit_i2c_err_check(struct spacemit_i2c_dev *i2c)
377 if (!(i2c->status & (SPACEMIT_SR_ERR | SPACEMIT_SR_MSD)))
383 * happens before spacemit_i2c_xfer to disable irq and i2c unit,
387 val = readl(i2c->base + SPACEMIT_ICR);
389 writel(val, i2c->base + SPACEMIT_ICR);
391 spacemit_i2c_clear_int_status(i2c, SPACEMIT_I2C_INT_STATUS_MASK);
393 i2c->state = SPACEMIT_STATE_IDLE;
394 complete(&i2c->complete);
399 struct spacemit_i2c_dev *i2c = devid;
402 status = readl(i2c->base + SPACEMIT_ISR);
406 i2c->status = status;
408 spacemit_i2c_clear_int_status(i2c, status);
410 if (i2c->status & SPACEMIT_SR_ERR)
413 val = readl(i2c->base + SPACEMIT_ICR);
415 writel(val, i2c->base + SPACEMIT_ICR);
417 switch (i2c->state) {
419 spacemit_i2c_handle_start(i2c);
422 spacemit_i2c_handle_read(i2c);
425 spacemit_i2c_handle_write(i2c);
431 if (i2c->state != SPACEMIT_STATE_IDLE) {
432 if (spacemit_i2c_is_last_msg(i2c)) {
434 spacemit_i2c_stop(i2c);
438 writel(val, i2c->base + SPACEMIT_ICR);
443 spacemit_i2c_err_check(i2c);
447 static void spacemit_i2c_calc_timeout(struct spacemit_i2c_dev *i2c)
452 for (; idx < i2c->msg_num; idx++)
453 cnt += (i2c->msgs + idx)->len + 1;
459 timeout = cnt * 9 * USEC_PER_SEC / i2c->clock_freq;
461 i2c->adapt.timeout = usecs_to_jiffies(timeout + USEC_PER_SEC / 10) / i2c->msg_num;
466 struct spacemit_i2c_dev *i2c = i2c_get_adapdata(adapt);
469 i2c->msgs = msgs;
470 i2c->msg_num = num;
472 spacemit_i2c_calc_timeout(i2c);
474 spacemit_i2c_init(i2c);
476 spacemit_i2c_enable(i2c);
478 ret = spacemit_i2c_wait_bus_idle(i2c);
480 ret = spacemit_i2c_xfer_msg(i2c);
482 dev_dbg(i2c->dev, "i2c transfer error: %d\n", ret);
484 spacemit_i2c_check_bus_release(i2c);
486 spacemit_i2c_disable(i2c);
489 dev_err(i2c->dev, "i2c transfer failed, ret %d err 0x%lx\n",
490 ret, i2c->status & SPACEMIT_SR_ERR);
510 struct spacemit_i2c_dev *i2c;
513 i2c = devm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL);
514 if (!i2c)
517 ret = of_property_read_u32(of_node, "clock-frequency", &i2c->clock_freq);
522 if (!i2c->clock_freq || i2c->clock_freq > SPACEMIT_I2C_MAX_FAST_MODE_FREQ) {
524 i2c->clock_freq, SPACEMIT_I2C_MAX_FAST_MODE_FREQ);
525 i2c->clock_freq = SPACEMIT_I2C_MAX_FAST_MODE_FREQ;
526 } else if (i2c->clock_freq < SPACEMIT_I2C_MAX_STANDARD_MODE_FREQ) {
528 i2c->clock_freq, SPACEMIT_I2C_MAX_STANDARD_MODE_FREQ);
529 i2c->clock_freq = SPACEMIT_I2C_MAX_STANDARD_MODE_FREQ;
532 i2c->dev = &pdev->dev;
534 i2c->base = devm_platform_ioremap_resource(pdev, 0);
535 if (IS_ERR(i2c->base))
536 return dev_err_probe(dev, PTR_ERR(i2c->base), "failed to do ioremap");
538 i2c->irq = platform_get_irq(pdev, 0);
539 if (i2c->irq < 0)
540 return dev_err_probe(dev, i2c->irq, "failed to get irq resource");
542 ret = devm_request_irq(i2c->dev, i2c->irq, spacemit_i2c_irq_handler,
543 IRQF_NO_SUSPEND | IRQF_ONESHOT, dev_name(i2c->dev), i2c);
555 spacemit_i2c_reset(i2c);
557 i2c_set_adapdata(&i2c->adapt, i2c);
558 i2c->adapt.owner = THIS_MODULE;
559 i2c->adapt.algo = &spacemit_i2c_algo;
560 i2c->adapt.dev.parent = i2c->dev;
561 i2c->adapt.nr = pdev->id;
563 i2c->adapt.dev.of_node = of_node;
565 strscpy(i2c->adapt.name, "spacemit-i2c-adapter", sizeof(i2c->adapt.name));
567 init_completion(&i2c->complete);
569 platform_set_drvdata(pdev, i2c);
571 ret = i2c_add_numbered_adapter(&i2c->adapt);
573 return dev_err_probe(&pdev->dev, ret, "failed to add i2c adapter");
580 struct spacemit_i2c_dev *i2c = platform_get_drvdata(pdev);
582 i2c_del_adapter(&i2c->adapt);
586 { .compatible = "spacemit,k1-i2c", },
595 .name = "i2c-k1",