Lines Matching +full:standby +full:- +full:gpios

2  * Copyright (c) 2018 Savoir-Faire Linux.
8 * SPDX-License-Identifier: Apache-2.0
35 * * When CSn is deasserted the device enters a standby mode.
36 * * Some devices support a Deep Power-Down mode which reduces current
37 * to as little as 0.1% of standby.
40 * * PM_DEVICE_STATE_ACTIVE covers both active and standby modes;
41 * * PM_DEVICE_STATE_SUSPENDED corresponds to deep-power-down mode;
63 #define DEV_CFG(_dev_) ((const struct spi_nor_config * const) (_dev_)->config)
66 /* MXICY Low-power/high perf mode is second bit in configuration register 2 */
72 /* Build-time data associated with the device. */
92 /* Expected JEDEC ID, from jedec-id property */
96 /* Optional support for entering 32-bit address mode. */
101 /* Length of BFP structure, in 32-bit words. */
105 * (little-endian stored words), from sfdp-bfp property
118 /* The write-protect GPIO (wp-gpios) */
123 /* The hold GPIO (hold-gpios) */
145 /* exist flags for dts opt-ins */
156 * struct spi_nor_data - Structure for defining the SPI NOR access
162 /* Low 32-bits of uptime counter at which device last entered
163 * deep power-down.
170 /* If set addressed operations should use 32-bit rather than
171 * 24-bit addresses.
174 * explicitly specifies 24-bit or 32-bit addressing.
226 /* Page writes range from sub-ms to 10ms */
241 if (IS_ENABLED(ANY_INST_USE_4B_ADDR_OPCODES) && DEV_CFG(dev)->use_4b_addr_opcodes) { in dev_erase_types()
246 const struct spi_nor_data *data = dev->data; in dev_erase_types()
248 return data->erase_types; in dev_erase_types()
258 const struct spi_nor_data *data = dev->data; in dev_flash_size()
260 return data->flash_size; in dev_flash_size()
262 const struct spi_nor_config *cfg = dev->config; in dev_flash_size()
264 return cfg->flash_size; in dev_flash_size()
276 const struct spi_nor_data *data = dev->data; in dev_page_size()
278 return data->page_size; in dev_page_size()
287 /* Capture the time at which the device entered deep power-down. */
291 const struct spi_nor_config *const driver_config = dev->config; in record_entered_dpd()
293 if (driver_config->dpd_exist) { in record_entered_dpd()
294 struct spi_nor_data *const driver_data = dev->data; in record_entered_dpd()
296 driver_data->ts_enter_dpd = k_uptime_get_32(); in record_entered_dpd()
309 const struct spi_nor_config *const driver_config = dev->config; in delay_until_exit_dpd_ok()
311 if (driver_config->dpd_exist) { in delay_until_exit_dpd_ok()
312 struct spi_nor_data *const driver_data = dev->data; in delay_until_exit_dpd_ok()
313 int32_t since = (int32_t)(k_uptime_get_32() - driver_data->ts_enter_dpd); in delay_until_exit_dpd_ok()
315 /* If the time is negative the 32-bit counter has wrapped, in delay_until_exit_dpd_ok()
323 since -= driver_config->t_enter_dpd; in delay_until_exit_dpd_ok()
326 since -= driver_config->t_dpdd_ms; in delay_until_exit_dpd_ok()
332 k_sleep(K_MSEC((uint32_t)-since)); in delay_until_exit_dpd_ok()
346 /* Indicates that addressed access uses a 24-bit address regardless of
351 /* Indicates that addressed access uses a 32-bit address regardless of
377 const struct spi_nor_config *const driver_cfg = dev->config; in spi_nor_access()
378 struct spi_nor_data *const driver_data = dev->data; in spi_nor_access()
399 && driver_data->flag_access_32bit)); in spi_nor_access()
427 return spi_write_dt(&driver_cfg->spi, &tx_set); in spi_nor_access()
430 return spi_transceive_dt(&driver_cfg->spi, &tx_set, &rx_set); in spi_nor_access()
509 /* READ_SFDP requires a 24-bit address followed by a single in read_sfdp()
510 * byte for a wait state. This is effected by using 32-bit in read_sfdp()
511 * address by shifting the 24-bit address up 8 bits. in read_sfdp()
522 const struct spi_nor_config *cfg = dev->config; in enter_dpd()
524 if (cfg->dpd_exist) { in enter_dpd()
537 const struct spi_nor_config *cfg = dev->config; in exit_dpd()
539 if (cfg->dpd_exist) { in exit_dpd()
542 if (cfg->dpd_wakeup_sequence_exist) { in exit_dpd()
547 * control CSn so fake it by writing a known-supported in exit_dpd()
548 * single-byte command, hoping that'll hold the assert in exit_dpd()
555 k_sleep(K_MSEC(cfg->t_rdp_ms)); in exit_dpd()
562 if (cfg->dpd_exist) { in exit_dpd()
563 k_sleep(K_MSEC(cfg->t_exit_dpd)); in exit_dpd()
576 const struct spi_nor_config *cfg = dev->config; in acquire_device()
579 struct spi_nor_data *const driver_data = dev->data; in acquire_device()
581 k_sem_take(&driver_data->sem, K_FOREVER); in acquire_device()
584 (void)pm_device_runtime_get(cfg->spi.bus); in acquire_device()
590 const struct spi_nor_config *cfg = dev->config; in release_device()
592 (void)pm_device_runtime_put(cfg->spi.bus); in release_device()
595 struct spi_nor_data *const driver_data = dev->data; in release_device()
597 k_sem_give(&driver_data->sem); in release_device()
609 * @return the non-negative value of the status register, or an error code.
660 * @return the non-negative value of the configuration register, or an error code.
664 const struct spi_nor_config *cfg = dev->config; in mxicy_rdcr()
665 uint16_t cr = -ENOSYS; in mxicy_rdcr()
667 if (cfg->mxicy_mx25r_power_mode_exist) { in mxicy_rdcr()
692 const struct spi_nor_config *cfg = dev->config; in mxicy_wrcr()
693 int ret = -ENOSYS; in mxicy_wrcr()
700 if (cfg->mxicy_mx25r_power_mode_exist) { in mxicy_wrcr()
733 const struct spi_nor_config *cfg = dev->config; in mxicy_configure()
734 int ret = -ENOSYS; in mxicy_configure()
736 if (cfg->mxicy_mx25r_power_mode_exist) { in mxicy_configure()
737 /* Low-power/high perf mode is second bit in configuration register 2 */ in mxicy_configure()
743 const bool use_high_perf = cfg->mxicy_mx25r_power_mode; in mxicy_configure()
793 return -EINVAL; in spi_nor_read()
798 return -EIO; in spi_nor_read()
803 if (IS_ENABLED(ANY_INST_USE_4B_ADDR_OPCODES) && DEV_CFG(dev)->use_4b_addr_opcodes) { in spi_nor_read()
830 return -EIO; in flash_spi_nor_ex_op()
843 ret = -ENOTSUP; in flash_spi_nor_ex_op()
863 return -EINVAL; in spi_nor_write()
868 return -EIO; in spi_nor_write()
883 if (((addr + to_write - 1U) / page_size) in spi_nor_write()
885 to_write = page_size - (addr % page_size); in spi_nor_write()
895 DEV_CFG(dev)->use_4b_addr_opcodes) { in spi_nor_write()
912 size -= to_write; in spi_nor_write()
943 return -EINVAL; in spi_nor_erase()
946 /* address must be sector-aligned */ in spi_nor_erase()
948 return -EINVAL; in spi_nor_erase()
953 return -EINVAL; in spi_nor_erase()
958 return -EIO; in spi_nor_erase()
973 size -= flash_size; in spi_nor_erase()
983 if ((etp->exp != 0) in spi_nor_erase()
984 && SPI_NOR_IS_ALIGNED(addr, etp->exp) in spi_nor_erase()
985 && (size >= BIT(etp->exp)) in spi_nor_erase()
987 || (etp->exp > bet->exp))) { in spi_nor_erase()
993 DEV_CFG(dev)->use_4b_addr_opcodes) { in spi_nor_erase()
994 ret = spi_nor_cmd_addr_write_4b(dev, bet->cmd, addr, NULL, in spi_nor_erase()
997 ret = spi_nor_cmd_addr_write(dev, bet->cmd, addr, NULL, 0); in spi_nor_erase()
999 addr += BIT(bet->exp); in spi_nor_erase()
1000 size -= BIT(bet->exp); in spi_nor_erase()
1004 ret = -EINVAL; in spi_nor_erase()
1034 const struct spi_nor_config *cfg = dev->config; in spi_nor_write_protection_set()
1037 if (DEV_CFG(dev)->wp_gpios_exist && write_protect == false) { in spi_nor_write_protection_set()
1038 gpio_pin_set_dt(&(DEV_CFG(dev)->wp), 0); in spi_nor_write_protection_set()
1045 if (cfg->requires_ulbpr_exist in spi_nor_write_protection_set()
1052 if (DEV_CFG(dev)->wp_gpios_exist && write_protect == true) { in spi_nor_write_protection_set()
1053 gpio_pin_set_dt(&(DEV_CFG(dev)->wp), 1); in spi_nor_write_protection_set()
1066 return -EIO; in spi_nor_sfdp_read()
1086 return -EINVAL; in spi_nor_read_jedec_id()
1090 return -EIO; in spi_nor_read_jedec_id()
1107 * (cleared) if the device is configured for 4-byte (3-byte) addresses
1112 * @param enter_4byte_addr the Enter 4-Byte Addressing bit set from
1116 * @retval -ENOTSUP if 4-byte addressing is supported but not in a way
1119 * @retval 0 if the device is successfully left in 24-bit mode or
1120 * reconfigured to 32-bit mode.
1127 LOG_DBG("Checking enter-4byte-addr %02x", enter_4byte_addr); in spi_nor_set_address_mode()
1137 /* This currently only supports command 0xB7 (Enter 4-Byte in spi_nor_set_address_mode()
1141 return -ENOTSUP; in spi_nor_set_address_mode()
1155 struct spi_nor_data *data = dev->data; in spi_nor_set_address_mode()
1157 data->flag_access_32bit = true; in spi_nor_set_address_mode()
1172 struct spi_nor_data *data = dev->data; in spi_nor_process_bfp()
1173 struct jesd216_erase_type *etp = data->erase_types; in spi_nor_process_bfp()
1176 LOG_INF("%s: %u %ciBy flash", dev->name, in spi_nor_process_bfp()
1184 memset(data->erase_types, 0, sizeof(data->erase_types)); in spi_nor_process_bfp()
1185 for (uint8_t ti = 1; ti <= ARRAY_SIZE(data->erase_types); ++ti) { in spi_nor_process_bfp()
1187 LOG_DBG("Erase %u with %02x", (uint32_t)BIT(etp->exp), etp->cmd); in spi_nor_process_bfp()
1192 data->page_size = jesd216_bfp_page_size(php, bfp); in spi_nor_process_bfp()
1194 data->flash_size = flash_size; in spi_nor_process_bfp()
1198 return -EINVAL; in spi_nor_process_bfp()
1202 LOG_DBG("Page size %u bytes", data->page_size); in spi_nor_process_bfp()
1204 /* If 4-byte addressing is supported, switch to it. */ in spi_nor_process_bfp()
1209 if (IS_ENABLED(ANY_INST_USE_4B_ADDR_OPCODES) && DEV_CFG(dev)->use_4b_addr_opcodes) { in spi_nor_process_bfp()
1210 LOG_DBG("4-byte addressing supported, using it via specific opcodes"); in spi_nor_process_bfp()
1219 LOG_ERR("Unable to enter 4-byte mode: %d\n", rc); in spi_nor_process_bfp()
1231 struct spi_nor_data *dev_data = dev->data; in spi_nor_process_sfdp()
1253 return -EINVAL; in spi_nor_process_sfdp()
1256 LOG_INF("%s: SFDP v %u.%u AP %x with %u PH", dev->name, in spi_nor_process_sfdp()
1257 hp->rev_major, hp->rev_minor, hp->access, 1 + hp->nph); in spi_nor_process_sfdp()
1259 const struct jesd216_param_header *php = hp->phdr; in spi_nor_process_sfdp()
1260 const struct jesd216_param_header *phpe = php + MIN(decl_nph, 1 + hp->nph); in spi_nor_process_sfdp()
1266 (php - hp->phdr), id, php->rev_major, php->rev_minor, in spi_nor_process_sfdp()
1267 php->len_dw, jesd216_param_addr(php)); in spi_nor_process_sfdp()
1271 uint32_t dw[MIN(php->len_dw, 20)]; in spi_nor_process_sfdp()
1289 DEV_CFG(dev)->use_4b_addr_opcodes) { in spi_nor_process_sfdp()
1303 MIN(sizeof(uint32_t) * php->len_dw, sizeof(u2.dw))); in spi_nor_process_sfdp()
1308 struct jesd216_erase_type *etp = &dev_data->erase_types[ei]; in spi_nor_process_sfdp()
1312 etp->exp = 0; in spi_nor_process_sfdp()
1313 etp->cmd = 0; in spi_nor_process_sfdp()
1315 etp->cmd = cmd; in spi_nor_process_sfdp()
1323 LOG_ERR("4-byte addressing not supported"); in spi_nor_process_sfdp()
1324 return -ENOTSUP; in spi_nor_process_sfdp()
1334 const struct spi_nor_config *cfg = dev->config; in spi_nor_process_sfdp()
1336 .len_dw = cfg->bfp_len, in spi_nor_process_sfdp()
1339 rc = spi_nor_process_bfp(dev, &bfp_hdr, cfg->bfp); in spi_nor_process_sfdp()
1351 struct spi_nor_data *data = dev->data; in setup_pages_layout()
1357 for (size_t i = 0; i < ARRAY_SIZE(data->erase_types); ++i) { in setup_pages_layout()
1358 const struct jesd216_erase_type *etp = &data->erase_types[i]; in setup_pages_layout()
1360 if ((etp->cmd != 0) in setup_pages_layout()
1361 && ((exp == 0) || (etp->exp < exp))) { in setup_pages_layout()
1362 exp = etp->exp; in setup_pages_layout()
1367 return -ENOTSUP; in setup_pages_layout()
1378 return -EINVAL; in setup_pages_layout()
1389 data->layout.pages_size = layout_page_size; in setup_pages_layout()
1390 data->layout.pages_count = flash_size / layout_page_size; in setup_pages_layout()
1391 LOG_DBG("layout %u x %u By pages", data->layout.pages_count, data->layout.pages_size); in setup_pages_layout()
1393 const struct spi_nor_config *cfg = dev->config; in setup_pages_layout()
1394 const struct flash_pages_layout *layout = &cfg->layout; in setup_pages_layout()
1396 size_t layout_size = layout->pages_size * layout->pages_count; in setup_pages_layout()
1400 flash_size, layout->pages_count, layout->pages_size); in setup_pages_layout()
1401 return -EINVAL; in setup_pages_layout()
1421 const struct spi_nor_config *cfg = dev->config; in spi_nor_configure()
1426 if (!spi_is_ready_dt(&cfg->spi)) { in spi_nor_configure()
1427 return -ENODEV; in spi_nor_configure()
1432 if (cfg->reset_gpios_exist) { in spi_nor_configure()
1433 if (!gpio_is_ready_dt(&cfg->reset)) { in spi_nor_configure()
1435 return -ENODEV; in spi_nor_configure()
1437 if (gpio_pin_configure_dt(&cfg->reset, GPIO_OUTPUT_ACTIVE)) { in spi_nor_configure()
1439 return -ENODEV; in spi_nor_configure()
1441 rc = gpio_pin_set_dt(&cfg->reset, 0); in spi_nor_configure()
1448 /* After a soft-reset the flash might be in DPD or busy writing/erasing. in spi_nor_configure()
1457 return -ENODEV; in spi_nor_configure()
1468 return -ENODEV; in spi_nor_configure()
1478 return -ENODEV; in spi_nor_configure()
1487 if (memcmp(jedec_id, cfg->jedec_id, sizeof(jedec_id)) != 0) { in spi_nor_configure()
1490 cfg->jedec_id[0], cfg->jedec_id[1], cfg->jedec_id[2]); in spi_nor_configure()
1491 return -EINVAL; in spi_nor_configure()
1500 if (cfg->has_lock != 0) { in spi_nor_configure()
1507 rc = spi_nor_wrsr(dev, rc & ~cfg->has_lock); in spi_nor_configure()
1514 return -ENODEV; in spi_nor_configure()
1522 if (cfg->enter_4byte_addr != 0) { in spi_nor_configure()
1523 rc = spi_nor_set_address_mode(dev, cfg->enter_4byte_addr); in spi_nor_configure()
1526 LOG_ERR("Unable to enter 4-byte mode: %d\n", rc); in spi_nor_configure()
1527 return -ENODEV; in spi_nor_configure()
1538 return -ENODEV; in spi_nor_configure()
1545 return -ENODEV; in spi_nor_configure()
1551 if (cfg->mxicy_mx25r_power_mode_exist) { in spi_nor_configure()
1590 rc = -ENOSYS; in spi_nor_pm_control()
1605 struct spi_nor_data *const driver_data = dev->data; in spi_nor_init()
1607 k_sem_init(&driver_data->sem, 1, K_SEM_MAX_LIMIT); in spi_nor_init()
1611 if (DEV_CFG(dev)->wp_gpios_exist) { in spi_nor_init()
1612 if (!device_is_ready(DEV_CFG(dev)->wp.port)) { in spi_nor_init()
1613 LOG_ERR("Write-protect pin not ready"); in spi_nor_init()
1614 return -ENODEV; in spi_nor_init()
1616 if (gpio_pin_configure_dt(&(DEV_CFG(dev)->wp), GPIO_OUTPUT_ACTIVE)) { in spi_nor_init()
1617 LOG_ERR("Write-protect pin failed to set active"); in spi_nor_init()
1618 return -ENODEV; in spi_nor_init()
1623 if (DEV_CFG(dev)->hold_gpios_exist) { in spi_nor_init()
1624 if (!device_is_ready(DEV_CFG(dev)->hold.port)) { in spi_nor_init()
1626 return -ENODEV; in spi_nor_init()
1628 if (gpio_pin_configure_dt(&(DEV_CFG(dev)->hold), GPIO_OUTPUT_INACTIVE)) { in spi_nor_init()
1630 return -ENODEV; in spi_nor_init()
1646 const struct spi_nor_data *data = dev->data; in spi_nor_pages_layout()
1648 *layout = &data->layout; in spi_nor_pages_layout()
1650 const struct spi_nor_config *cfg = dev->config; in spi_nor_pages_layout()
1652 *layout = &cfg->layout; in spi_nor_pages_layout()
1695 "jedec,spi-nor size required for non-runtime SFDP page layout"); \
1711 "jedec,spi-nor sfdp-bfp required for devicetree SFDP"); \
1716 "jedec,spi-nor jedec-id required for non-runtime SFDP"); \