/** * @brief Hardware de-initialization * * The function will restore original pinshare value and deactivate GPIO pins. * * @param dev pointer to structure of device data * @return 0 on success, negative errno on error */ static int tsb_spi_hw_deinit(struct device *dev) { struct tsb_spi_info *info = NULL; uint32_t pinshare = 0; int i = 0; /* check input parameters */ if (!dev || !device_get_private(dev)) { return -EINVAL; } info = device_get_private(dev); /* release GPIO pins */ for (i = 0; i < info->caps.csnum; i++) { gpio_deactivate(info->chipselect[i]); } gpio_deactivate(SPI_SDO); gpio_deactivate(SPI_SDI); gpio_deactivate(SPI_SCK); /* restore pinshare#5 setting */ pinshare = tsb_get_pinshare() & TSB_PIN_GPIO10; /* current setting */ if ((info->pinshare & TSB_PIN_GPIO10)) { if (!pinshare) { tsb_set_pinshare(TSB_PIN_GPIO10); } } else { if (pinshare) { tsb_clr_pinshare(TSB_PIN_GPIO10); } } return 0; }
/** * Init the USB4624 hub * * Activate the GPIO line * * @param dev Device * @return 0 if successful */ static int usb4624_open(struct device *dev) { /* GPIO0 is pinshared on ES2 and later, but not on ES1 */ #if !defined(CONFIG_TSB_CHIP_REV_ES1) tsb_clr_pinshare(TSB_PIN_UART_CTSRTS); #endif gpio_activate(HUB_LINE_N_RESET); return 0; }
/** * Initialise an I2C device */ struct i2c_dev_s *up_i2cinitialize(int port) { irqstate_t flags; int retval; i2cvdbg("Init I2C port %d\n", port); /* Only one I2C port on TSB */ if (port > 0) return NULL; flags = irqsave(); if (refcount++) goto out; retval = tsb_request_pinshare(TSB_PIN_GPIO21 | TSB_PIN_GPIO22); if (retval) { lowsyslog("I2C: cannot get ownership of I2C pins\n"); goto err_req_pinshare; } sem_init(&g_mutex, 0, 1); sem_init(&g_wait, 0, 0); /* enable I2C pins */ tsb_clr_pinshare(TSB_PIN_GPIO21); tsb_clr_pinshare(TSB_PIN_GPIO22); /* enable I2C clocks */ tsb_clk_enable(TSB_CLK_I2CP); tsb_clk_enable(TSB_CLK_I2CS); /* reset I2C module */ tsb_reset(TSB_RST_I2CP); tsb_reset(TSB_RST_I2CS); /* Initialize the I2C controller */ tsb_i2c_init(); /* Allocate a watchdog timer */ g_timeout = wd_create(); DEBUGASSERT(g_timeout != 0); /* Attach Interrupt Handler */ irq_attach(TSB_IRQ_I2C, i2c_interrupt); /* Enable Interrupt Handler */ up_enable_irq(TSB_IRQ_I2C); /* Install our operations */ g_dev.ops = &dev_i2c_ops; out: irqrestore(flags); return &g_dev; err_req_pinshare: refcount--; irqrestore(flags); return NULL; }
int main(int argc, FAR char *argv[]) { #else int etm_main(int argc, char *argv[]) { #endif char cmd; long drive_ma; unsigned short last_drive_ma = etm.drive_ma; if (argc < 2) { print_usage(); return EXIT_FAILURE; } else { cmd = argv[1][0]; } switch (cmd) { case 'h': case '?': print_usage(); break; case 'e': /* enable ETM */ if (argc == 2) { etm.drive_ma = DRIVE_MA_MAX; } else if (argc == 3) { drive_ma = strtol(argv[2], NULL, 10); if (drive_ma != DRIVE_MA_MIN && drive_ma != DRIVE_MA_DEFAULT && drive_ma != DRIVE_MA_MAX) { printf("Invalid drive strength of %ld ma when trying to enable ETM (%u|%u|%u are valid)\n", drive_ma, DRIVE_MA_MIN, DRIVE_MA_DEFAULT, DRIVE_MA_MAX); return EXIT_FAILURE; } etm.drive_ma = (unsigned short) drive_ma; } else { printf("Too many arguments specified when attempting to enable ETM\n"); return EXIT_FAILURE; } if (etm.enabled) { /* update drive strength if it has changed */ if (etm.drive_ma != last_drive_ma) { set_trace_drive_ma(etm.drive_ma); printf("ETM drive strength changed to %u milliamps\n", etm.drive_ma); } else printf("WARNING: ETM is already enabled\n"); } else { /* * perhaps we ought to be recording the old value * but the present API doesn't expose it */ etm.etm_pinshare_save = tsb_get_pinshare() & TSB_PIN_ETM; tsb_set_pinshare(TSB_PIN_ETM); /* set drive strength for the TRACE signals to the specified value */ etm.drive_ma_save = get_trace_drive_ma(); set_trace_drive_ma(etm.drive_ma); /* * record current value of the ETM lock status register so that we can restore * the original lock state if ETM TRACE is disabled */ etm.lsr_save = getreg32(ETMLSR); /* unlock ETM: may need a delay right after */ putreg32(ETM_UNLOCK, ETMLAR); /* put ETM into programming mode: may need a delay right after */ etm.cr_save = getreg32(ETMCR); putreg32(ETMCR_PROGRAM, ETMCR); /* Don't define a trigger for TRACE (NOT Always) */ etm.trigger_save = getreg32(ETMTRIGGER); putreg32(ETM_EVENT_NEVER, ETMTRIGGER); /* TRACE all memory */ etm.teevr_save = getreg32(ETMTEEVR); putreg32(ETM_EVENT_ALWAYS, ETMTEEVR); /* Set identifier for trace output (match what DTRACE selects) */ etm.traceidr_save = getreg32(ETMTRACEIDR); putreg32(0x2, ETMTRACEIDR); /* Set trace port width to 4 (versus 1) */ etm.cpsr_save = getreg32(TPIU_CPSR); putreg32(0x8, TPIU_CPSR); /* Set trace output type to parallel (versus 1 == serial) */ etm.sppr_save = getreg32(TPIU_SPPR); putreg32(0x0, TPIU_SPPR); /* And finally, set ETM to operational mode */ putreg32(ETMCR_OPERATE, ETMCR); etm.enabled = 1; printf("ETM enabled with a drive strength of %u milliamps\n", etm.drive_ma); } break; case 'd': /* Disable ETM */ if (!etm.enabled) { printf("WARNING: etm is already disabled\n"); } else { /* Put ETM back into programming mode */ putreg32(ETMCR_PROGRAM, ETMCR); /* Restore registers to saved values */ putreg32(etm.sppr_save, TPIU_SPPR); putreg32(etm.cpsr_save, TPIU_CPSR); putreg32(etm.traceidr_save, ETMTRACEIDR); putreg32(etm.teevr_save, ETMTEEVR); putreg32(etm.trigger_save, ETMTRIGGER); putreg32(etm.cr_save, ETMCR); /* Relock ETM if it was locked when we enabled TRACE */ if (etm.lsr_save & ETMLSR_LOCKED) putreg32(ETM_LOCK, ETMLAR); /* Restore the original drive strength */ set_trace_drive_ma(etm.drive_ma_save); /* Clear the ETM pinshare if it wasn't set on entry */ if (!etm.etm_pinshare_save) tsb_clr_pinshare(TSB_PIN_ETM); etm.enabled = 0; etm.drive_ma = 0; } break; case 's': /* Get the ETM state */ if (etm.enabled) { printf("ETM state = enabled, with a drive strength of %u milliamps\n", etm.drive_ma); } else { printf("ETM state = either never enabled or returned to original state\n"); } break; default: printf("ETM: Unknown command\n"); print_usage(); return EXIT_FAILURE; } return 0; }
int main(int argc, FAR char *argv[]) { #else int pinshare_main(int argc, char *argv[]) { #endif uint32_t mask = 0; char cmd = '\0'; int ret = 0; char *endptr = NULL; if (argc < 2) { print_usage(); return EXIT_FAILURE; } else { cmd = argv[1][0]; } switch (cmd) { case 'h': case '?': print_usage(); break; case 'r': case 'g': /* read current value of PINSHARE register */ if (argc != 2) { print_usage(); ret = EXIT_FAILURE; } else { printf("Current value of PINSHARE register is: 0x%x\n", tsb_get_pinshare()); } break; default: /* set or clear specified bits of PINSHARE register */ if (argc != 3) { print_usage(); ret = EXIT_FAILURE; } mask = strtoul(argv[2], &endptr, 16); if (*endptr) { printf("PINSHARE: Unable to parse provided hex bitmask \"%s\"\n", argv[2]); ret = EXIT_FAILURE; } else { switch(cmd) { case 's': tsb_set_pinshare(mask); printf("New value of PINSHARE register is: 0x%x\n", tsb_get_pinshare()); break; case 'c': if (mask & 0x1) { printf("PINSHARE: Leaving bit 0 set, to keep UART active!\n"); mask &= ~1; } tsb_clr_pinshare(mask); printf("New value of PINSHARE register is: 0x%x\n", tsb_get_pinshare()); break; default: printf("PINSHARE: Unknown command\n"); print_usage(); ret = EXIT_FAILURE; } } } return ret; }