static void board_configure_analogix(void) { int node, ret; struct fdt_gpio_state reset_gpio; struct fdt_gpio_state powerdown_gpio; node = fdtdec_next_compatible(gd->fdt_blob, 0, COMPAT_ANALOGIX_ANX7805); if (node <= 0) return; /* Configure Analogix 780x bridge in USB pass-through mode */ ret = fdtdec_decode_gpio(gd->fdt_blob, node, "reset-gpio", &reset_gpio); if (ret < 0) { debug("%s: Could not find reset-gpio", __func__); return; } ret = fdtdec_decode_gpio(gd->fdt_blob, node, "powerdown-gpio", &powerdown_gpio); if (ret < 0) { debug("%s: Could not find powerdown-gpio", __func__); return; } fdtdec_setup_gpio(&powerdown_gpio); fdtdec_setup_gpio(&reset_gpio); gpio_direction_output(powerdown_gpio.gpio, 1); gpio_direction_output(reset_gpio.gpio, 1); }
static int sdhci_get_config(const void *blob, int node, struct sdhci_host *host) { int bus_width, dev_id; unsigned int base; /* Get device id */ dev_id = pinmux_decode_periph_id(blob, node); if (dev_id < PERIPH_ID_SDMMC0 && dev_id > PERIPH_ID_SDMMC3) { debug("MMC: Can't get device id\n"); return -1; } host->index = dev_id - PERIPH_ID_SDMMC0; /* Get bus width */ bus_width = fdtdec_get_int(blob, node, "samsung,bus-width", 0); if (bus_width <= 0) { debug("MMC: Can't get bus-width\n"); return -1; } host->bus_width = bus_width; /* Get the base address from the device node */ base = fdtdec_get_addr(blob, node, "reg"); if (!base) { debug("MMC: Can't get base address\n"); return -1; } host->ioaddr = (void *)base; fdtdec_decode_gpio(blob, node, "pwr-gpios", &host->pwr_gpio); fdtdec_decode_gpio(blob, node, "cd-gpios", &host->cd_gpio); return 0; }
static int board_dp_fill_gpios(const void *blob) { int np, ret, rev; np = fdtdec_next_compatible(blob, 0, COMPAT_NXP_PTN3460); if (np < 0) { debug("%s: Could not find COMPAT_NXP_PTN3460 (%d)\n", __func__, ret); return np; } ret = fdtdec_decode_gpio(blob, np, "powerdown-gpio", &local.dp_pd); if (ret) { debug("%s: Could not decode powerdown-gpio (%d)\n", __func__, ret); return ret; } ret = fdtdec_decode_gpio(blob, np, "reset-gpio", &local.dp_rst); if (ret) { debug("%s: Could not decode reset-gpio (%d)\n", __func__, ret); return ret; } ret = fdtdec_decode_gpio(blob, np, "hotplug-gpio", &local.dp_hpd); if (ret) { debug("%s: Could not decode hotplug (%d)\n", __func__, ret); return ret; } /* If board is older, replace pd gpio with rst gpio */ rev = board_get_revision(); if (rev >= 4 && rev != 6) { local.dp_pd = local.dp_rst; local.dp_rst.gpio = FDT_GPIO_NONE; } return 0; }
static int board_i2c_arb_init(const void *blob) { int node; local.arbitrate_node = -1; node = fdtdec_next_compatible(blob, 0, COMPAT_GOOGLE_ARBITRATOR); if (node < 0) { debug("Cannot find bus arbitrator node\n"); return 0; } if (fdtdec_decode_gpio(blob, node, "google,ap-claim-gpios", &local.ap_claim) || fdtdec_decode_gpio(blob, node, "google,ec-claim-gpios", &local.ec_claim)) { debug("Cannot find bus arbitrator GPIOs\n"); return 0; } if (fdtdec_setup_gpio(&local.ap_claim) || fdtdec_setup_gpio(&local.ec_claim)) { debug("Cannot claim arbitration GPIOs\n"); return -1; } /* We are currently not claiming the bus */ gpio_direction_output(local.ap_claim.gpio, 1); gpio_direction_input(local.ec_claim.gpio); gpio_set_pull(local.ec_claim.gpio, EXYNOS_GPIO_PULL_UP); local.arbitrate_node = fdtdec_lookup_phandle(blob, node, "google,arbitrate-bus"); if (local.arbitrate_node < 0) { debug("Cannot find bus to arbitrate\n"); return -1; } local.slew_delay_us = fdtdec_get_int(blob, node, "google,slew-delay-us", 10); local.wait_retry_ms = fdtdec_get_int(blob, node, "google,wait-retry-us", 2000); local.wait_retry_ms = DIV_ROUND_UP(local.wait_retry_ms, 1000); local.wait_free_ms = fdtdec_get_int(blob, node, "google,wait-free-us", 50000); local.wait_free_ms = DIV_ROUND_UP(local.wait_free_ms, 1000); debug("Bus arbitration ready on fdt node %d\n", local.arbitrate_node); return 0; }
static int fdt_decode_usb(const void *blob, int node, struct fdt_usb *config) { const char *phy, *mode; config->reg = (struct usb_ctlr *)fdtdec_get_addr(blob, node, "reg"); mode = fdt_getprop(blob, node, "dr_mode", NULL); if (mode) { if (0 == strcmp(mode, "host")) config->dr_mode = DR_MODE_HOST; else if (0 == strcmp(mode, "peripheral")) config->dr_mode = DR_MODE_DEVICE; else if (0 == strcmp(mode, "otg")) config->dr_mode = DR_MODE_OTG; else { debug("%s: Cannot decode dr_mode '%s'\n", __func__, mode); return -FDT_ERR_NOTFOUND; } } else { config->dr_mode = DR_MODE_HOST; } phy = fdt_getprop(blob, node, "phy_type", NULL); config->utmi = phy && 0 == strcmp("utmi", phy); config->ulpi = phy && 0 == strcmp("ulpi", phy); config->enabled = fdtdec_get_is_enabled(blob, node); config->has_legacy_mode = fdtdec_get_bool(blob, node, "nvidia,has-legacy-mode"); if (config->has_legacy_mode) port_addr_clear_csc = (u32) config->reg; config->periph_id = clock_decode_periph_id(blob, node); if (config->periph_id == PERIPH_ID_NONE) { debug("%s: Missing/invalid peripheral ID\n", __func__); return -FDT_ERR_NOTFOUND; } fdtdec_decode_gpio(blob, node, "nvidia,vbus-gpio", &config->vbus_gpio); fdtdec_decode_gpio(blob, node, "nvidia,phy-reset-gpio", &config->phy_reset_gpio); debug("enabled=%d, legacy_mode=%d, utmi=%d, ulpi=%d, periph_id=%d, " "vbus=%d, phy_reset=%d, dr_mode=%d\n", config->enabled, config->has_legacy_mode, config->utmi, config->ulpi, config->periph_id, config->vbus_gpio.gpio, config->phy_reset_gpio.gpio, config->dr_mode); return 0; }
/** * Decode EC interface details from the device tree and allocate a suitable * device. * * @param blob Device tree blob * @param node Node to decode from * @param devp Returns a pointer to the new allocated device * @return 0 if ok, -1 on error */ static int cros_ec_decode_fdt(const void *blob, int node, struct cros_ec_dev **devp) { enum fdt_compat_id compat; struct cros_ec_dev *dev; int parent; /* See what type of parent we are inside (this is expensive) */ parent = fdt_parent_offset(blob, node); if (parent < 0) { debug("%s: Cannot find node parent\n", __func__); return -1; } dev = &static_dev; dev->node = node; dev->parent_node = parent; compat = fdtdec_lookup(blob, parent); switch (compat) { #ifdef CONFIG_CROS_EC_SPI case COMPAT_SAMSUNG_EXYNOS_SPI: dev->interface = CROS_EC_IF_SPI; if (cros_ec_spi_decode_fdt(dev, blob)) return -1; break; #endif #ifdef CONFIG_CROS_EC_I2C case COMPAT_SAMSUNG_S3C2440_I2C: dev->interface = CROS_EC_IF_I2C; if (cros_ec_i2c_decode_fdt(dev, blob)) return -1; break; #endif #ifdef CONFIG_CROS_EC_LPC case COMPAT_INTEL_LPC: dev->interface = CROS_EC_IF_LPC; break; #endif #ifdef CONFIG_CROS_EC_SANDBOX case COMPAT_SANDBOX_HOST_EMULATION: dev->interface = CROS_EC_IF_SANDBOX; break; #endif default: debug("%s: Unknown compat id %d\n", __func__, compat); return -1; } fdtdec_decode_gpio(blob, node, "ec-interrupt", &dev->ec_int); dev->optimise_flash_write = fdtdec_get_bool(blob, node, "optimise-flash-write"); *devp = dev; return 0; }
/** * Decode the panel information from the fdt. * * @param blob fdt blob * @param config structure to store fdt config into * @return 0 if ok, -ve on error */ static int fdt_decode_lcd(const void *blob, struct fdt_panel_config *config) { int display_node; disp_config = tegra_display_get_config(); if (!disp_config) { debug("%s: Display controller is not configured\n", __func__); return -1; } display_node = disp_config->panel_node; if (display_node < 0) { debug("%s: No panel configuration available\n", __func__); return -1; } config->pwm_channel = pwm_request(blob, display_node, "nvidia,pwm"); if (config->pwm_channel < 0) { debug("%s: Unable to request PWM channel\n", __func__); return -1; } config->cache_type = fdtdec_get_int(blob, display_node, "nvidia,cache-type", FDT_LCD_CACHE_WRITE_BACK_FLUSH); /* These GPIOs are all optional */ fdtdec_decode_gpio(blob, display_node, "nvidia,backlight-enable-gpios", &config->backlight_en); fdtdec_decode_gpio(blob, display_node, "nvidia,lvds-shutdown-gpios", &config->lvds_shutdown); fdtdec_decode_gpio(blob, display_node, "nvidia,backlight-vdd-gpios", &config->backlight_vdd); fdtdec_decode_gpio(blob, display_node, "nvidia,panel-vdd-gpios", &config->panel_vdd); return fdtdec_get_int_array(blob, display_node, "nvidia,panel-timings", config->panel_timings, FDT_LCD_TIMINGS); }
static int exynos5_sata_enable_power(const void *blob) { int node; struct fdt_gpio_state gpio; node = fdtdec_next_compatible(blob, 0, COMPAT_GOOGLE_SATA); if (node >= 0 && fdtdec_decode_gpio(blob, node, "enable-gpios", &gpio) == 0) { gpio_cfg_pin(gpio.gpio, EXYNOS_GPIO_OUTPUT); gpio_set_value(gpio.gpio, 1); return 0; } return -ENODEV; }
static int exynos_usb_parse_dt(const void *blob, struct exynos_ehci *exynos) { fdt_addr_t addr; unsigned int node; int depth; node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS_EHCI); if (node <= 0) { debug("EHCI: Can't get device node for ehci\n"); return -ENODEV; } /* * Get the base address for EHCI controller from the device node */ addr = fdtdec_get_addr(blob, node, "reg"); if (addr == FDT_ADDR_T_NONE) { debug("Can't get the EHCI register address\n"); return -ENXIO; } exynos->hcd = (struct ehci_hccr *)addr; /* Vbus gpio */ fdtdec_decode_gpio(blob, node, "samsung,vbus-gpio", &exynos->vbus_gpio); depth = 0; node = fdtdec_next_compatible_subnode(blob, node, COMPAT_SAMSUNG_EXYNOS_USB_PHY, &depth); if (node <= 0) { debug("EHCI: Can't get device node for usb-phy controller\n"); return -ENODEV; } /* * Get the base address for usbphy from the device node */ exynos->usb = (struct exynos_usb_phy *)fdtdec_get_addr(blob, node, "reg"); if (exynos->usb == NULL) { debug("Can't get the usbphy register address\n"); return -ENXIO; } return 0; }
/* * This functions disable the USB3.0 PLL to save power */ static void disable_usb30_pll(void) { int node, ret; struct fdt_gpio_state en_gpio; node = fdtdec_next_compatible(gd->fdt_blob, 0, COMPAT_SAMSUNG_EXYNOS_USB); if (node < 0) return; ret = fdtdec_decode_gpio(gd->fdt_blob, node, "usb3-pll-gpio", &en_gpio); if (ret) return; fdtdec_setup_gpio(&en_gpio); gpio_direction_output(en_gpio.gpio, en_gpio.flags); }
static void board_enable_audio_codec(void) { int node, ret, value; struct fdt_gpio_state en_gpio; node = fdtdec_next_compatible(gd->fdt_blob, 0, COMPAT_SAMSUNG_EXYNOS_SOUND); if (node <= 0) return; ret = fdtdec_decode_gpio(gd->fdt_blob, node, "codec-enable-gpio", &en_gpio); if (ret == -FDT_ERR_NOTFOUND) return; /* Turn on the GPIO which connects to the codec's "enable" line. */ value = (en_gpio.flags & FDT_GPIO_ACTIVE_LOW) ? 0 : 1; gpio_direction_output(en_gpio.gpio, value); gpio_set_pull(en_gpio.gpio, EXYNOS_GPIO_PULL_NONE); }