diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-stm32f4.c')
| -rw-r--r-- | drivers/i2c/busses/i2c-stm32f4.c | 96 |
1 files changed, 39 insertions, 57 deletions
diff --git a/drivers/i2c/busses/i2c-stm32f4.c b/drivers/i2c/busses/i2c-stm32f4.c index f9dd7e86b861..b3d56d0aa9d0 100644 --- a/drivers/i2c/busses/i2c-stm32f4.c +++ b/drivers/i2c/busses/i2c-stm32f4.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Driver for STMicroelectronics STM32 I2C controller * @@ -6,11 +7,11 @@ * http://www.st.com/resource/en/reference_manual/DM00031020.pdf * * Copyright (C) M'boumba Cedric Madianga 2016 + * Copyright (C) STMicroelectronics 2017 * Author: M'boumba Cedric Madianga <cedric.madianga@gmail.com> * * This driver is based on i2c-st.c * - * License terms: GNU General Public License (GPL), version 2 */ #include <linux/clk.h> @@ -27,6 +28,8 @@ #include <linux/platform_device.h> #include <linux/reset.h> +#include "i2c-stm32.h" + /* STM32F4 I2C offset registers */ #define STM32F4_I2C_CR1 0x00 #define STM32F4_I2C_CR2 0x04 @@ -90,15 +93,9 @@ #define STM32F4_I2C_MAX_FREQ 46U #define HZ_TO_MHZ 1000000 -enum stm32f4_i2c_speed { - STM32F4_I2C_SPEED_STANDARD, /* 100 kHz */ - STM32F4_I2C_SPEED_FAST, /* 400 kHz */ - STM32F4_I2C_SPEED_END, -}; - /** * struct stm32f4_i2c_msg - client specific data - * @addr: 8-bit slave addr, including r/w bit + * @addr: 8-bit target addr, including r/w bit * @count: number of bytes to be transferred * @buf: data buffer * @result: result of the transfer @@ -159,7 +156,7 @@ static int stm32f4_i2c_set_periph_clk_freq(struct stm32f4_i2c_dev *i2c_dev) i2c_dev->parent_rate = clk_get_rate(i2c_dev->clk); freq = DIV_ROUND_UP(i2c_dev->parent_rate, HZ_TO_MHZ); - if (i2c_dev->speed == STM32F4_I2C_SPEED_STANDARD) { + if (i2c_dev->speed == STM32_I2C_SPEED_STANDARD) { /* * To reach 100 kHz, the parent clk frequency should be between * a minimum value of 2 MHz and a maximum value of 46 MHz due @@ -216,7 +213,7 @@ static void stm32f4_i2c_set_rise_time(struct stm32f4_i2c_dev *i2c_dev) * is not higher than 46 MHz . As a result trise is at most 4 bits wide * and so fits into the TRISE bits [5:0]. */ - if (i2c_dev->speed == STM32F4_I2C_SPEED_STANDARD) + if (i2c_dev->speed == STM32_I2C_SPEED_STANDARD) trise = freq + 1; else trise = freq * 3 / 10 + 1; @@ -230,15 +227,15 @@ static void stm32f4_i2c_set_speed_mode(struct stm32f4_i2c_dev *i2c_dev) u32 val; u32 ccr = 0; - if (i2c_dev->speed == STM32F4_I2C_SPEED_STANDARD) { + if (i2c_dev->speed == STM32_I2C_SPEED_STANDARD) { /* * In standard mode: * t_scl_high = t_scl_low = CCR * I2C parent clk period * So to reach 100 kHz, we have: - * CCR = I2C parent rate / 100 kHz >> 1 + * CCR = I2C parent rate / (100 kHz * 2) * * For example with parent rate = 2 MHz: - * CCR = 2000000 / (100000 << 1) = 10 + * CCR = 2000000 / (100000 * 2) = 10 * t_scl_high = t_scl_low = 10 * (1 / 2000000) = 5000 ns * t_scl_high + t_scl_low = 10000 ns so 100 kHz is reached * @@ -246,7 +243,7 @@ static void stm32f4_i2c_set_speed_mode(struct stm32f4_i2c_dev *i2c_dev) * parent rate is not higher than 46 MHz . As a result val * is at most 8 bits wide and so fits into the CCR bits [11:0]. */ - val = i2c_dev->parent_rate / (100000 << 1); + val = i2c_dev->parent_rate / (I2C_MAX_STANDARD_MODE_FREQ * 2); } else { /* * In fast mode, we compute CCR with duty = 0 as with low @@ -266,7 +263,7 @@ static void stm32f4_i2c_set_speed_mode(struct stm32f4_i2c_dev *i2c_dev) * parent rate is not higher than 46 MHz . As a result val * is at most 6 bits wide and so fits into the CCR bits [11:0]. */ - val = DIV_ROUND_UP(i2c_dev->parent_rate, 400000 * 3); + val = DIV_ROUND_UP(i2c_dev->parent_rate, I2C_MAX_FAST_MODE_FREQ * 3); /* Select Fast mode */ ccr |= STM32F4_I2C_CCR_FS; @@ -316,7 +313,7 @@ static int stm32f4_i2c_wait_free_bus(struct stm32f4_i2c_dev *i2c_dev) } /** - * stm32f4_i2c_write_ byte() - Write a byte in the data register + * stm32f4_i2c_write_byte() - Write a byte in the data register * @i2c_dev: Controller's private data * @byte: Data to write in the register */ @@ -352,7 +349,7 @@ static void stm32f4_i2c_read_msg(struct stm32f4_i2c_dev *i2c_dev) static void stm32f4_i2c_terminate_xfer(struct stm32f4_i2c_dev *i2c_dev) { struct stm32f4_i2c_msg *msg = &i2c_dev->msg; - void __iomem *reg = i2c_dev->base + STM32F4_I2C_CR2; + void __iomem *reg; stm32f4_i2c_disable_irq(i2c_dev); @@ -483,7 +480,7 @@ static void stm32f4_i2c_handle_rx_done(struct stm32f4_i2c_dev *i2c_dev) /** * stm32f4_i2c_handle_rx_addr() - Handle address matched interrupt in case of - * master receiver + * controller receiver * @i2c_dev: Controller's private data */ static void stm32f4_i2c_handle_rx_addr(struct stm32f4_i2c_dev *i2c_dev) @@ -537,7 +534,7 @@ static void stm32f4_i2c_handle_rx_addr(struct stm32f4_i2c_dev *i2c_dev) default: /* * N-byte reception: - * Enable ACK, reset POS (ACK postion) and clear ADDR flag. + * Enable ACK, reset POS (ACK position) and clear ADDR flag. * In that way, ACK will be sent as soon as the current byte * will be received in the shift register */ @@ -646,7 +643,7 @@ static irqreturn_t stm32f4_i2c_isr_error(int irq, void *data) /* * Acknowledge failure: - * In master transmitter mode a Stop must be generated by software + * In controller transmitter mode a Stop must be generated by software */ if (status & STM32F4_I2C_SR1_AF) { if (!(msg->addr & I2C_M_RD)) { @@ -684,7 +681,7 @@ static int stm32f4_i2c_xfer_msg(struct stm32f4_i2c_dev *i2c_dev, { struct stm32f4_i2c_msg *f4_msg = &i2c_dev->msg; void __iomem *reg = i2c_dev->base + STM32F4_I2C_CR1; - unsigned long timeout; + unsigned long time_left; u32 mask; int ret; @@ -709,11 +706,11 @@ static int stm32f4_i2c_xfer_msg(struct stm32f4_i2c_dev *i2c_dev, stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_START); } - 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 = f4_msg->result; - if (!timeout) + if (!time_left) ret = -ETIMEDOUT; return ret; @@ -751,8 +748,8 @@ static u32 stm32f4_i2c_func(struct i2c_adapter *adap) return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; } -static struct i2c_algorithm stm32f4_i2c_algo = { - .master_xfer = stm32f4_i2c_xfer, +static const struct i2c_algorithm stm32f4_i2c_algo = { + .xfer = stm32f4_i2c_xfer, .functionality = stm32f4_i2c_func, }; @@ -770,8 +767,7 @@ static int stm32f4_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); @@ -787,31 +783,25 @@ static int stm32f4_i2c_probe(struct platform_device *pdev) return -EINVAL; } - i2c_dev->clk = devm_clk_get(&pdev->dev, NULL); + i2c_dev->clk = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(i2c_dev->clk)) { - dev_err(&pdev->dev, "Error: Missing controller clock\n"); + dev_err(&pdev->dev, "Failed to enable clock\n"); return PTR_ERR(i2c_dev->clk); } - ret = clk_prepare_enable(i2c_dev->clk); - if (ret) { - dev_err(i2c_dev->dev, "Failed to prepare_enable clock\n"); - return ret; - } - rst = devm_reset_control_get(&pdev->dev, NULL); - if (IS_ERR(rst)) { - dev_err(&pdev->dev, "Error: Missing controller reset\n"); - ret = PTR_ERR(rst); - goto clk_free; - } + rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); + if (IS_ERR(rst)) + return dev_err_probe(&pdev->dev, PTR_ERR(rst), + "Error: Missing reset ctrl\n"); + reset_control_assert(rst); udelay(2); reset_control_deassert(rst); - i2c_dev->speed = STM32F4_I2C_SPEED_STANDARD; + i2c_dev->speed = STM32_I2C_SPEED_STANDARD; ret = of_property_read_u32(np, "clock-frequency", &clk_rate); - if (!ret && clk_rate >= 400000) - i2c_dev->speed = STM32F4_I2C_SPEED_FAST; + if (!ret && clk_rate >= I2C_MAX_FAST_MODE_FREQ) + i2c_dev->speed = STM32_I2C_SPEED_FAST; i2c_dev->dev = &pdev->dev; @@ -820,7 +810,7 @@ static int stm32f4_i2c_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "Failed to request irq event %i\n", irq_event); - goto clk_free; + return ret; } ret = devm_request_irq(&pdev->dev, irq_error, stm32f4_i2c_isr_error, 0, @@ -828,12 +818,12 @@ static int stm32f4_i2c_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "Failed to request irq error %i\n", irq_error); - goto clk_free; + return ret; } ret = stm32f4_i2c_hw_config(i2c_dev); if (ret) - goto clk_free; + return ret; adap = &i2c_dev->adap; i2c_set_adapdata(adap, i2c_dev); @@ -849,7 +839,7 @@ static int stm32f4_i2c_probe(struct platform_device *pdev) ret = i2c_add_adapter(adap); if (ret) - goto clk_free; + return ret; platform_set_drvdata(pdev, i2c_dev); @@ -858,21 +848,13 @@ static int stm32f4_i2c_probe(struct platform_device *pdev) dev_info(i2c_dev->dev, "STM32F4 I2C driver registered\n"); return 0; - -clk_free: - clk_disable_unprepare(i2c_dev->clk); - return ret; } -static int stm32f4_i2c_remove(struct platform_device *pdev) +static void stm32f4_i2c_remove(struct platform_device *pdev) { struct stm32f4_i2c_dev *i2c_dev = platform_get_drvdata(pdev); i2c_del_adapter(&i2c_dev->adap); - - clk_unprepare(i2c_dev->clk); - - return 0; } static const struct of_device_id stm32f4_i2c_match[] = { |
