/* * The PMU supplies power to the Bluetooth and WLAN modules. both * consume the PMU AON output so check the presence of the * 'vddaon-supply' property and whether it leads us to the right * device.
*/ if (!of_property_present(dev_node, "vddaon-supply")) return PWRSEQ_NO_MATCH;
/* * `reg_node` is the PMU AON regulator, its parent is the `regulators` * node and finally its grandparent is the PMU device node that we're * looking for.
*/ if (!reg_node->parent || !reg_node->parent->parent ||
reg_node->parent->parent != ctx->of_node) return PWRSEQ_NO_MATCH;
return PWRSEQ_MATCH_OK;
}
staticint pwrseq_qcom_wcn_probe(struct platform_device *pdev)
{ struct device *dev = &pdev->dev; struct pwrseq_qcom_wcn_ctx *ctx; struct pwrseq_config config; int i, ret;
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM;
ctx->of_node = dev->of_node;
ctx->pdata = of_device_get_match_data(dev); if (!ctx->pdata) return dev_err_probe(dev, -ENODEV, "Failed to obtain platform data\n");
ctx->regs = devm_kcalloc(dev, ctx->pdata->num_vregs, sizeof(*ctx->regs), GFP_KERNEL); if (!ctx->regs) return -ENOMEM;
for (i = 0; i < ctx->pdata->num_vregs; i++)
ctx->regs[i].supply = ctx->pdata->vregs[i];
ret = devm_regulator_bulk_get(dev, ctx->pdata->num_vregs, ctx->regs); if (ret < 0) return dev_err_probe(dev, ret, "Failed to get all regulators\n");
ctx->bt_gpio = devm_gpiod_get_optional(dev, "bt-enable", GPIOD_OUT_LOW); if (IS_ERR(ctx->bt_gpio)) return dev_err_probe(dev, PTR_ERR(ctx->bt_gpio), "Failed to get the Bluetooth enable GPIO\n");
/* * FIXME: This should actually be GPIOD_OUT_LOW, but doing so would * cause the WLAN power to be toggled, resulting in PCIe link down. * Since the PCIe controller driver is not handling link down currently, * the device becomes unusable. So we need to keep this workaround until * the link down handling is implemented in the controller driver.
*/
ctx->wlan_gpio = devm_gpiod_get_optional(dev, "wlan-enable",
GPIOD_ASIS); if (IS_ERR(ctx->wlan_gpio)) return dev_err_probe(dev, PTR_ERR(ctx->wlan_gpio), "Failed to get the WLAN enable GPIO\n");
ctx->xo_clk_gpio = devm_gpiod_get_optional(dev, "xo-clk",
GPIOD_OUT_LOW); if (IS_ERR(ctx->xo_clk_gpio)) return dev_err_probe(dev, PTR_ERR(ctx->xo_clk_gpio), "Failed to get the XO_CLK GPIO\n");
/* * Set direction to output but keep the current value in order to not * disable the WLAN module accidentally if it's already powered on.
*/
gpiod_direction_output(ctx->wlan_gpio,
gpiod_get_value_cansleep(ctx->wlan_gpio));
ctx->clk = devm_clk_get_optional(dev, NULL); if (IS_ERR(ctx->clk)) return dev_err_probe(dev, PTR_ERR(ctx->clk), "Failed to get the reference clock\n");
ctx->pwrseq = devm_pwrseq_device_register(dev, &config); if (IS_ERR(ctx->pwrseq)) return dev_err_probe(dev, PTR_ERR(ctx->pwrseq), "Failed to register the power sequencer\n");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.