Skip to content

Commit 793e2c1

Browse files
Delsiangalak
authored andcommitted
drivers: flash: at45: Add Reset and WP pins
Adding Reset and Write-protect pins initialization during AT45 driver start-up. Usually these pins are driven high when not used. The AT45 device incorporates an internal power-on reset circuit, so there is no initial on-off reset sequence. Signed-off-by: Eug Krashtan <[email protected]>
1 parent 93bf5f5 commit 793e2c1

File tree

2 files changed

+97
-2
lines changed

2 files changed

+97
-2
lines changed

drivers/flash/spi_flash_at45.c

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
LOG_MODULE_REGISTER(spi_flash_at45, CONFIG_FLASH_LOG_LEVEL);
1313

14+
#define DT_DRV_COMPAT atmel_at45
15+
1416
/* AT45 commands used by this driver: */
1517
/* - Continuous Array Read (Low Power Mode) */
1618
#define CMD_READ 0x01
@@ -42,6 +44,11 @@ LOG_MODULE_REGISTER(spi_flash_at45, CONFIG_FLASH_LOG_LEVEL);
4244
#define STATUS_REG_LSB_RDY_BUSY_BIT 0x80
4345
#define STATUS_REG_LSB_PAGE_SIZE_BIT 0x01
4446

47+
#define INST_HAS_WP_OR(inst) DT_INST_NODE_HAS_PROP(inst, wp_gpios) ||
48+
#define ANY_INST_HAS_WP_GPIOS DT_INST_FOREACH_STATUS_OKAY(INST_HAS_WP_OR) 0
49+
50+
#define INST_HAS_RESET_OR(inst) DT_INST_NODE_HAS_PROP(inst, reset_gpios) ||
51+
#define ANY_INST_HAS_RESET_GPIOS DT_INST_FOREACH_STATUS_OKAY(INST_HAS_RESET_OR) 0
4552

4653
#define DEF_BUF_SET(_name, _buf_array) \
4754
const struct spi_buf_set _name = { \
@@ -64,6 +71,12 @@ struct spi_flash_at45_config {
6471
const char *cs_gpio;
6572
gpio_pin_t cs_pin;
6673
gpio_dt_flags_t cs_dt_flags;
74+
#if ANY_INST_HAS_RESET_GPIOS
75+
const struct gpio_dt_spec *reset;
76+
#endif
77+
#if ANY_INST_HAS_WP_GPIOS
78+
const struct gpio_dt_spec *wp;
79+
#endif
6780
#if IS_ENABLED(CONFIG_FLASH_PAGE_LAYOUT)
6881
struct flash_pages_layout pages_layout;
6982
#endif
@@ -340,6 +353,12 @@ static int spi_flash_at45_write(const struct device *dev, off_t offset,
340353

341354
acquire(dev);
342355

356+
#if ANY_INST_HAS_WP_GPIOS
357+
if (cfg->wp) {
358+
gpio_pin_set(cfg->wp->port, cfg->wp->pin, 0);
359+
}
360+
#endif
361+
343362
while (len) {
344363
size_t chunk_len = len;
345364
off_t current_page_start =
@@ -360,6 +379,12 @@ static int spi_flash_at45_write(const struct device *dev, off_t offset,
360379
len -= chunk_len;
361380
}
362381

382+
#if ANY_INST_HAS_WP_GPIOS
383+
if (cfg->wp) {
384+
gpio_pin_set(cfg->wp->port, cfg->wp->pin, 1);
385+
}
386+
#endif
387+
363388
release(dev);
364389

365390
return err;
@@ -446,6 +471,12 @@ static int spi_flash_at45_erase(const struct device *dev, off_t offset,
446471

447472
acquire(dev);
448473

474+
#if ANY_INST_HAS_WP_GPIOS
475+
if (cfg->wp) {
476+
gpio_pin_set(cfg->wp->port, cfg->wp->pin, 0);
477+
}
478+
#endif
479+
449480
if (size == cfg->chip_size) {
450481
err = perform_chip_erase(dev);
451482
} else {
@@ -481,6 +512,12 @@ static int spi_flash_at45_erase(const struct device *dev, off_t offset,
481512
}
482513
}
483514

515+
#if ANY_INST_HAS_WP_GPIOS
516+
if (cfg->wp) {
517+
gpio_pin_set(cfg->wp->port, cfg->wp->pin, 1);
518+
}
519+
#endif
520+
484521
release(dev);
485522

486523
return err;
@@ -534,6 +571,28 @@ static int spi_flash_at45_init(const struct device *dev)
534571
return -ENODEV;
535572
}
536573

574+
#if ANY_INST_HAS_RESET_GPIOS
575+
if (dev_config->reset) {
576+
if (gpio_pin_configure_dt(dev_config->reset,
577+
GPIO_OUTPUT_ACTIVE)) {
578+
LOG_ERR("Couldn't configure reset pin");
579+
return -ENODEV;
580+
}
581+
gpio_pin_set(dev_config->reset->port, dev_config->reset->pin, 0);
582+
}
583+
#endif
584+
585+
#if ANY_INST_HAS_WP_GPIOS
586+
if (dev_config->wp) {
587+
if (gpio_pin_configure_dt(dev_config->wp,
588+
GPIO_OUTPUT_ACTIVE)) {
589+
LOG_ERR("Couldn't configure write protect pin");
590+
return -ENODEV;
591+
}
592+
gpio_pin_set(dev_config->wp->port, dev_config->wp->pin, 1);
593+
}
594+
#endif
595+
537596
if (dev_config->cs_gpio) {
538597
dev_data->spi_cs.gpio_dev =
539598
device_get_binding(dev_config->cs_gpio);
@@ -636,7 +695,21 @@ static const struct flash_driver_api spi_flash_at45_api = {
636695
#endif
637696
};
638697

639-
#define DT_DRV_COMPAT atmel_at45
698+
#define INST_HAS_RESET_GPIO(idx) \
699+
DT_NODE_HAS_PROP(DT_DRV_INST(idx), reset_gpios)
700+
701+
#define INST_RESET_GPIO_SPEC(idx) \
702+
IF_ENABLED(INST_HAS_RESET_GPIO(idx), \
703+
(static const struct gpio_dt_spec reset_##idx = \
704+
GPIO_DT_SPEC_GET(DT_DRV_INST(idx), reset_gpios);))
705+
706+
#define INST_HAS_WP_GPIO(idx) \
707+
DT_NODE_HAS_PROP(DT_DRV_INST(idx), wp_gpios)
708+
709+
#define INST_WP_GPIO_SPEC(idx) \
710+
IF_ENABLED(INST_HAS_WP_GPIO(idx), \
711+
(static const struct gpio_dt_spec wp_##idx = \
712+
GPIO_DT_SPEC_GET(DT_DRV_INST(idx), wp_gpios);))
640713

641714
#define SPI_FLASH_AT45_INST(idx) \
642715
enum { \
@@ -648,7 +721,9 @@ static const struct flash_driver_api spi_flash_at45_api = {
648721
.lock = Z_SEM_INITIALIZER(inst_##idx##_data.lock, 1, 1), \
649722
IF_ENABLED(CONFIG_PM_DEVICE, ( \
650723
.pm_state = PM_DEVICE_ACTIVE_STATE)) \
651-
}; \
724+
}; \
725+
INST_RESET_GPIO_SPEC(idx) \
726+
INST_WP_GPIO_SPEC(idx) \
652727
static const struct spi_flash_at45_config inst_##idx##_config = { \
653728
.spi_bus = DT_INST_BUS_LABEL(idx), \
654729
.spi_cfg = { \
@@ -662,6 +737,10 @@ static const struct flash_driver_api spi_flash_at45_api = {
662737
.cs_gpio = DT_INST_SPI_DEV_CS_GPIOS_LABEL(idx), \
663738
.cs_pin = DT_INST_SPI_DEV_CS_GPIOS_PIN(idx), \
664739
.cs_dt_flags = DT_INST_SPI_DEV_CS_GPIOS_FLAGS(idx),)) \
740+
IF_ENABLED(INST_HAS_RESET_GPIO(idx), \
741+
(.reset = &reset_##idx,)) \
742+
IF_ENABLED(INST_HAS_WP_GPIO(idx), \
743+
(.wp = &wp_##idx,)) \
665744
IF_ENABLED(CONFIG_FLASH_PAGE_LAYOUT, ( \
666745
.pages_layout = { \
667746
.pages_count = INST_##idx##_PAGES, \

dts/bindings/mtd/atmel,at45.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,19 @@ properties:
6262
Time, in nanoseconds, needed by the chip to exit from the Deep Power-Down
6363
mode (or Ultra-Deep Power-Down mode when the "use-udpd" property is set)
6464
after the corresponding command is issued.
65+
66+
reset-gpios:
67+
type: phandle-array
68+
required: false
69+
description: |
70+
The RESET pin of AT45 is active low.
71+
If connected directly the MCU pin should be configured
72+
as active low.
73+
74+
wp-gpios:
75+
type: phandle-array
76+
required: false
77+
description: |
78+
The WP pin of AT45 is active low.
79+
If connected directly the MCU pin should be configured
80+
as active low.

0 commit comments

Comments
 (0)