summaryrefslogtreecommitdiff
path: root/drivers/i2c/busses/i2c-stm32f4.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-stm32f4.c')
-rw-r--r--drivers/i2c/busses/i2c-stm32f4.c96
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[] = {