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