Skip to content

Commit a2a897c

Browse files
magp-nordicmasz-nordic
authored andcommitted
drivers: mspi: add pin assignments checks
Add checking pin assignment from DTS to make sure that no CS pin overlaps with any data pin and that there are enough pins defined for selected mode. Signed-off-by: Magdalena Pastula <[email protected]>
1 parent 903b1f9 commit a2a897c

File tree

2 files changed

+139
-9
lines changed

2 files changed

+139
-9
lines changed

drivers/mspi/mspi_nrfe.c

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ LOG_MODULE_REGISTER(mspi_nrfe, CONFIG_MSPI_LOG_LEVEL);
2929
#define EXTREME_DRIVE_FREQ_THRESHOLD 32000000
3030
#define CNT0_TOP_CALCULATE(freq) (NRFX_CEIL_DIV(SystemCoreClock, freq * 2) - 1)
3131

32+
#ifdef CONFIG_SOC_NRF54L15
33+
34+
#define NRFE_MSPI_PORT_NUMBER 2 /* Physical port number */
35+
#define NRFE_MSPI_SCK_PIN_NUMBER 1 /* Physical pin number on port 2 */
36+
37+
#define NRFE_MSPI_DATA_LINE_CNT_MAX 8
38+
#else
39+
#error "Unsupported SoC for SDP MSPI"
40+
#endif
41+
3242
#define SDP_MPSI_PINCTRL_DEV_CONFIG_INIT(node_id) \
3343
{ \
3444
.reg = PINCTRL_REG_NONE, \
@@ -310,6 +320,75 @@ static int send_data(nrfe_mspi_opcode_t opcode, const void *data, size_t len)
310320
return rc;
311321
}
312322

323+
static int check_pin_assignments(const struct pinctrl_state *state)
324+
{
325+
uint8_t data_pins[NRFE_MSPI_DATA_LINE_CNT_MAX];
326+
uint8_t data_pins_cnt = 0;
327+
uint8_t cs_pins[NRFE_MSPI_PINS_MAX];
328+
uint8_t cs_pins_cnt = 0;
329+
uint32_t psel = 0;
330+
331+
for (uint8_t i = 0; i < state->pin_cnt; i++) {
332+
psel = NRF_GET_PIN(state->pins[i]);
333+
if (NRF_PIN_NUMBER_TO_PORT(psel) != NRFE_MSPI_PORT_NUMBER) {
334+
LOG_ERR("Wrong port number. Only %d port is supported.",
335+
NRFE_MSPI_PORT_NUMBER);
336+
return -ENOTSUP;
337+
}
338+
switch (NRF_GET_FUN(state->pins[i])) {
339+
case NRF_FUN_SDP_MSPI_DQ0:
340+
case NRF_FUN_SDP_MSPI_DQ1:
341+
case NRF_FUN_SDP_MSPI_DQ2:
342+
case NRF_FUN_SDP_MSPI_DQ3:
343+
case NRF_FUN_SDP_MSPI_DQ4:
344+
case NRF_FUN_SDP_MSPI_DQ5:
345+
case NRF_FUN_SDP_MSPI_DQ6:
346+
case NRF_FUN_SDP_MSPI_DQ7:
347+
data_pins[data_pins_cnt] = NRF_PIN_NUMBER_TO_PIN(psel);
348+
data_pins_cnt++;
349+
break;
350+
case NRF_FUN_SDP_MSPI_CS0:
351+
case NRF_FUN_SDP_MSPI_CS1:
352+
case NRF_FUN_SDP_MSPI_CS2:
353+
case NRF_FUN_SDP_MSPI_CS3:
354+
case NRF_FUN_SDP_MSPI_CS4:
355+
cs_pins[cs_pins_cnt] = NRF_PIN_NUMBER_TO_PIN(psel);
356+
cs_pins_cnt++;
357+
break;
358+
case NRF_FUN_SDP_MSPI_SCK:
359+
if (NRF_PIN_NUMBER_TO_PIN(psel) != NRFE_MSPI_SCK_PIN_NUMBER) {
360+
LOG_ERR("Clock signal only supported on pin %d.%d",
361+
NRFE_MSPI_PORT_NUMBER, NRFE_MSPI_SCK_PIN_NUMBER);
362+
return -ENOTSUP;
363+
}
364+
break;
365+
default:
366+
LOG_ERR("Not supported pin function: %d", NRF_GET_FUN(state->pins[i]));
367+
return -ENOTSUP;
368+
}
369+
}
370+
371+
if (cs_pins_cnt == 0) {
372+
LOG_ERR("No CS pin defined.");
373+
return -EINVAL;
374+
}
375+
376+
for (uint8_t i = 0; i < cs_pins_cnt; i++) {
377+
for (uint8_t j = 0; j < data_pins_cnt; j++) {
378+
if (cs_pins[i] == data_pins[j]) {
379+
LOG_ERR("CS pin cannot be the same as any data line pin.");
380+
return -EINVAL;
381+
}
382+
}
383+
if (cs_pins[i] == NRFE_MSPI_SCK_PIN_NUMBER) {
384+
LOG_ERR("CS pin cannot be the same CLK pin.");
385+
return -EINVAL;
386+
}
387+
}
388+
389+
return 0;
390+
}
391+
313392
/**
314393
* @brief Configures the MSPI controller based on the provided spec.
315394
*
@@ -326,6 +405,7 @@ static int api_config(const struct mspi_dt_spec *spec)
326405
const struct mspi_cfg *config = &spec->config;
327406
const struct mspi_nrfe_config *drv_cfg = spec->bus->config;
328407
nrfe_mspi_pinctrl_soc_pin_msg_t mspi_pin_config;
408+
int ret;
329409

330410
if (config->op_mode != MSPI_OP_MODE_CONTROLLER) {
331411
LOG_ERR("Only MSPI controller mode is supported.");
@@ -361,6 +441,12 @@ static int api_config(const struct mspi_dt_spec *spec)
361441
return -ENOTSUP;
362442
}
363443

444+
ret = check_pin_assignments(&drv_cfg->pcfg->states[state_id]);
445+
446+
if (ret < 0) {
447+
return ret;
448+
}
449+
364450
for (uint8_t i = 0; i < drv_cfg->pcfg->states[state_id].pin_cnt; i++) {
365451
mspi_pin_config.pin[i] = drv_cfg->pcfg->states[state_id].pins[i];
366452
}
@@ -387,6 +473,54 @@ static int check_io_mode(enum mspi_io_mode io_mode)
387473
return 0;
388474
}
389475

476+
static int check_pins_for_io_mode(const struct pinctrl_state *state, enum mspi_io_mode io_mode)
477+
{
478+
bool d0_defined = false;
479+
bool d1_defined = false;
480+
uint8_t data_pins_cnt = 0;
481+
482+
switch (io_mode) {
483+
case MSPI_IO_MODE_SINGLE: {
484+
for (uint8_t i = 0; i < state->pin_cnt; i++) {
485+
if (NRF_GET_FUN(state->pins[i]) == NRF_FUN_SDP_MSPI_DQ0) {
486+
d0_defined = true;
487+
} else if (NRF_GET_FUN(state->pins[i]) == NRF_FUN_SDP_MSPI_DQ1) {
488+
d1_defined = true;
489+
}
490+
}
491+
if (!d0_defined || !d1_defined) {
492+
LOG_ERR("IO SINGLE mode requires definitions of D0 and D1 pins.");
493+
return -EINVAL;
494+
}
495+
break;
496+
}
497+
case MSPI_IO_MODE_QUAD:
498+
case MSPI_IO_MODE_QUAD_1_1_4:
499+
case MSPI_IO_MODE_QUAD_1_4_4: {
500+
for (uint8_t i = 0; i < state->pin_cnt; i++) {
501+
switch (NRF_GET_FUN(state->pins[i])) {
502+
case NRF_FUN_SDP_MSPI_DQ0:
503+
case NRF_FUN_SDP_MSPI_DQ1:
504+
case NRF_FUN_SDP_MSPI_DQ2:
505+
case NRF_FUN_SDP_MSPI_DQ3:
506+
data_pins_cnt++;
507+
break;
508+
default:
509+
break;
510+
}
511+
}
512+
if (data_pins_cnt < 4) {
513+
LOG_ERR("Not enough data pins for QUAD mode: %d", data_pins_cnt);
514+
return -EINVAL;
515+
}
516+
break;
517+
}
518+
default:
519+
break;
520+
}
521+
return 0;
522+
}
523+
390524
/**
391525
* @brief Configure a device on the MSPI bus.
392526
*
@@ -458,6 +592,11 @@ static int api_dev_config(const struct device *dev, const struct mspi_dev_id *de
458592
if (rc < 0) {
459593
return rc;
460594
}
595+
rc = check_pins_for_io_mode(&drv_cfg->pcfg->states[PINCTRL_STATE_DEFAULT],
596+
cfg->io_mode);
597+
if (rc < 0) {
598+
return rc;
599+
}
461600
}
462601

463602
if (param_mask & MSPI_DEVICE_CONFIG_DATA_RATE) {

include/drivers/mspi/nrfe_mspi.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,7 @@ extern "C" {
1616
#endif
1717

1818
#ifdef CONFIG_SOC_NRF54L15
19-
20-
#define NRFE_MSPI_PORT_NUMBER 2 /* Physical port number */
21-
#define NRFE_MSPI_SCK_PIN_NUMBER 1 /* Physical pins number on port 2 */
22-
#define NRFE_MSPI_DQ0_PIN_NUMBER 2
23-
#define NRFE_MSPI_DQ1_PIN_NUMBER 4
24-
#define NRFE_MSPI_DQ2_PIN_NUMBER 3
25-
#define NRFE_MSPI_DQ3_PIN_NUMBER 0
26-
#define NRFE_MSPI_CS0_PIN_NUMBER 5
2719
#define NRFE_MSPI_PINS_MAX 6
28-
2920
#else
3021
#error "Unsupported SoC for SDP MSPI"
3122
#endif

0 commit comments

Comments
 (0)