summaryrefslogtreecommitdiff
path: root/drivers/i2c/busses/i2c-mt65xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-mt65xx.c')
-rw-r--r--drivers/i2c/busses/i2c-mt65xx.c61
1 files changed, 27 insertions, 34 deletions
diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 7ca3f2221ba6..aefdbee1f03c 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -19,9 +19,7 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/module.h>
-#include <linux/of_address.h>
-#include <linux/of_device.h>
-#include <linux/of_irq.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/scatterlist.h>
#include <linux/sched.h>
@@ -870,7 +868,7 @@ static int mtk_i2c_calculate_speed(struct mtk_i2c *i2c, unsigned int clk_src,
return 0;
}
-static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int parent_clk)
+static void mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int parent_clk)
{
unsigned int clk_src;
unsigned int step_cnt;
@@ -940,9 +938,6 @@ static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int parent_clk)
break;
}
-
-
- return 0;
}
static void i2c_dump_register(struct mtk_i2c *i2c)
@@ -1245,6 +1240,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
{
int ret;
int left_num = num;
+ bool write_then_read_en = false;
struct mtk_i2c *i2c = i2c_get_adapdata(adap);
ret = clk_bulk_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
@@ -1258,6 +1254,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
if (!(msgs[0].flags & I2C_M_RD) && (msgs[1].flags & I2C_M_RD) &&
msgs[0].addr == msgs[1].addr) {
i2c->auto_restart = 0;
+ write_then_read_en = true;
}
}
@@ -1282,12 +1279,10 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
else
i2c->op = I2C_MASTER_WR;
- if (!i2c->auto_restart) {
- if (num > 1) {
- /* combined two messages into one transaction */
- i2c->op = I2C_MASTER_WRRD;
- left_num--;
- }
+ if (write_then_read_en) {
+ /* combined two messages into one transaction */
+ i2c->op = I2C_MASTER_WRRD;
+ left_num--;
}
/* always use DMA mode. */
@@ -1295,7 +1290,10 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
if (ret < 0)
goto err_exit;
- msgs++;
+ if (i2c->op == I2C_MASTER_WRRD)
+ msgs += 2;
+ else
+ msgs++;
}
/* the return value is number of executed messages */
ret = num;
@@ -1308,12 +1306,9 @@ err_exit:
static irqreturn_t mtk_i2c_irq(int irqno, void *dev_id)
{
struct mtk_i2c *i2c = dev_id;
- u16 restart_flag = 0;
+ u16 restart_flag = i2c->auto_restart ? I2C_RS_TRANSFER : 0;
u16 intr_stat;
- if (i2c->auto_restart)
- restart_flag = I2C_RS_TRANSFER;
-
intr_stat = mtk_i2c_readw(i2c, OFFSET_INTR_STAT);
mtk_i2c_writew(i2c, intr_stat, OFFSET_INTR_STAT);
@@ -1347,7 +1342,7 @@ static u32 mtk_i2c_functionality(struct i2c_adapter *adap)
}
static const struct i2c_algorithm mtk_i2c_algorithm = {
- .master_xfer = mtk_i2c_transfer,
+ .xfer = mtk_i2c_transfer,
.functionality = mtk_i2c_functionality,
};
@@ -1444,25 +1439,25 @@ static int mtk_i2c_probe(struct platform_device *pdev)
if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk))
return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk);
+ i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = devm_clk_get_optional(&pdev->dev, "pmic");
+ if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk)) {
+ dev_err(&pdev->dev, "cannot get pmic clock\n");
+ return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk);
+ }
+
if (i2c->have_pmic) {
- i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = devm_clk_get(&pdev->dev, "pmic");
- if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk)) {
+ if (!i2c->clocks[I2C_MT65XX_CLK_PMIC].clk) {
dev_err(&pdev->dev, "cannot get pmic clock\n");
- return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk);
+ return -ENODEV;
}
speed_clk = I2C_MT65XX_CLK_PMIC;
} else {
- i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = NULL;
speed_clk = I2C_MT65XX_CLK_MAIN;
}
strscpy(i2c->adap.name, I2C_DRV_NAME, sizeof(i2c->adap.name));
- ret = mtk_i2c_set_speed(i2c, clk_get_rate(i2c->clocks[speed_clk].clk));
- if (ret) {
- dev_err(&pdev->dev, "Failed to set the speed.\n");
- return -EINVAL;
- }
+ mtk_i2c_set_speed(i2c, clk_get_rate(i2c->clocks[speed_clk].clk));
if (i2c->dev_comp->max_dma_support > 32) {
ret = dma_set_mask(&pdev->dev,
@@ -1514,7 +1509,6 @@ static void mtk_i2c_remove(struct platform_device *pdev)
clk_bulk_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
}
-#ifdef CONFIG_PM_SLEEP
static int mtk_i2c_suspend_noirq(struct device *dev)
{
struct mtk_i2c *i2c = dev_get_drvdata(dev);
@@ -1544,19 +1538,18 @@ static int mtk_i2c_resume_noirq(struct device *dev)
return 0;
}
-#endif
static const struct dev_pm_ops mtk_i2c_pm = {
- SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mtk_i2c_suspend_noirq,
- mtk_i2c_resume_noirq)
+ NOIRQ_SYSTEM_SLEEP_PM_OPS(mtk_i2c_suspend_noirq,
+ mtk_i2c_resume_noirq)
};
static struct platform_driver mtk_i2c_driver = {
.probe = mtk_i2c_probe,
- .remove_new = mtk_i2c_remove,
+ .remove = mtk_i2c_remove,
.driver = {
.name = I2C_DRV_NAME,
- .pm = &mtk_i2c_pm,
+ .pm = pm_sleep_ptr(&mtk_i2c_pm),
.of_match_table = mtk_i2c_of_match,
},
};