Skip to content

Commit f7f8de0

Browse files
author
Erdem Simsek
committed
[nrf fromtree] drivers: i2s: Support audio auxpll in TDM driver
Add support for audio_auxpll clock source as an alternative to audiopll in the i2s_nrf_tdm driver. This enables TDM functionality on platforms that use the auxiliary PLL for audio clocking. - Add audio_auxpll node detection and configuration - Update clock management to support both audiopll and audio_auxpll - Add build assertions for supported frequency configurations Signed-off-by: Erdem Simsek <[email protected]>
1 parent 011312e commit f7f8de0

File tree

1 file changed

+33
-15
lines changed

1 file changed

+33
-15
lines changed

drivers/i2s/i2s_nrf_tdm.c

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <hal/nrf_tdm.h>
1111
#include <haly/nrfy_gpio.h>
1212
#include <zephyr/drivers/clock_control/nrf_clock_control.h>
13+
#include <zephyr/dt-bindings/clock/nrf-auxpll.h>
1314
#include <zephyr/drivers/i2s.h>
1415
#include <zephyr/drivers/pinctrl.h>
1516
#include <zephyr/irq.h>
@@ -47,11 +48,13 @@ LOG_MODULE_REGISTER(tdm_nrf, CONFIG_I2S_LOG_LEVEL);
4748
#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(audiopll))
4849
#define NODE_ACLK DT_NODELABEL(audiopll)
4950
#define ACLK_FREQUENCY DT_PROP_OR(NODE_ACLK, frequency, 0)
50-
51-
static const struct device *audiopll = DEVICE_DT_GET(NODE_ACLK);
52-
static const struct nrf_clock_spec aclk_spec = {
53-
.frequency = ACLK_FREQUENCY,
54-
};
51+
#elif DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(audio_auxpll))
52+
#define NODE_AUDIO_AUXPLL DT_NODELABEL(audio_auxpll)
53+
#define ACLK_NORDIC_FREQUENCY DT_PROP(NODE_AUDIO_AUXPLL, nordic_frequency)
54+
BUILD_ASSERT((ACLK_NORDIC_FREQUENCY == NRF_AUXPLL_FREQ_DIV_AUDIO_48K) ||
55+
(ACLK_NORDIC_FREQUENCY == NRF_AUXPLL_FREQ_DIV_AUDIO_44K1),
56+
"Unsupported Audio AUXPLL frequency selection for TDM");
57+
#define ACLK_FREQUENCY CLOCK_CONTROL_NRF_AUXPLL_GET_FREQ(NODE_AUDIO_AUXPLL)
5558
#elif DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(aclk))
5659
#define NODE_ACLK DT_NODELABEL(aclk)
5760
#define ACLK_FREQUENCY DT_PROP_OR(NODE_ACLK, clock_frequency, 0)
@@ -107,7 +110,10 @@ struct tdm_drv_cfg {
107110
};
108111

109112
struct tdm_drv_data {
110-
#if CONFIG_CLOCK_CONTROL_NRF
113+
#if CONFIG_CLOCK_CONTROL_NRFS_AUDIOPLL || DT_NODE_HAS_STATUS_OKAY(NODE_AUDIO_AUXPLL)
114+
const struct device *audiopll;
115+
struct nrf_clock_spec aclk_spec;
116+
#elif CONFIG_CLOCK_CONTROL_NRF
111117
struct onoff_manager *clk_mgr;
112118
#endif
113119
struct onoff_client clk_cli;
@@ -132,8 +138,10 @@ static int audio_clock_request(struct tdm_drv_data *drv_data)
132138
{
133139
#if DT_NODE_HAS_STATUS_OKAY(NODE_ACLK) && CONFIG_CLOCK_CONTROL_NRF
134140
return onoff_request(drv_data->clk_mgr, &drv_data->clk_cli);
135-
#elif DT_NODE_HAS_STATUS_OKAY(NODE_ACLK) && CONFIG_CLOCK_CONTROL_NRFS_AUDIOPLL
136-
return nrf_clock_control_request(audiopll, &aclk_spec, &drv_data->clk_cli);
141+
#elif (DT_NODE_HAS_STATUS_OKAY(NODE_ACLK) && CONFIG_CLOCK_CONTROL_NRFS_AUDIOPLL) || \
142+
DT_NODE_HAS_STATUS_OKAY(NODE_AUDIO_AUXPLL)
143+
return nrf_clock_control_request(drv_data->audiopll, &drv_data->aclk_spec,
144+
&drv_data->clk_cli);
137145
#else
138146
(void)drv_data;
139147

@@ -145,10 +153,9 @@ static int audio_clock_release(struct tdm_drv_data *drv_data)
145153
{
146154
#if DT_NODE_HAS_STATUS_OKAY(NODE_ACLK) && CONFIG_CLOCK_CONTROL_NRF
147155
return onoff_release(drv_data->clk_mgr);
148-
#elif DT_NODE_HAS_STATUS_OKAY(NODE_ACLK) && CONFIG_CLOCK_CONTROL_NRFS_AUDIOPLL
149-
(void)drv_data;
150-
151-
return nrf_clock_control_release(audiopll, &aclk_spec);
156+
#elif (DT_NODE_HAS_STATUS_OKAY(NODE_ACLK) && CONFIG_CLOCK_CONTROL_NRFS_AUDIOPLL) || \
157+
DT_NODE_HAS_STATUS_OKAY(NODE_AUDIO_AUXPLL)
158+
return nrf_clock_control_release(drv_data->audiopll, &drv_data->aclk_spec);
152159
#else
153160
(void)drv_data;
154161

@@ -1120,6 +1127,16 @@ static void clock_manager_init(const struct device *dev)
11201127
subsys = CLOCK_CONTROL_NRF_SUBSYS_HFAUDIO;
11211128
drv_data->clk_mgr = z_nrf_clock_control_get_onoff(subsys);
11221129
__ASSERT_NO_MSG(drv_data->clk_mgr != NULL);
1130+
#elif DT_NODE_HAS_STATUS_OKAY(NODE_ACLK) && CONFIG_CLOCK_CONTROL_NRFS_AUDIOPLL
1131+
struct tdm_drv_data *drv_data = dev->data;
1132+
1133+
drv_data->audiopll = DEVICE_DT_GET(NODE_ACLK);
1134+
drv_data->aclk_spec.frequency = ACLK_FREQUENCY;
1135+
#elif DT_NODE_HAS_STATUS_OKAY(NODE_AUDIO_AUXPLL)
1136+
struct tdm_drv_data *drv_data = dev->data;
1137+
1138+
drv_data->audiopll = DEVICE_DT_GET(NODE_AUDIO_AUXPLL);
1139+
drv_data->aclk_spec.frequency = ACLK_FREQUENCY;
11231140
#else
11241141
(void)dev;
11251142
#endif
@@ -1194,9 +1211,10 @@ static DEVICE_API(i2s, tdm_nrf_drv_api) = {
11941211
clock_manager_init(dev); \
11951212
return 0; \
11961213
} \
1197-
BUILD_ASSERT((TDM_SCK_CLK_SRC(idx) != ACLK && TDM_MCK_CLK_SRC(idx) != ACLK) || \
1198-
DT_NODE_HAS_STATUS_OKAY(NODE_ACLK), \
1199-
"Clock source ACLK requires the audiopll node."); \
1214+
BUILD_ASSERT((TDM_SCK_CLK_SRC(idx) != ACLK && TDM_MCK_CLK_SRC(idx) != ACLK) || \
1215+
(DT_NODE_HAS_STATUS_OKAY(NODE_ACLK) || \
1216+
DT_NODE_HAS_STATUS_OKAY(NODE_AUDIO_AUXPLL)), \
1217+
"Clock source ACLK requires the audiopll/audio_auxpll node."); \
12001218
NRF_DT_CHECK_NODE_HAS_REQUIRED_MEMORY_REGIONS(TDM(idx)); \
12011219
DEVICE_DT_DEFINE(TDM(idx), tdm_nrf_init##idx, NULL, &tdm_nrf_data##idx, &tdm_nrf_cfg##idx, \
12021220
POST_KERNEL, CONFIG_I2S_INIT_PRIORITY, &tdm_nrf_drv_api);

0 commit comments

Comments
 (0)