Skip to content

Commit 2397a63

Browse files
gautierg-stkartben
authored andcommitted
drivers: i2c: move functions to a common file
In preparation of the introduction of the STM32 I2Cv2 RTIO driver, move some functions that are used in both drivers into a common file. Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
1 parent 0c59977 commit 2397a63

File tree

6 files changed

+182
-161
lines changed

6 files changed

+182
-161
lines changed

drivers/i2c/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,12 @@ zephyr_library_sources_ifdef(CONFIG_I2C_SEDI i2c_sedi.c)
6767
zephyr_library_sources_ifdef(CONFIG_I2C_SIFIVE i2c_sifive.c)
6868
zephyr_library_sources_ifdef(CONFIG_I2C_SMARTBOND i2c_smartbond.c)
6969
zephyr_library_sources_ifdef(CONFIG_I2C_STM32_V1
70+
i2c_ll_stm32_common.c
7071
i2c_ll_stm32_v1.c
7172
i2c_ll_stm32.c
7273
)
7374
zephyr_library_sources_ifdef(CONFIG_I2C_STM32_V2
75+
i2c_ll_stm32_common.c
7476
i2c_ll_stm32_v2.c
7577
i2c_ll_stm32.c
7678
)

drivers/i2c/i2c_ll_stm32.c

Lines changed: 0 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -329,59 +329,6 @@ static DEVICE_API(i2c, api_funcs) = {
329329
#endif
330330
};
331331

332-
#ifdef CONFIG_PM_DEVICE
333-
334-
static int i2c_stm32_suspend(const struct device *dev)
335-
{
336-
int ret;
337-
const struct i2c_stm32_config *cfg = dev->config;
338-
const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
339-
340-
/* Disable device clock. */
341-
ret = clock_control_off(clk, (clock_control_subsys_t)&cfg->pclken[0]);
342-
if (ret < 0) {
343-
LOG_ERR("failure disabling I2C clock");
344-
return ret;
345-
}
346-
347-
/* Move pins to sleep state */
348-
ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_SLEEP);
349-
if (ret == -ENOENT) {
350-
/* Warn but don't block suspend */
351-
LOG_WRN("I2C pinctrl sleep state not available ");
352-
} else if (ret < 0) {
353-
return ret;
354-
}
355-
356-
return 0;
357-
}
358-
359-
#endif
360-
361-
static int i2c_stm32_activate(const struct device *dev)
362-
{
363-
int ret;
364-
const struct i2c_stm32_config *cfg = dev->config;
365-
const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
366-
367-
/* Move pins to active/default state */
368-
ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
369-
if (ret < 0) {
370-
LOG_ERR("I2C pinctrl setup failed (%d)", ret);
371-
return ret;
372-
}
373-
374-
/* Enable device clock. */
375-
if (clock_control_on(clk,
376-
(clock_control_subsys_t) &cfg->pclken[0]) != 0) {
377-
LOG_ERR("i2c: failure enabling clock");
378-
return -EIO;
379-
}
380-
381-
return 0;
382-
}
383-
384-
385332
static int i2c_stm32_init(const struct device *dev)
386333
{
387334
const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
@@ -450,28 +397,6 @@ static int i2c_stm32_init(const struct device *dev)
450397
return 0;
451398
}
452399

453-
#ifdef CONFIG_PM_DEVICE
454-
455-
static int i2c_stm32_pm_action(const struct device *dev, enum pm_device_action action)
456-
{
457-
int err;
458-
459-
switch (action) {
460-
case PM_DEVICE_ACTION_RESUME:
461-
err = i2c_stm32_activate(dev);
462-
break;
463-
case PM_DEVICE_ACTION_SUSPEND:
464-
err = i2c_stm32_suspend(dev);
465-
break;
466-
default:
467-
return -ENOTSUP;
468-
}
469-
470-
return err;
471-
}
472-
473-
#endif
474-
475400
#ifdef CONFIG_SMBUS_STM32_SMBALERT
476401
void i2c_stm32_smbalert_set_callback(const struct device *dev, i2c_stm32_smbalert_cb_func_t func,
477402
const struct device *cb_dev)
@@ -540,51 +465,6 @@ void i2c_stm32_smbalert_disable(const struct device *dev)
540465

541466
/* Macros for I2C instance declaration */
542467

543-
#ifdef CONFIG_I2C_STM32_INTERRUPT
544-
545-
#ifdef CONFIG_I2C_STM32_COMBINED_INTERRUPT
546-
#define I2C_STM32_IRQ_CONNECT_AND_ENABLE(index) \
547-
do { \
548-
IRQ_CONNECT(DT_INST_IRQN(index), \
549-
DT_INST_IRQ(index, priority), \
550-
i2c_stm32_combined_isr, \
551-
DEVICE_DT_INST_GET(index), 0); \
552-
irq_enable(DT_INST_IRQN(index)); \
553-
} while (false)
554-
#else
555-
#define I2C_STM32_IRQ_CONNECT_AND_ENABLE(index) \
556-
do { \
557-
IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, event, irq), \
558-
DT_INST_IRQ_BY_NAME(index, event, priority),\
559-
i2c_stm32_event_isr, \
560-
DEVICE_DT_INST_GET(index), 0); \
561-
irq_enable(DT_INST_IRQ_BY_NAME(index, event, irq)); \
562-
\
563-
IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, error, irq), \
564-
DT_INST_IRQ_BY_NAME(index, error, priority),\
565-
i2c_stm32_error_isr, \
566-
DEVICE_DT_INST_GET(index), 0); \
567-
irq_enable(DT_INST_IRQ_BY_NAME(index, error, irq)); \
568-
} while (false)
569-
#endif /* CONFIG_I2C_STM32_COMBINED_INTERRUPT */
570-
571-
#define I2C_STM32_IRQ_HANDLER_DECL(index) \
572-
static void i2c_stm32_irq_config_func_##index(const struct device *dev)
573-
#define I2C_STM32_IRQ_HANDLER_FUNCTION(index) \
574-
.irq_config_func = i2c_stm32_irq_config_func_##index,
575-
#define I2C_STM32_IRQ_HANDLER(index) \
576-
static void i2c_stm32_irq_config_func_##index(const struct device *dev) \
577-
{ \
578-
I2C_STM32_IRQ_CONNECT_AND_ENABLE(index); \
579-
}
580-
#else
581-
582-
#define I2C_STM32_IRQ_HANDLER_DECL(index)
583-
#define I2C_STM32_IRQ_HANDLER_FUNCTION(index)
584-
#define I2C_STM32_IRQ_HANDLER(index)
585-
586-
#endif /* CONFIG_I2C_STM32_INTERRUPT */
587-
588468
#ifdef CONFIG_I2C_STM32_V2_DMA
589469

590470
#define I2C_DMA_INIT(index, dir) \

drivers/i2c/i2c_ll_stm32.h

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
#define ZEPHYR_DRIVERS_I2C_I2C_LL_STM32_H_
1111

1212
#include <zephyr/drivers/i2c/stm32.h>
13+
#include <zephyr/kernel.h>
14+
#include <zephyr/devicetree.h>
15+
#include <zephyr/pm/device.h>
16+
#include <zephyr/pm/device_runtime.h>
17+
#include <zephyr/logging/log.h>
1318

1419
#ifdef CONFIG_I2C_STM32_BUS_RECOVERY
1520
#include <zephyr/drivers/gpio.h>
@@ -117,15 +122,65 @@ int i2c_stm32_transaction(const struct device *dev,
117122
int i2c_stm32_configure_timing(const struct device *dev, uint32_t clk);
118123
int i2c_stm32_runtime_configure(const struct device *dev, uint32_t config);
119124

120-
void i2c_stm32_event_isr(void *arg);
121-
void i2c_stm32_error_isr(void *arg);
122-
#ifdef CONFIG_I2C_STM32_COMBINED_INTERRUPT
123-
void i2c_stm32_combined_isr(void *arg);
124-
#endif /* CONFIG_I2C_STM32_COMBINED_INTERRUPT */
125-
126125
#ifdef CONFIG_I2C_TARGET
127126
int i2c_stm32_target_register(const struct device *dev, struct i2c_target_config *config);
128127
int i2c_stm32_target_unregister(const struct device *dev, struct i2c_target_config *config);
129128
#endif /* CONFIG_I2C_TARGET */
130129

130+
int i2c_stm32_activate(const struct device *dev);
131+
132+
#ifdef CONFIG_PM_DEVICE
133+
int i2c_stm32_pm_action(const struct device *dev, enum pm_device_action action);
134+
int i2c_stm32_suspend(const struct device *dev);
135+
#endif /* CONFIG_PM_DEVICE */
136+
137+
int i2c_stm32_error(const struct device *dev);
138+
void i2c_stm32_event(const struct device *dev);
139+
140+
#ifdef CONFIG_I2C_STM32_INTERRUPT
141+
#ifdef CONFIG_I2C_STM32_COMBINED_INTERRUPT
142+
void i2c_stm32_combined_isr(void *arg);
143+
#define I2C_STM32_IRQ_CONNECT_AND_ENABLE(index) \
144+
do { \
145+
IRQ_CONNECT(DT_INST_IRQN(index), \
146+
DT_INST_IRQ(index, priority), \
147+
i2c_stm32_combined_isr, \
148+
DEVICE_DT_INST_GET(index), 0); \
149+
irq_enable(DT_INST_IRQN(index)); \
150+
} while (false)
151+
#else /* CONFIG_I2C_STM32_COMBINED_INTERRUPT */
152+
void i2c_stm32_event_isr(void *arg);
153+
void i2c_stm32_error_isr(void *arg);
154+
#define I2C_STM32_IRQ_CONNECT_AND_ENABLE(index) \
155+
do { \
156+
IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, event, irq), \
157+
DT_INST_IRQ_BY_NAME(index, event, priority), \
158+
i2c_stm32_event_isr, \
159+
DEVICE_DT_INST_GET(index), 0); \
160+
irq_enable(DT_INST_IRQ_BY_NAME(index, event, irq)); \
161+
\
162+
IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, error, irq), \
163+
DT_INST_IRQ_BY_NAME(index, error, priority), \
164+
i2c_stm32_error_isr, \
165+
DEVICE_DT_INST_GET(index), 0); \
166+
irq_enable(DT_INST_IRQ_BY_NAME(index, error, irq)); \
167+
} while (false)
168+
#endif /* CONFIG_I2C_STM32_COMBINED_INTERRUPT */
169+
170+
#define I2C_STM32_IRQ_HANDLER_DECL(index) \
171+
static void i2c_stm32_irq_config_func_##index(const struct device *dev)
172+
#define I2C_STM32_IRQ_HANDLER_FUNCTION(index) \
173+
.irq_config_func = i2c_stm32_irq_config_func_##index,
174+
#define I2C_STM32_IRQ_HANDLER(index) \
175+
static void i2c_stm32_irq_config_func_##index(const struct device *dev) \
176+
{ \
177+
I2C_STM32_IRQ_CONNECT_AND_ENABLE(index); \
178+
}
179+
180+
#else /* CONFIG_I2C_STM32_INTERRUPT */
181+
#define STM32_I2C_IRQ_HANDLER_DECL(index)
182+
#define STM32_I2C_IRQ_HANDLER_FUNCTION(index)
183+
#define STM32_I2C_IRQ_HANDLER(index)
184+
#endif /* CONFIG_I2C_STM32_INTERRUPT */
185+
131186
#endif /* ZEPHYR_DRIVERS_I2C_I2C_LL_STM32_H_ */

drivers/i2c/i2c_ll_stm32_common.c

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* Copyright (c) 2016 BayLibre, SAS
3+
* Copyright (c) 2017 Linaro Ltd
4+
* Copyright (c) 2024 Intel Corporation
5+
* Copyright (c) 2025 STMicroelectronics
6+
*
7+
* SPDX-License-Identifier: Apache-2.0
8+
*/
9+
10+
#include <zephyr/drivers/clock_control/stm32_clock_control.h>
11+
#include <zephyr/drivers/clock_control.h>
12+
#include <zephyr/drivers/pinctrl.h>
13+
14+
#define LOG_LEVEL CONFIG_I2C_LOG_LEVEL
15+
#include <zephyr/logging/log.h>
16+
LOG_MODULE_REGISTER(i2c_ll_stm32_common);
17+
18+
#include "i2c_ll_stm32.h"
19+
20+
#ifdef CONFIG_I2C_STM32_COMBINED_INTERRUPT
21+
void i2c_stm32_combined_isr(void *arg)
22+
{
23+
const struct device *dev = (const struct device *) arg;
24+
25+
if (i2c_stm32_error(dev)) {
26+
return;
27+
}
28+
i2c_stm32_event(dev);
29+
}
30+
#else
31+
void i2c_stm32_event_isr(void *arg)
32+
{
33+
const struct device *dev = (const struct device *) arg;
34+
35+
i2c_stm32_event(dev);
36+
}
37+
38+
void i2c_stm32_error_isr(void *arg)
39+
{
40+
const struct device *dev = (const struct device *) arg;
41+
42+
(void)i2c_stm32_error(dev);
43+
}
44+
#endif
45+
46+
int i2c_stm32_activate(const struct device *dev)
47+
{
48+
int ret;
49+
const struct i2c_stm32_config *cfg = dev->config;
50+
const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
51+
52+
/* Move pins to active/default state */
53+
ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
54+
if (ret < 0) {
55+
LOG_ERR("I2C pinctrl setup failed (%d)", ret);
56+
return ret;
57+
}
58+
59+
/* Enable device clock. */
60+
if (clock_control_on(clk,
61+
(clock_control_subsys_t) &cfg->pclken[0]) != 0) {
62+
LOG_ERR("i2c: failure enabling clock");
63+
return -EIO;
64+
}
65+
66+
return 0;
67+
}
68+
69+
#ifdef CONFIG_PM_DEVICE
70+
int i2c_stm32_suspend(const struct device *dev)
71+
{
72+
int ret;
73+
const struct i2c_stm32_config *cfg = dev->config;
74+
const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
75+
76+
/* Disable device clock. */
77+
ret = clock_control_off(clk, (clock_control_subsys_t)&cfg->pclken[0]);
78+
if (ret < 0) {
79+
LOG_ERR("failure disabling I2C clock");
80+
return ret;
81+
}
82+
83+
/* Move pins to sleep state */
84+
ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_SLEEP);
85+
if (ret == -ENOENT) {
86+
/* Warn but don't block suspend */
87+
LOG_WRN("I2C pinctrl sleep state not available ");
88+
} else if (ret < 0) {
89+
return ret;
90+
}
91+
92+
return 0;
93+
}
94+
95+
int i2c_stm32_pm_action(const struct device *dev, enum pm_device_action action)
96+
{
97+
int err;
98+
99+
switch (action) {
100+
case PM_DEVICE_ACTION_RESUME:
101+
err = i2c_stm32_activate(dev);
102+
break;
103+
case PM_DEVICE_ACTION_SUSPEND:
104+
err = i2c_stm32_suspend(dev);
105+
break;
106+
default:
107+
return -ENOTSUP;
108+
}
109+
110+
return err;
111+
}
112+
#endif

drivers/i2c/i2c_ll_stm32_v1.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -564,9 +564,8 @@ int i2c_stm32_target_unregister(const struct device *dev, struct i2c_target_conf
564564
}
565565
#endif /* defined(CONFIG_I2C_TARGET) */
566566

567-
void i2c_stm32_event_isr(void *arg)
567+
void i2c_stm32_event(const struct device *dev)
568568
{
569-
const struct device *dev = (const struct device *)arg;
570569
const struct i2c_stm32_config *cfg = dev->config;
571570
struct i2c_stm32_data *data = dev->data;
572571
I2C_TypeDef *i2c = cfg->i2c;
@@ -593,17 +592,16 @@ void i2c_stm32_event_isr(void *arg)
593592
}
594593
}
595594

596-
void i2c_stm32_error_isr(void *arg)
595+
int i2c_stm32_error(const struct device *dev)
597596
{
598-
const struct device *dev = (const struct device *)arg;
599597
const struct i2c_stm32_config *cfg = dev->config;
600598
struct i2c_stm32_data *data = dev->data;
601599
I2C_TypeDef *i2c = cfg->i2c;
602600

603601
#if defined(CONFIG_I2C_TARGET)
604602
if (data->slave_attached && !data->master_active) {
605603
/* No need for a slave error function right now. */
606-
return;
604+
return 0;
607605
}
608606
#endif
609607

@@ -634,9 +632,10 @@ void i2c_stm32_error_isr(void *arg)
634632
goto end;
635633
}
636634
#endif
637-
return;
635+
return 0;
638636
end:
639637
i2c_stm32_master_mode_end(dev);
638+
return -EIO;
640639
}
641640

642641
static int32_t i2c_stm32_msg_write(const struct device *dev, struct i2c_msg *msg,

0 commit comments

Comments
 (0)