diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-st.c')
| -rw-r--r-- | drivers/i2c/busses/i2c-st.c | 72 |
1 files changed, 26 insertions, 46 deletions
diff --git a/drivers/i2c/busses/i2c-st.c b/drivers/i2c/busses/i2c-st.c index 9e62f893958a..97d70e667227 100644 --- a/drivers/i2c/busses/i2c-st.c +++ b/drivers/i2c/busses/i2c-st.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2013 STMicroelectronics * - * I2C master mode controller driver, used in STMicroelectronics devices. + * I2C controller driver, used in STMicroelectronics devices. * * Author: Maxime Coquelin <maxime.coquelin@st.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, as - * published by the Free Software Foundation. */ #include <linux/clk.h> @@ -16,6 +13,7 @@ #include <linux/i2c.h> #include <linux/interrupt.h> #include <linux/io.h> +#include <linux/minmax.h> #include <linux/module.h> #include <linux/of_address.h> #include <linux/of_irq.h> @@ -153,8 +151,8 @@ struct st_i2c_timings { /** * struct st_i2c_client - client specific data - * @addr: 8-bit slave addr, including r/w bit - * @count: number of bytes to be transfered + * @addr: 8-bit target addr, including r/w bit + * @count: number of bytes to be transferred * @xfered: number of bytes already transferred * @buf: data buffer * @result: result of the transfer @@ -216,7 +214,7 @@ static inline void st_i2c_clr_bits(void __iomem *reg, u32 mask) */ static struct st_i2c_timings i2c_timings[] = { [I2C_MODE_STANDARD] = { - .rate = 100000, + .rate = I2C_MAX_STANDARD_MODE_FREQ, .rep_start_hold = 4400, .rep_start_setup = 5170, .start_hold = 4400, @@ -225,7 +223,7 @@ static struct st_i2c_timings i2c_timings[] = { .bus_free_time = 5170, }, [I2C_MODE_FAST] = { - .rate = 400000, + .rate = I2C_MAX_FAST_MODE_FREQ, .rep_start_hold = 660, .rep_start_setup = 660, .start_hold = 660, @@ -425,23 +423,20 @@ static void st_i2c_wr_fill_tx_fifo(struct st_i2c_dev *i2c_dev) tx_fstat = readl_relaxed(i2c_dev->base + SSC_TX_FSTAT); tx_fstat &= SSC_TX_FSTAT_STATUS; - if (c->count < (SSC_TXFIFO_SIZE - tx_fstat)) - i = c->count; - else - i = SSC_TXFIFO_SIZE - tx_fstat; - - for (; i > 0; i--, c->count--, c->buf++) + for (i = min(c->count, SSC_TXFIFO_SIZE - tx_fstat); + i > 0; i--, c->count--, c->buf++) st_i2c_write_tx_fifo(i2c_dev, *c->buf); } /** * st_i2c_rd_fill_tx_fifo() - Fill the Tx FIFO in read mode * @i2c_dev: Controller's private data + * @max: Maximum amount of data to fill into the Tx FIFO * * This functions fills the Tx FIFO with fixed pattern when * in read mode to trigger clock. */ -static void st_i2c_rd_fill_tx_fifo(struct st_i2c_dev *i2c_dev, int max) +static void st_i2c_rd_fill_tx_fifo(struct st_i2c_dev *i2c_dev, u32 max) { struct st_i2c_client *c = &i2c_dev->client; u32 tx_fstat, sta; @@ -454,12 +449,8 @@ static void st_i2c_rd_fill_tx_fifo(struct st_i2c_dev *i2c_dev, int max) tx_fstat = readl_relaxed(i2c_dev->base + SSC_TX_FSTAT); tx_fstat &= SSC_TX_FSTAT_STATUS; - if (max < (SSC_TXFIFO_SIZE - tx_fstat)) - i = max; - else - i = SSC_TXFIFO_SIZE - tx_fstat; - - for (; i > 0; i--, c->xfered++) + for (i = min(max, SSC_TXFIFO_SIZE - tx_fstat); + i > 0; i--, c->xfered++) st_i2c_write_tx_fifo(i2c_dev, 0xff); } @@ -526,7 +517,7 @@ static void st_i2c_handle_write(struct st_i2c_dev *i2c_dev) } /** - * st_i2c_handle_write() - Handle FIFO enmpty interrupt in case of read + * st_i2c_handle_read() - Handle FIFO empty interrupt in case of read * @i2c_dev: Controller's private data */ static void st_i2c_handle_read(struct st_i2c_dev *i2c_dev) @@ -560,7 +551,7 @@ static void st_i2c_handle_read(struct st_i2c_dev *i2c_dev) } /** - * st_i2c_isr() - Interrupt routine + * st_i2c_isr_thread() - Interrupt routine * @irq: interrupt number * @data: Controller's private data */ @@ -649,7 +640,7 @@ static int st_i2c_xfer_msg(struct st_i2c_dev *i2c_dev, struct i2c_msg *msg, { struct st_i2c_client *c = &i2c_dev->client; u32 ctl, i2c, it; - unsigned long timeout; + unsigned long time_left; int ret; c->addr = i2c_8bit_addr_from_msg(msg); @@ -669,7 +660,7 @@ static int st_i2c_xfer_msg(struct st_i2c_dev *i2c_dev, struct i2c_msg *msg, i2c |= SSC_I2C_ACKG; st_i2c_set_bits(i2c_dev->base + SSC_I2C, i2c); - /* Write slave address */ + /* Write target address */ st_i2c_write_tx_fifo(i2c_dev, c->addr); /* Pre-fill Tx fifo with data in case of write */ @@ -687,15 +678,12 @@ static int st_i2c_xfer_msg(struct st_i2c_dev *i2c_dev, struct i2c_msg *msg, st_i2c_set_bits(i2c_dev->base + SSC_I2C, SSC_I2C_STRTG); } - timeout = wait_for_completion_timeout(&i2c_dev->complete, - i2c_dev->adap.timeout); + time_left = wait_for_completion_timeout(&i2c_dev->complete, + i2c_dev->adap.timeout); ret = c->result; - if (!timeout) { - dev_err(i2c_dev->dev, "Write to slave 0x%x timed out\n", - c->addr); + if (!time_left) ret = -ETIMEDOUT; - } i2c = SSC_I2C_STOPG | SSC_I2C_REPSTRTG; st_i2c_clr_bits(i2c_dev->base + SSC_I2C, i2c); @@ -742,7 +730,6 @@ static int st_i2c_xfer(struct i2c_adapter *i2c_adap, return (ret < 0) ? ret : i; } -#ifdef CONFIG_PM_SLEEP static int st_i2c_suspend(struct device *dev) { struct st_i2c_dev *i2c_dev = dev_get_drvdata(dev); @@ -764,11 +751,7 @@ static int st_i2c_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(st_i2c_pm, st_i2c_suspend, st_i2c_resume); -#define ST_I2C_PM (&st_i2c_pm) -#else -#define ST_I2C_PM NULL -#endif +static DEFINE_SIMPLE_DEV_PM_OPS(st_i2c_pm, st_i2c_suspend, st_i2c_resume); static u32 st_i2c_func(struct i2c_adapter *adap) { @@ -776,7 +759,7 @@ static u32 st_i2c_func(struct i2c_adapter *adap) } static const struct i2c_algorithm st_i2c_algo = { - .master_xfer = st_i2c_xfer, + .xfer = st_i2c_xfer, .functionality = st_i2c_func, }; @@ -819,8 +802,7 @@ static int st_i2c_probe(struct platform_device *pdev) if (!i2c_dev) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - i2c_dev->base = devm_ioremap_resource(&pdev->dev, res); + i2c_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(i2c_dev->base)) return PTR_ERR(i2c_dev->base); @@ -838,7 +820,7 @@ static int st_i2c_probe(struct platform_device *pdev) i2c_dev->mode = I2C_MODE_STANDARD; ret = of_property_read_u32(np, "clock-frequency", &clk_rate); - if ((!ret) && (clk_rate == 400000)) + if (!ret && (clk_rate == I2C_MAX_FAST_MODE_FREQ)) i2c_dev->mode = I2C_MODE_FAST; i2c_dev->dev = &pdev->dev; @@ -883,13 +865,11 @@ static int st_i2c_probe(struct platform_device *pdev) return 0; } -static int st_i2c_remove(struct platform_device *pdev) +static void st_i2c_remove(struct platform_device *pdev) { struct st_i2c_dev *i2c_dev = platform_get_drvdata(pdev); i2c_del_adapter(&i2c_dev->adap); - - return 0; } static const struct of_device_id st_i2c_match[] = { @@ -903,7 +883,7 @@ static struct platform_driver st_i2c_driver = { .driver = { .name = "st-i2c", .of_match_table = st_i2c_match, - .pm = ST_I2C_PM, + .pm = pm_sleep_ptr(&st_i2c_pm), }, .probe = st_i2c_probe, .remove = st_i2c_remove, |
