aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorEtienne Carriere <etienne.carriere@linaro.org>2019-03-08 13:40:34 +0100
committerJérôme Forissier <jerome.forissier@linaro.org>2019-04-10 14:08:40 +0200
commitc75303f777b76d6b61a6ccaddb81d7b544c731dc (patch)
tree11e6ce45e25c07ace05281258654dd2608fb9a8d /core
parent400b8cbf9a4c60450b7feea2e1d883eac2aba664 (diff)
stm32_i2c: handle pinctrl
Get pinctrl support from stm32_gpio.h into STM32 I2C driver. When device tree content defines pins related to an I2C interface, the I2C driver saves the pins configuration instances and set the registered pins in the expected power mode at runtime. Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org> Acked-by: Jens Wiklander <jens.wiklander@linaro.org>
Diffstat (limited to 'core')
-rw-r--r--core/drivers/stm32_i2c.c27
-rw-r--r--core/include/drivers/stm32_i2c.h11
2 files changed, 35 insertions, 3 deletions
diff --git a/core/drivers/stm32_i2c.c b/core/drivers/stm32_i2c.c
index c6257041..35fa505e 100644
--- a/core/drivers/stm32_i2c.c
+++ b/core/drivers/stm32_i2c.c
@@ -648,7 +648,9 @@ static int i2c_config_analog_filter(struct i2c_handle_s *hi2c,
}
int stm32_i2c_get_setup_from_fdt(void *fdt, int node,
- struct stm32_i2c_init_s *init)
+ struct stm32_i2c_init_s *init,
+ struct stm32_pinctrl **pinctrl,
+ size_t *pinctrl_count)
{
const fdt32_t *cuint = NULL;
struct dt_node_info info = { .status = 0 };
@@ -694,6 +696,24 @@ int stm32_i2c_get_setup_from_fdt(void *fdt, int node,
init->speed_mode = STM32_I2C_SPEED_DEFAULT;
}
+ count = stm32_pinctrl_fdt_get_pinctrl(fdt, node, NULL, 0);
+ if (count <= 0) {
+ *pinctrl = NULL;
+ *pinctrl_count = 0;
+ return count;
+ }
+
+ if (count > 2)
+ panic("Too many PINCTRLs found");
+
+ *pinctrl = calloc(count, sizeof(**pinctrl));
+ if (!*pinctrl)
+ panic();
+
+ *pinctrl_count = stm32_pinctrl_fdt_get_pinctrl(fdt, node,
+ *pinctrl, count);
+ assert(*pinctrl_count == (unsigned int)count);
+
return 0;
}
@@ -1381,8 +1401,10 @@ void stm32_i2c_resume(struct i2c_handle_s *hi2c)
(hi2c->i2c_state != I2C_STATE_SUSPENDED))
panic();
+ stm32_pinctrl_load_active_cfg(hi2c->pinctrl, hi2c->pinctrl_count);
+
if (hi2c->i2c_state == I2C_STATE_RESET) {
- /* This is no valid I2C configuration loaded yet */
+ /* There is no valid I2C configuration to be loaded yet */
return;
}
@@ -1400,6 +1422,7 @@ void stm32_i2c_suspend(struct i2c_handle_s *hi2c)
panic();
save_cfg(hi2c, &hi2c->sec_cfg);
+ stm32_pinctrl_load_standby_cfg(hi2c->pinctrl, hi2c->pinctrl_count);
hi2c->i2c_state = I2C_STATE_SUSPENDED;
}
diff --git a/core/include/drivers/stm32_i2c.h b/core/include/drivers/stm32_i2c.h
index 2ca7ac89..ac0ea225 100644
--- a/core/include/drivers/stm32_i2c.h
+++ b/core/include/drivers/stm32_i2c.h
@@ -6,6 +6,7 @@
#ifndef __STM32_I2C_H
#define __STM32_I2C_H
+#include <drivers/stm32_gpio.h>
#include <mm/core_memprot.h>
#include <stdbool.h>
#include <stdint.h>
@@ -89,6 +90,8 @@ struct i2c_cfg {
* @i2c_state: Driver state ID I2C_STATE_*
* @i2c_err: Last error code I2C_ERROR_*
* @sec_cfg: I2C regsiters configuration storage
+ * @pinctrl: PINCTRLs configuration for the I2C PINs
+ * @pinctrl_count: Number of PINCTRLs elements
*/
struct i2c_handle_s {
struct io_pa_va base;
@@ -96,6 +99,8 @@ struct i2c_handle_s {
enum i2c_state_e i2c_state;
uint32_t i2c_err;
struct i2c_cfg sec_cfg;
+ struct stm32_pinctrl *pinctrl;
+ size_t pinctrl_count;
};
/* STM32 specific defines */
@@ -112,10 +117,14 @@ struct i2c_handle_s {
* @fdt: Reference to DT
* @node: Target I2C node in the DT
* @init: Output stm32_i2c_init_s structure
+ * @pinctrl: Reference to output pinctrl array
+ * @pinctrl_count: Input @pinctrl array size, output expected size
* Return 0 on success else a negative value
*/
int stm32_i2c_get_setup_from_fdt(void *fdt, int node,
- struct stm32_i2c_init_s *init);
+ struct stm32_i2c_init_s *init,
+ struct stm32_pinctrl **pinctrl,
+ size_t *pinctrl_count);
/*
* Initialize I2C bus handle from input configuration directives