static int arizona_ldo1_probe(struct platform_device *pdev) { struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); const struct regulator_desc *desc; struct regulator_config config = { }; struct arizona_ldo1 *ldo1; int ret; arizona->external_dcvdd = false; ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL); if (ldo1 == NULL) { dev_err(&pdev->dev, "Unable to allocate private data\n"); return -ENOMEM; } ldo1->arizona = arizona; /* * Since the chip usually supplies itself we provide some * default init_data for it. This will be overridden with * platform data if provided. */ switch (arizona->type) { case WM5102: case WM8997: case WM8998: case WM1814: desc = &arizona_ldo1_hc; ldo1->init_data = arizona_ldo1_dvfs; break; default: desc = &arizona_ldo1; ldo1->init_data = arizona_ldo1_default; break; } ldo1->init_data.consumer_supplies = &ldo1->supply; ldo1->supply.supply = "DCVDD"; ldo1->supply.dev_name = dev_name(arizona->dev); config.dev = arizona->dev; config.driver_data = ldo1; config.regmap = arizona->regmap; if (IS_ENABLED(CONFIG_OF)) { if (!dev_get_platdata(arizona->dev)) { ret = arizona_ldo1_of_get_pdata(arizona, &config); if (ret < 0) return ret; } } config.ena_gpio = arizona->pdata.ldoena; config.ena_gpio_flags = GPIOF_OUT_INIT_LOW; if (arizona->pdata.ldo1) config.init_data = arizona->pdata.ldo1; else config.init_data = &ldo1->init_data; /* * LDO1 can only be used to supply DCVDD so if it has no * consumers then DCVDD is supplied externally. */ if (config.init_data->num_consumer_supplies == 0) arizona->external_dcvdd = true; ldo1->regulator = regulator_register(desc, &config); if (IS_ERR(ldo1->regulator)) { ret = PTR_ERR(ldo1->regulator); dev_err(arizona->dev, "Failed to register LDO1 supply: %d\n", ret); return ret; } of_node_put(config.of_node); platform_set_drvdata(pdev, ldo1); return 0; }
static int arizona_ldo1_common_init(struct platform_device *pdev, struct arizona_ldo1 *ldo1, const struct regulator_desc *desc, struct arizona_ldo1_pdata *pdata, bool *external_dcvdd) { struct device *parent_dev = pdev->dev.parent; struct regulator_config config = { }; int ret; *external_dcvdd = false; ldo1->supply.supply = "DCVDD"; ldo1->init_data.consumer_supplies = &ldo1->supply; ldo1->supply.dev_name = dev_name(parent_dev); config.dev = parent_dev; config.driver_data = ldo1; config.regmap = ldo1->regmap; if (IS_ENABLED(CONFIG_OF)) { if (!dev_get_platdata(parent_dev)) { ret = arizona_ldo1_of_get_pdata(pdata, &config, desc, external_dcvdd); if (ret < 0) return ret; } } /* We assume that high output = regulator off * Don't use devm, since we need to get against the parent device * so clean up would happen at the wrong time */ config.ena_gpiod = gpiod_get_optional(parent_dev, "wlf,ldoena", GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_NONEXCLUSIVE); if (IS_ERR(config.ena_gpiod)) return PTR_ERR(config.ena_gpiod); ldo1->ena_gpiod = config.ena_gpiod; if (pdata->init_data) config.init_data = pdata->init_data; else config.init_data = &ldo1->init_data; /* * LDO1 can only be used to supply DCVDD so if it has no * consumers then DCVDD is supplied externally. */ if (config.init_data->num_consumer_supplies == 0) *external_dcvdd = true; ldo1->regulator = devm_regulator_register(&pdev->dev, desc, &config); of_node_put(config.of_node); if (IS_ERR(ldo1->regulator)) { ret = PTR_ERR(ldo1->regulator); dev_err(&pdev->dev, "Failed to register LDO1 supply: %d\n", ret); return ret; } platform_set_drvdata(pdev, ldo1); return 0; }