1 /*
2 * Copyright (c) 2020-2024 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/drivers/flash.h>
8 #include <zephyr/drivers/spi.h>
9 #include <zephyr/pm/device.h>
10 #include <zephyr/sys/byteorder.h>
11 #include <zephyr/logging/log.h>
12
13 LOG_MODULE_REGISTER(spi_flash_at45, CONFIG_FLASH_LOG_LEVEL);
14
15 #define DT_DRV_COMPAT atmel_at45
16
17 /* AT45 commands used by this driver: */
18 /* - Continuous Array Read (Low Power Mode) */
19 #define CMD_READ 0x01
20 /* - Main Memory Byte/Page Program through Buffer 1 without Built-In Erase */
21 #define CMD_WRITE 0x02
22 /* - Read-Modify-Write */
23 #define CMD_MODIFY 0x58
24 /* - Manufacturer and Device ID Read */
25 #define CMD_READ_ID 0x9F
26 /* - Status Register Read */
27 #define CMD_READ_STATUS 0xD7
28 /* - Chip Erase */
29 #define CMD_CHIP_ERASE { 0xC7, 0x94, 0x80, 0x9A }
30 /* - Sector Erase */
31 #define CMD_SECTOR_ERASE 0x7C
32 /* - Block Erase */
33 #define CMD_BLOCK_ERASE 0x50
34 /* - Page Erase */
35 #define CMD_PAGE_ERASE 0x81
36 /* - Deep Power-Down */
37 #define CMD_ENTER_DPD 0xB9
38 /* - Resume from Deep Power-Down */
39 #define CMD_EXIT_DPD 0xAB
40 /* - Ultra-Deep Power-Down */
41 #define CMD_ENTER_UDPD 0x79
42 /* - Buffer and Page Size Configuration, "Power of 2" binary page size */
43 #define CMD_BINARY_PAGE_SIZE { 0x3D, 0x2A, 0x80, 0xA6 }
44
45 #define STATUS_REG_LSB_RDY_BUSY_BIT 0x80
46 #define STATUS_REG_LSB_PAGE_SIZE_BIT 0x01
47
48 #define INST_HAS_WP_OR(inst) DT_INST_NODE_HAS_PROP(inst, wp_gpios) ||
49 #define ANY_INST_HAS_WP_GPIOS DT_INST_FOREACH_STATUS_OKAY(INST_HAS_WP_OR) 0
50
51 #define INST_HAS_RESET_OR(inst) DT_INST_NODE_HAS_PROP(inst, reset_gpios) ||
52 #define ANY_INST_HAS_RESET_GPIOS DT_INST_FOREACH_STATUS_OKAY(INST_HAS_RESET_OR) 0
53
54 #define DEF_BUF_SET(_name, _buf_array) \
55 const struct spi_buf_set _name = { \
56 .buffers = _buf_array, \
57 .count = ARRAY_SIZE(_buf_array), \
58 }
59
60 struct spi_flash_at45_data {
61 struct k_sem lock;
62 };
63
64 struct spi_flash_at45_config {
65 struct spi_dt_spec bus;
66 #if ANY_INST_HAS_RESET_GPIOS
67 const struct gpio_dt_spec *reset;
68 #endif
69 #if ANY_INST_HAS_WP_GPIOS
70 const struct gpio_dt_spec *wp;
71 #endif
72 #if defined(CONFIG_FLASH_PAGE_LAYOUT)
73 struct flash_pages_layout pages_layout;
74 #endif
75 uint32_t chip_size;
76 uint32_t sector_size;
77 uint32_t sector_0a_size;
78 uint16_t block_size;
79 uint16_t page_size;
80 bool no_chip_erase;
81 bool no_sector_erase;
82 uint16_t t_enter_dpd; /* in microseconds */
83 uint16_t t_exit_dpd; /* in microseconds */
84 bool use_udpd;
85 uint8_t jedec_id[3];
86 };
87
88 static const struct flash_parameters flash_at45_parameters = {
89 .write_block_size = 1,
90 .erase_value = 0xff,
91 };
92
acquire(const struct device * dev)93 static void acquire(const struct device *dev)
94 {
95 struct spi_flash_at45_data *data = dev->data;
96
97 k_sem_take(&data->lock, K_FOREVER);
98 }
99
release(const struct device * dev)100 static void release(const struct device *dev)
101 {
102 struct spi_flash_at45_data *data = dev->data;
103
104 k_sem_give(&data->lock);
105 }
106
check_jedec_id(const struct device * dev)107 static int check_jedec_id(const struct device *dev)
108 {
109 const struct spi_flash_at45_config *cfg = dev->config;
110 int err;
111 uint8_t const *expected_id = cfg->jedec_id;
112 uint8_t read_id[sizeof(cfg->jedec_id)];
113 const uint8_t opcode = CMD_READ_ID;
114 const struct spi_buf tx_buf[] = {
115 {
116 .buf = (void *)&opcode,
117 .len = sizeof(opcode),
118 }
119 };
120 const struct spi_buf rx_buf[] = {
121 {
122 .len = sizeof(opcode),
123 },
124 {
125 .buf = read_id,
126 .len = sizeof(read_id),
127 }
128 };
129 DEF_BUF_SET(tx_buf_set, tx_buf);
130 DEF_BUF_SET(rx_buf_set, rx_buf);
131
132 err = spi_transceive_dt(&cfg->bus, &tx_buf_set, &rx_buf_set);
133 if (err != 0) {
134 LOG_ERR("SPI transaction failed with code: %d/%u",
135 err, __LINE__);
136 return -EIO;
137 }
138
139 if (memcmp(expected_id, read_id, sizeof(read_id)) != 0) {
140 LOG_ERR("Wrong JEDEC ID: %02X %02X %02X, "
141 "expected: %02X %02X %02X",
142 read_id[0], read_id[1], read_id[2],
143 expected_id[0], expected_id[1], expected_id[2]);
144 return -ENODEV;
145 }
146
147 return 0;
148 }
149
150 /*
151 * Reads 2-byte Status Register:
152 * - Byte 0 to LSB
153 * - Byte 1 to MSB
154 * of the pointed parameter.
155 */
read_status_register(const struct device * dev,uint16_t * status)156 static int read_status_register(const struct device *dev, uint16_t *status)
157 {
158 const struct spi_flash_at45_config *cfg = dev->config;
159 int err;
160 const uint8_t opcode = CMD_READ_STATUS;
161 const struct spi_buf tx_buf[] = {
162 {
163 .buf = (void *)&opcode,
164 .len = sizeof(opcode),
165 }
166 };
167 const struct spi_buf rx_buf[] = {
168 {
169 .len = sizeof(opcode),
170 },
171 {
172 .buf = status,
173 .len = sizeof(uint16_t),
174 }
175 };
176 DEF_BUF_SET(tx_buf_set, tx_buf);
177 DEF_BUF_SET(rx_buf_set, rx_buf);
178
179 err = spi_transceive_dt(&cfg->bus, &tx_buf_set, &rx_buf_set);
180 if (err != 0) {
181 LOG_ERR("SPI transaction failed with code: %d/%u",
182 err, __LINE__);
183 return -EIO;
184 }
185
186 *status = sys_le16_to_cpu(*status);
187 return 0;
188 }
189
wait_until_ready(const struct device * dev)190 static int wait_until_ready(const struct device *dev)
191 {
192 int err;
193 uint16_t status;
194
195 do {
196 err = read_status_register(dev, &status);
197 } while (err == 0 && !(status & STATUS_REG_LSB_RDY_BUSY_BIT));
198
199 return err;
200 }
201
configure_page_size(const struct device * dev)202 static int configure_page_size(const struct device *dev)
203 {
204 const struct spi_flash_at45_config *cfg = dev->config;
205 int err;
206 uint16_t status;
207 uint8_t const conf_binary_page_size[] = CMD_BINARY_PAGE_SIZE;
208 const struct spi_buf tx_buf[] = {
209 {
210 .buf = (void *)conf_binary_page_size,
211 .len = sizeof(conf_binary_page_size),
212 }
213 };
214 DEF_BUF_SET(tx_buf_set, tx_buf);
215
216 err = read_status_register(dev, &status);
217 if (err != 0) {
218 return err;
219 }
220
221 /* If the device is already configured for "power of 2" binary
222 * page size, there is nothing more to do.
223 */
224 if (status & STATUS_REG_LSB_PAGE_SIZE_BIT) {
225 return 0;
226 }
227
228 err = spi_write_dt(&cfg->bus, &tx_buf_set);
229 if (err != 0) {
230 LOG_ERR("SPI transaction failed with code: %d/%u",
231 err, __LINE__);
232 } else {
233 err = wait_until_ready(dev);
234 }
235
236 return (err != 0) ? -EIO : 0;
237 }
238
is_valid_request(off_t addr,size_t size,size_t chip_size)239 static bool is_valid_request(off_t addr, size_t size, size_t chip_size)
240 {
241 return (addr >= 0 && (addr + size) <= chip_size);
242 }
243
spi_flash_at45_read(const struct device * dev,off_t offset,void * data,size_t len)244 static int spi_flash_at45_read(const struct device *dev, off_t offset,
245 void *data, size_t len)
246 {
247 const struct spi_flash_at45_config *cfg = dev->config;
248 int err;
249
250 if (!is_valid_request(offset, len, cfg->chip_size)) {
251 return -ENODEV;
252 }
253
254 uint8_t const op_and_addr[] = {
255 CMD_READ,
256 (offset >> 16) & 0xFF,
257 (offset >> 8) & 0xFF,
258 (offset >> 0) & 0xFF,
259 };
260 const struct spi_buf tx_buf[] = {
261 {
262 .buf = (void *)&op_and_addr,
263 .len = sizeof(op_and_addr),
264 }
265 };
266 const struct spi_buf rx_buf[] = {
267 {
268 .len = sizeof(op_and_addr),
269 },
270 {
271 .buf = data,
272 .len = len,
273 }
274 };
275 DEF_BUF_SET(tx_buf_set, tx_buf);
276 DEF_BUF_SET(rx_buf_set, rx_buf);
277
278 acquire(dev);
279 err = spi_transceive_dt(&cfg->bus, &tx_buf_set, &rx_buf_set);
280 release(dev);
281
282 if (err != 0) {
283 LOG_ERR("SPI transaction failed with code: %d/%u",
284 err, __LINE__);
285 }
286
287 return (err != 0) ? -EIO : 0;
288 }
289
perform_write(const struct device * dev,off_t offset,const void * data,size_t len)290 static int perform_write(const struct device *dev, off_t offset,
291 const void *data, size_t len)
292 {
293 const struct spi_flash_at45_config *cfg = dev->config;
294 int err;
295 uint8_t const op_and_addr[] = {
296 IS_ENABLED(CONFIG_SPI_FLASH_AT45_USE_READ_MODIFY_WRITE)
297 ? CMD_MODIFY
298 : CMD_WRITE,
299 (offset >> 16) & 0xFF,
300 (offset >> 8) & 0xFF,
301 (offset >> 0) & 0xFF,
302 };
303 const struct spi_buf tx_buf[] = {
304 {
305 .buf = (void *)&op_and_addr,
306 .len = sizeof(op_and_addr),
307 },
308 {
309 .buf = (void *)data,
310 .len = len,
311 }
312 };
313 DEF_BUF_SET(tx_buf_set, tx_buf);
314
315 err = spi_write_dt(&cfg->bus, &tx_buf_set);
316 if (err != 0) {
317 LOG_ERR("SPI transaction failed with code: %d/%u",
318 err, __LINE__);
319 } else {
320 err = wait_until_ready(dev);
321 }
322
323 return (err != 0) ? -EIO : 0;
324 }
325
spi_flash_at45_write(const struct device * dev,off_t offset,const void * data,size_t len)326 static int spi_flash_at45_write(const struct device *dev, off_t offset,
327 const void *data, size_t len)
328 {
329 const struct spi_flash_at45_config *cfg = dev->config;
330 int err = 0;
331
332 if (!is_valid_request(offset, len, cfg->chip_size)) {
333 return -ENODEV;
334 }
335
336 acquire(dev);
337
338 #if ANY_INST_HAS_WP_GPIOS
339 if (cfg->wp) {
340 gpio_pin_set_dt(cfg->wp, 0);
341 }
342 #endif
343
344 while (len) {
345 size_t chunk_len = len;
346 off_t current_page_start =
347 offset - (offset & (cfg->page_size - 1));
348 off_t current_page_end = current_page_start + cfg->page_size;
349
350 if (chunk_len > (current_page_end - offset)) {
351 chunk_len = (current_page_end - offset);
352 }
353
354 err = perform_write(dev, offset, data, chunk_len);
355 if (err != 0) {
356 break;
357 }
358
359 data = (uint8_t *)data + chunk_len;
360 offset += chunk_len;
361 len -= chunk_len;
362 }
363
364 #if ANY_INST_HAS_WP_GPIOS
365 if (cfg->wp) {
366 gpio_pin_set_dt(cfg->wp, 1);
367 }
368 #endif
369
370 release(dev);
371
372 return err;
373 }
374
perform_chip_erase(const struct device * dev)375 static int perform_chip_erase(const struct device *dev)
376 {
377 const struct spi_flash_at45_config *cfg = dev->config;
378 int err;
379 uint8_t const chip_erase_cmd[] = CMD_CHIP_ERASE;
380 const struct spi_buf tx_buf[] = {
381 {
382 .buf = (void *)&chip_erase_cmd,
383 .len = sizeof(chip_erase_cmd),
384 }
385 };
386 DEF_BUF_SET(tx_buf_set, tx_buf);
387
388 err = spi_write_dt(&cfg->bus, &tx_buf_set);
389 if (err != 0) {
390 LOG_ERR("SPI transaction failed with code: %d/%u",
391 err, __LINE__);
392 } else {
393 err = wait_until_ready(dev);
394 }
395
396 return (err != 0) ? -EIO : 0;
397 }
398
is_erase_possible(size_t entity_size,off_t offset,size_t requested_size)399 static bool is_erase_possible(size_t entity_size,
400 off_t offset, size_t requested_size)
401 {
402 return (requested_size >= entity_size &&
403 (offset & (entity_size - 1)) == 0);
404 }
405
perform_erase_op(const struct device * dev,uint8_t opcode,off_t offset)406 static int perform_erase_op(const struct device *dev, uint8_t opcode,
407 off_t offset)
408 {
409 const struct spi_flash_at45_config *cfg = dev->config;
410 int err;
411 uint8_t const op_and_addr[] = {
412 opcode,
413 (offset >> 16) & 0xFF,
414 (offset >> 8) & 0xFF,
415 (offset >> 0) & 0xFF,
416 };
417 const struct spi_buf tx_buf[] = {
418 {
419 .buf = (void *)&op_and_addr,
420 .len = sizeof(op_and_addr),
421 }
422 };
423 DEF_BUF_SET(tx_buf_set, tx_buf);
424
425 err = spi_write_dt(&cfg->bus, &tx_buf_set);
426 if (err != 0) {
427 LOG_ERR("SPI transaction failed with code: %d/%u",
428 err, __LINE__);
429 } else {
430 err = wait_until_ready(dev);
431 }
432
433 return (err != 0) ? -EIO : 0;
434 }
435
spi_flash_at45_erase(const struct device * dev,off_t offset,size_t size)436 static int spi_flash_at45_erase(const struct device *dev, off_t offset,
437 size_t size)
438 {
439 const struct spi_flash_at45_config *cfg = dev->config;
440 int err = 0;
441
442 if (!is_valid_request(offset, size, cfg->chip_size)) {
443 return -ENODEV;
444 }
445
446 /* Diagnose region errors before starting to erase. */
447 if (((offset % cfg->page_size) != 0)
448 || ((size % cfg->page_size) != 0)) {
449 return -EINVAL;
450 }
451
452 acquire(dev);
453
454 #if ANY_INST_HAS_WP_GPIOS
455 if (cfg->wp) {
456 gpio_pin_set_dt(cfg->wp, 0);
457 }
458 #endif
459
460 if (!cfg->no_chip_erase && size == cfg->chip_size) {
461 err = perform_chip_erase(dev);
462 } else {
463 while (size) {
464 size_t sector_size = cfg->sector_size;
465
466 if (cfg->sector_0a_size) {
467 if (offset < cfg->sector_0a_size) {
468 sector_size = cfg->sector_0a_size;
469 } else if (offset < cfg->sector_size) {
470 /* Sector 0b. Calculate its size. */
471 sector_size -= cfg->sector_0a_size;
472 }
473 }
474
475 if (!cfg->no_sector_erase &&
476 is_erase_possible(sector_size,
477 offset, size)) {
478 err = perform_erase_op(dev, CMD_SECTOR_ERASE,
479 offset);
480 offset += sector_size;
481 size -= sector_size;
482 } else if (is_erase_possible(cfg->block_size,
483 offset, size)) {
484 err = perform_erase_op(dev, CMD_BLOCK_ERASE,
485 offset);
486 offset += cfg->block_size;
487 size -= cfg->block_size;
488 } else if (is_erase_possible(cfg->page_size,
489 offset, size)) {
490 err = perform_erase_op(dev, CMD_PAGE_ERASE,
491 offset);
492 offset += cfg->page_size;
493 size -= cfg->page_size;
494 } else {
495 LOG_ERR("Unsupported erase request: "
496 "size %zu at 0x%lx",
497 size, (long)offset);
498 err = -EINVAL;
499 }
500
501 if (err != 0) {
502 break;
503 }
504 }
505 }
506
507 #if ANY_INST_HAS_WP_GPIOS
508 if (cfg->wp) {
509 gpio_pin_set_dt(cfg->wp, 1);
510 }
511 #endif
512
513 release(dev);
514
515 return err;
516 }
517
518 #if defined(CONFIG_FLASH_PAGE_LAYOUT)
spi_flash_at45_pages_layout(const struct device * dev,const struct flash_pages_layout ** layout,size_t * layout_size)519 static void spi_flash_at45_pages_layout(const struct device *dev,
520 const struct flash_pages_layout **layout,
521 size_t *layout_size)
522 {
523 const struct spi_flash_at45_config *cfg = dev->config;
524
525 *layout = &cfg->pages_layout;
526 *layout_size = 1;
527 }
528 #endif /* defined(CONFIG_FLASH_PAGE_LAYOUT) */
529
power_down_op(const struct device * dev,uint8_t opcode,uint32_t delay)530 static int power_down_op(const struct device *dev, uint8_t opcode,
531 uint32_t delay)
532 {
533 const struct spi_flash_at45_config *cfg = dev->config;
534 int err = 0;
535 const struct spi_buf tx_buf[] = {
536 {
537 .buf = (void *)&opcode,
538 .len = sizeof(opcode),
539 }
540 };
541 DEF_BUF_SET(tx_buf_set, tx_buf);
542
543 err = spi_write_dt(&cfg->bus, &tx_buf_set);
544 if (err != 0) {
545 LOG_ERR("SPI transaction failed with code: %d/%u",
546 err, __LINE__);
547 return -EIO;
548 }
549
550
551 k_busy_wait(delay);
552 return 0;
553 }
554
spi_flash_at45_init(const struct device * dev)555 static int spi_flash_at45_init(const struct device *dev)
556 {
557 const struct spi_flash_at45_config *dev_config = dev->config;
558 int err;
559
560 if (!spi_is_ready_dt(&dev_config->bus)) {
561 LOG_ERR("SPI bus %s not ready", dev_config->bus.bus->name);
562 return -ENODEV;
563 }
564
565 #if ANY_INST_HAS_RESET_GPIOS
566 if (dev_config->reset) {
567 if (!device_is_ready(dev_config->reset->port)) {
568 LOG_ERR("Reset pin not ready");
569 return -ENODEV;
570 }
571 if (gpio_pin_configure_dt(dev_config->reset, GPIO_OUTPUT_ACTIVE)) {
572 LOG_ERR("Couldn't configure reset pin");
573 return -ENODEV;
574 }
575 gpio_pin_set_dt(dev_config->reset, 0);
576 }
577 #endif
578
579 #if ANY_INST_HAS_WP_GPIOS
580 if (dev_config->wp) {
581 if (!device_is_ready(dev_config->wp->port)) {
582 LOG_ERR("Write protect pin not ready");
583 return -ENODEV;
584 }
585 if (gpio_pin_configure_dt(dev_config->wp, GPIO_OUTPUT_ACTIVE)) {
586 LOG_ERR("Couldn't configure write protect pin");
587 return -ENODEV;
588 }
589 }
590 #endif
591
592 acquire(dev);
593
594 /* Just in case the chip was in the Deep (or Ultra-Deep) Power-Down
595 * mode, issue the command to bring it back to normal operation.
596 * Exiting from the Ultra-Deep mode requires only that the CS line
597 * is asserted for a certain time, so issuing the Resume from Deep
598 * Power-Down command will work in both cases.
599 */
600 power_down_op(dev, CMD_EXIT_DPD, dev_config->t_exit_dpd);
601
602 err = check_jedec_id(dev);
603 if (err == 0) {
604 err = configure_page_size(dev);
605 }
606
607 release(dev);
608
609 return err;
610 }
611
612 #if defined(CONFIG_PM_DEVICE)
spi_flash_at45_pm_action(const struct device * dev,enum pm_device_action action)613 static int spi_flash_at45_pm_action(const struct device *dev,
614 enum pm_device_action action)
615 {
616 const struct spi_flash_at45_config *dev_config = dev->config;
617
618 switch (action) {
619 case PM_DEVICE_ACTION_RESUME:
620 acquire(dev);
621 power_down_op(dev, CMD_EXIT_DPD, dev_config->t_exit_dpd);
622 release(dev);
623 break;
624
625 case PM_DEVICE_ACTION_SUSPEND:
626 acquire(dev);
627 power_down_op(dev,
628 dev_config->use_udpd ? CMD_ENTER_UDPD : CMD_ENTER_DPD,
629 dev_config->t_enter_dpd);
630 release(dev);
631 break;
632
633 default:
634 return -ENOTSUP;
635 }
636
637 return 0;
638 }
639 #endif /* defined(CONFIG_PM_DEVICE) */
640
641 static const struct flash_parameters *
flash_at45_get_parameters(const struct device * dev)642 flash_at45_get_parameters(const struct device *dev)
643 {
644 ARG_UNUSED(dev);
645
646 return &flash_at45_parameters;
647 }
648
spi_flash_at45_get_size(const struct device * dev,uint64_t * size)649 static int spi_flash_at45_get_size(const struct device *dev, uint64_t *size)
650 {
651 const struct spi_flash_at45_config *cfg = dev->config;
652
653 *size = (uint64_t)cfg->chip_size;
654
655 return 0;
656 }
657
658 static DEVICE_API(flash, spi_flash_at45_api) = {
659 .read = spi_flash_at45_read,
660 .write = spi_flash_at45_write,
661 .erase = spi_flash_at45_erase,
662 .get_parameters = flash_at45_get_parameters,
663 .get_size = spi_flash_at45_get_size,
664 #if defined(CONFIG_FLASH_PAGE_LAYOUT)
665 .page_layout = spi_flash_at45_pages_layout,
666 #endif
667 };
668
669 #define INST_HAS_RESET_GPIO(idx) \
670 DT_INST_NODE_HAS_PROP(idx, reset_gpios)
671
672 #define INST_RESET_GPIO_SPEC(idx) \
673 IF_ENABLED(INST_HAS_RESET_GPIO(idx), \
674 (static const struct gpio_dt_spec reset_##idx = \
675 GPIO_DT_SPEC_INST_GET(idx, reset_gpios);))
676
677 #define INST_HAS_WP_GPIO(idx) \
678 DT_INST_NODE_HAS_PROP(idx, wp_gpios)
679
680 #define INST_WP_GPIO_SPEC(idx) \
681 IF_ENABLED(INST_HAS_WP_GPIO(idx), \
682 (static const struct gpio_dt_spec wp_##idx = \
683 GPIO_DT_SPEC_INST_GET(idx, wp_gpios);))
684
685 #define SPI_FLASH_AT45_INST(idx) \
686 enum { \
687 INST_##idx##_BYTES = (DT_INST_PROP(idx, size) / 8), \
688 INST_##idx##_PAGES = (INST_##idx##_BYTES / \
689 DT_INST_PROP(idx, page_size)), \
690 }; \
691 static struct spi_flash_at45_data inst_##idx##_data = { \
692 .lock = Z_SEM_INITIALIZER(inst_##idx##_data.lock, 1, 1), \
693 }; \
694 INST_RESET_GPIO_SPEC(idx) \
695 INST_WP_GPIO_SPEC(idx) \
696 static const struct spi_flash_at45_config inst_##idx##_config = { \
697 .bus = SPI_DT_SPEC_INST_GET( \
698 idx, SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | \
699 SPI_WORD_SET(8), 0), \
700 IF_ENABLED(INST_HAS_RESET_GPIO(idx), \
701 (.reset = &reset_##idx,)) \
702 IF_ENABLED(INST_HAS_WP_GPIO(idx), \
703 (.wp = &wp_##idx,)) \
704 IF_ENABLED(CONFIG_FLASH_PAGE_LAYOUT, ( \
705 .pages_layout = { \
706 .pages_count = INST_##idx##_PAGES, \
707 .pages_size = DT_INST_PROP(idx, page_size), \
708 },)) \
709 .chip_size = INST_##idx##_BYTES, \
710 .sector_size = DT_INST_PROP(idx, sector_size), \
711 .sector_0a_size = DT_INST_PROP(idx, sector_0a_pages) \
712 * DT_INST_PROP(idx, page_size), \
713 .block_size = DT_INST_PROP(idx, block_size), \
714 .page_size = DT_INST_PROP(idx, page_size), \
715 .no_chip_erase = DT_INST_PROP(idx, no_chip_erase), \
716 .no_sector_erase = DT_INST_PROP(idx, no_sector_erase), \
717 .t_enter_dpd = DIV_ROUND_UP( \
718 DT_INST_PROP(idx, enter_dpd_delay), \
719 NSEC_PER_USEC), \
720 .t_exit_dpd = DIV_ROUND_UP( \
721 DT_INST_PROP(idx, exit_dpd_delay), \
722 NSEC_PER_USEC), \
723 .use_udpd = DT_INST_PROP(idx, use_udpd), \
724 .jedec_id = DT_INST_PROP(idx, jedec_id), \
725 }; \
726 IF_ENABLED(CONFIG_FLASH_PAGE_LAYOUT, ( \
727 BUILD_ASSERT( \
728 (INST_##idx##_PAGES * DT_INST_PROP(idx, page_size)) \
729 == INST_##idx##_BYTES, \
730 "Page size specified for instance " #idx " of " \
731 "atmel,at45 is not compatible with its " \
732 "total size");)) \
733 \
734 PM_DEVICE_DT_INST_DEFINE(idx, spi_flash_at45_pm_action); \
735 \
736 DEVICE_DT_INST_DEFINE(idx, \
737 spi_flash_at45_init, PM_DEVICE_DT_INST_GET(idx), \
738 &inst_##idx##_data, &inst_##idx##_config, \
739 POST_KERNEL, CONFIG_SPI_FLASH_AT45_INIT_PRIORITY, \
740 &spi_flash_at45_api);
741
742 DT_INST_FOREACH_STATUS_OKAY(SPI_FLASH_AT45_INST)
743