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