|
2 | 2 | // Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. |
3 | 3 |
|
4 | 4 | #include <linux/acpi.h> |
| 5 | +#include <linux/bitfield.h> |
5 | 6 | #include <linux/clk.h> |
6 | 7 | #include <linux/dmaengine.h> |
7 | 8 | #include <linux/dma-mapping.h> |
@@ -67,6 +68,7 @@ enum geni_i2c_err_code { |
67 | 68 | GENI_TIMEOUT, |
68 | 69 | }; |
69 | 70 |
|
| 71 | +#define I2C_DMA_TX_IRQ_MASK GENMASK(12, 5) |
70 | 72 | #define DM_I2C_CB_ERR ((BIT(NACK) | BIT(BUS_PROTO) | BIT(ARB_LOST)) \ |
71 | 73 | << 5) |
72 | 74 |
|
@@ -99,6 +101,7 @@ struct geni_i2c_dev { |
99 | 101 | struct dma_chan *rx_c; |
100 | 102 | bool gpi_mode; |
101 | 103 | bool abort_done; |
| 104 | + struct gpi_i2c_result i2c_result; |
102 | 105 | }; |
103 | 106 |
|
104 | 107 | struct geni_i2c_desc { |
@@ -498,9 +501,18 @@ static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg, |
498 | 501 |
|
499 | 502 | static void i2c_gpi_cb_result(void *cb, const struct dmaengine_result *result) |
500 | 503 | { |
501 | | - struct geni_i2c_dev *gi2c = cb; |
502 | | - |
503 | | - if (result->result != DMA_TRANS_NOERROR) { |
| 504 | + struct gpi_i2c_result *i2c_res = cb; |
| 505 | + struct geni_i2c_dev *gi2c = container_of(i2c_res, struct geni_i2c_dev, i2c_result); |
| 506 | + u32 status; |
| 507 | + |
| 508 | + status = FIELD_GET(I2C_DMA_TX_IRQ_MASK, i2c_res->status); |
| 509 | + if (status == BIT(NACK)) { |
| 510 | + geni_i2c_err(gi2c, NACK); |
| 511 | + } else if (status == BIT(BUS_PROTO)) { |
| 512 | + geni_i2c_err(gi2c, BUS_PROTO); |
| 513 | + } else if (status == BIT(ARB_LOST)) { |
| 514 | + geni_i2c_err(gi2c, ARB_LOST); |
| 515 | + } else if (result->result != DMA_TRANS_NOERROR) { |
504 | 516 | dev_err(gi2c->se.dev, "DMA txn failed:%d\n", result->result); |
505 | 517 | gi2c->err = -EIO; |
506 | 518 | } else if (result->residue) { |
@@ -582,7 +594,7 @@ static int geni_i2c_gpi(struct geni_i2c_dev *gi2c, struct i2c_msg *msg, |
582 | 594 | } |
583 | 595 |
|
584 | 596 | desc->callback_result = i2c_gpi_cb_result; |
585 | | - desc->callback_param = gi2c; |
| 597 | + desc->callback_param = &gi2c->i2c_result; |
586 | 598 |
|
587 | 599 | dmaengine_submit(desc); |
588 | 600 | *buf = dma_buf; |
@@ -870,7 +882,13 @@ static int geni_i2c_probe(struct platform_device *pdev) |
870 | 882 | goto err_clk; |
871 | 883 | } |
872 | 884 | proto = geni_se_read_proto(&gi2c->se); |
873 | | - if (proto != GENI_SE_I2C) { |
| 885 | + if (proto == GENI_SE_INVALID_PROTO) { |
| 886 | + ret = geni_load_se_firmware(&gi2c->se, GENI_SE_I2C); |
| 887 | + if (ret) { |
| 888 | + dev_err_probe(dev, ret, "i2c firmware load failed ret: %d\n", ret); |
| 889 | + goto err_resources; |
| 890 | + } |
| 891 | + } else if (proto != GENI_SE_I2C) { |
874 | 892 | ret = dev_err_probe(dev, -ENXIO, "Invalid proto %d\n", proto); |
875 | 893 | goto err_resources; |
876 | 894 | } |
|
0 commit comments