11910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown/* 21910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown * arizona-ldo1.c -- LDO1 supply for Arizona devices 31910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown * 41910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown * Copyright 2012 Wolfson Microelectronics PLC. 51910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown * 61910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 71910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown * 81910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown * This program is free software; you can redistribute it and/or modify it 91910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown * under the terms of the GNU General Public License as published by the 101910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown * Free Software Foundation; either version 2 of the License, or (at your 111910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown * option) any later version. 121910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown */ 131910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown 141910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown#include <linux/module.h> 151910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown#include <linux/moduleparam.h> 161910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown#include <linux/init.h> 171910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown#include <linux/bitops.h> 181910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown#include <linux/err.h> 197b22b9a5aba1eeda05d4b08c8b1c70c9ba385e82Arnd Bergmann#include <linux/of.h> 201910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown#include <linux/platform_device.h> 211910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown#include <linux/regulator/driver.h> 221910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown#include <linux/regulator/machine.h> 232cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax#include <linux/regulator/of_regulator.h> 241910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown#include <linux/gpio.h> 251910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown#include <linux/slab.h> 261910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown 271910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown#include <linux/mfd/arizona/core.h> 281910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown#include <linux/mfd/arizona/pdata.h> 291910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown#include <linux/mfd/arizona/registers.h> 301910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown 311910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brownstruct arizona_ldo1 { 321910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown struct regulator_dev *regulator; 331910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown struct arizona *arizona; 341910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown 351910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown struct regulator_consumer_supply supply; 361910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown struct regulator_init_data init_data; 371910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown}; 381910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown 3973ee29460e5d0adbb46e4962df69ae2465746612Mark Brownstatic int arizona_ldo1_hc_list_voltage(struct regulator_dev *rdev, 4073ee29460e5d0adbb46e4962df69ae2465746612Mark Brown unsigned int selector) 4173ee29460e5d0adbb46e4962df69ae2465746612Mark Brown{ 4273ee29460e5d0adbb46e4962df69ae2465746612Mark Brown if (selector >= rdev->desc->n_voltages) 4373ee29460e5d0adbb46e4962df69ae2465746612Mark Brown return -EINVAL; 4473ee29460e5d0adbb46e4962df69ae2465746612Mark Brown 4573ee29460e5d0adbb46e4962df69ae2465746612Mark Brown if (selector == rdev->desc->n_voltages - 1) 4673ee29460e5d0adbb46e4962df69ae2465746612Mark Brown return 1800000; 4773ee29460e5d0adbb46e4962df69ae2465746612Mark Brown else 4873ee29460e5d0adbb46e4962df69ae2465746612Mark Brown return rdev->desc->min_uV + (rdev->desc->uV_step * selector); 4973ee29460e5d0adbb46e4962df69ae2465746612Mark Brown} 5073ee29460e5d0adbb46e4962df69ae2465746612Mark Brown 5173ee29460e5d0adbb46e4962df69ae2465746612Mark Brownstatic int arizona_ldo1_hc_map_voltage(struct regulator_dev *rdev, 5273ee29460e5d0adbb46e4962df69ae2465746612Mark Brown int min_uV, int max_uV) 5373ee29460e5d0adbb46e4962df69ae2465746612Mark Brown{ 5473ee29460e5d0adbb46e4962df69ae2465746612Mark Brown int sel; 5573ee29460e5d0adbb46e4962df69ae2465746612Mark Brown 5673ee29460e5d0adbb46e4962df69ae2465746612Mark Brown sel = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step); 5773ee29460e5d0adbb46e4962df69ae2465746612Mark Brown if (sel >= rdev->desc->n_voltages) 5873ee29460e5d0adbb46e4962df69ae2465746612Mark Brown sel = rdev->desc->n_voltages - 1; 5973ee29460e5d0adbb46e4962df69ae2465746612Mark Brown 6073ee29460e5d0adbb46e4962df69ae2465746612Mark Brown return sel; 6173ee29460e5d0adbb46e4962df69ae2465746612Mark Brown} 6273ee29460e5d0adbb46e4962df69ae2465746612Mark Brown 6373ee29460e5d0adbb46e4962df69ae2465746612Mark Brownstatic int arizona_ldo1_hc_set_voltage_sel(struct regulator_dev *rdev, 6473ee29460e5d0adbb46e4962df69ae2465746612Mark Brown unsigned sel) 6573ee29460e5d0adbb46e4962df69ae2465746612Mark Brown{ 6673ee29460e5d0adbb46e4962df69ae2465746612Mark Brown struct arizona_ldo1 *ldo = rdev_get_drvdata(rdev); 6773ee29460e5d0adbb46e4962df69ae2465746612Mark Brown struct regmap *regmap = ldo->arizona->regmap; 6873ee29460e5d0adbb46e4962df69ae2465746612Mark Brown unsigned int val; 6973ee29460e5d0adbb46e4962df69ae2465746612Mark Brown int ret; 7073ee29460e5d0adbb46e4962df69ae2465746612Mark Brown 7173ee29460e5d0adbb46e4962df69ae2465746612Mark Brown if (sel == rdev->desc->n_voltages - 1) 7273ee29460e5d0adbb46e4962df69ae2465746612Mark Brown val = ARIZONA_LDO1_HI_PWR; 7373ee29460e5d0adbb46e4962df69ae2465746612Mark Brown else 7473ee29460e5d0adbb46e4962df69ae2465746612Mark Brown val = 0; 7573ee29460e5d0adbb46e4962df69ae2465746612Mark Brown 7673ee29460e5d0adbb46e4962df69ae2465746612Mark Brown ret = regmap_update_bits(regmap, ARIZONA_LDO1_CONTROL_2, 7773ee29460e5d0adbb46e4962df69ae2465746612Mark Brown ARIZONA_LDO1_HI_PWR, val); 7873ee29460e5d0adbb46e4962df69ae2465746612Mark Brown if (ret != 0) 7973ee29460e5d0adbb46e4962df69ae2465746612Mark Brown return ret; 8073ee29460e5d0adbb46e4962df69ae2465746612Mark Brown 8173ee29460e5d0adbb46e4962df69ae2465746612Mark Brown ret = regmap_update_bits(regmap, ARIZONA_DYNAMIC_FREQUENCY_SCALING_1, 8273ee29460e5d0adbb46e4962df69ae2465746612Mark Brown ARIZONA_SUBSYS_MAX_FREQ, val); 8373ee29460e5d0adbb46e4962df69ae2465746612Mark Brown if (ret != 0) 8473ee29460e5d0adbb46e4962df69ae2465746612Mark Brown return ret; 8573ee29460e5d0adbb46e4962df69ae2465746612Mark Brown 8673ee29460e5d0adbb46e4962df69ae2465746612Mark Brown if (val) 8773ee29460e5d0adbb46e4962df69ae2465746612Mark Brown return 0; 8873ee29460e5d0adbb46e4962df69ae2465746612Mark Brown 8973ee29460e5d0adbb46e4962df69ae2465746612Mark Brown val = sel << ARIZONA_LDO1_VSEL_SHIFT; 9073ee29460e5d0adbb46e4962df69ae2465746612Mark Brown 9173ee29460e5d0adbb46e4962df69ae2465746612Mark Brown return regmap_update_bits(regmap, ARIZONA_LDO1_CONTROL_1, 9273ee29460e5d0adbb46e4962df69ae2465746612Mark Brown ARIZONA_LDO1_VSEL_MASK, val); 9373ee29460e5d0adbb46e4962df69ae2465746612Mark Brown} 9473ee29460e5d0adbb46e4962df69ae2465746612Mark Brown 9573ee29460e5d0adbb46e4962df69ae2465746612Mark Brownstatic int arizona_ldo1_hc_get_voltage_sel(struct regulator_dev *rdev) 9673ee29460e5d0adbb46e4962df69ae2465746612Mark Brown{ 9773ee29460e5d0adbb46e4962df69ae2465746612Mark Brown struct arizona_ldo1 *ldo = rdev_get_drvdata(rdev); 9873ee29460e5d0adbb46e4962df69ae2465746612Mark Brown struct regmap *regmap = ldo->arizona->regmap; 9973ee29460e5d0adbb46e4962df69ae2465746612Mark Brown unsigned int val; 10073ee29460e5d0adbb46e4962df69ae2465746612Mark Brown int ret; 10173ee29460e5d0adbb46e4962df69ae2465746612Mark Brown 10273ee29460e5d0adbb46e4962df69ae2465746612Mark Brown ret = regmap_read(regmap, ARIZONA_LDO1_CONTROL_2, &val); 10373ee29460e5d0adbb46e4962df69ae2465746612Mark Brown if (ret != 0) 10473ee29460e5d0adbb46e4962df69ae2465746612Mark Brown return ret; 10573ee29460e5d0adbb46e4962df69ae2465746612Mark Brown 10673ee29460e5d0adbb46e4962df69ae2465746612Mark Brown if (val & ARIZONA_LDO1_HI_PWR) 10773ee29460e5d0adbb46e4962df69ae2465746612Mark Brown return rdev->desc->n_voltages - 1; 10873ee29460e5d0adbb46e4962df69ae2465746612Mark Brown 10973ee29460e5d0adbb46e4962df69ae2465746612Mark Brown ret = regmap_read(regmap, ARIZONA_LDO1_CONTROL_1, &val); 11073ee29460e5d0adbb46e4962df69ae2465746612Mark Brown if (ret != 0) 11173ee29460e5d0adbb46e4962df69ae2465746612Mark Brown return ret; 11273ee29460e5d0adbb46e4962df69ae2465746612Mark Brown 11373ee29460e5d0adbb46e4962df69ae2465746612Mark Brown return (val & ARIZONA_LDO1_VSEL_MASK) >> ARIZONA_LDO1_VSEL_SHIFT; 11473ee29460e5d0adbb46e4962df69ae2465746612Mark Brown} 11573ee29460e5d0adbb46e4962df69ae2465746612Mark Brown 11673ee29460e5d0adbb46e4962df69ae2465746612Mark Brownstatic struct regulator_ops arizona_ldo1_hc_ops = { 11773ee29460e5d0adbb46e4962df69ae2465746612Mark Brown .list_voltage = arizona_ldo1_hc_list_voltage, 11873ee29460e5d0adbb46e4962df69ae2465746612Mark Brown .map_voltage = arizona_ldo1_hc_map_voltage, 11973ee29460e5d0adbb46e4962df69ae2465746612Mark Brown .get_voltage_sel = arizona_ldo1_hc_get_voltage_sel, 12073ee29460e5d0adbb46e4962df69ae2465746612Mark Brown .set_voltage_sel = arizona_ldo1_hc_set_voltage_sel, 12173ee29460e5d0adbb46e4962df69ae2465746612Mark Brown .get_bypass = regulator_get_bypass_regmap, 12273ee29460e5d0adbb46e4962df69ae2465746612Mark Brown .set_bypass = regulator_set_bypass_regmap, 12373ee29460e5d0adbb46e4962df69ae2465746612Mark Brown}; 12473ee29460e5d0adbb46e4962df69ae2465746612Mark Brown 12573ee29460e5d0adbb46e4962df69ae2465746612Mark Brownstatic const struct regulator_desc arizona_ldo1_hc = { 12673ee29460e5d0adbb46e4962df69ae2465746612Mark Brown .name = "LDO1", 12773ee29460e5d0adbb46e4962df69ae2465746612Mark Brown .supply_name = "LDOVDD", 12873ee29460e5d0adbb46e4962df69ae2465746612Mark Brown .type = REGULATOR_VOLTAGE, 12973ee29460e5d0adbb46e4962df69ae2465746612Mark Brown .ops = &arizona_ldo1_hc_ops, 13073ee29460e5d0adbb46e4962df69ae2465746612Mark Brown 13173ee29460e5d0adbb46e4962df69ae2465746612Mark Brown .bypass_reg = ARIZONA_LDO1_CONTROL_1, 13273ee29460e5d0adbb46e4962df69ae2465746612Mark Brown .bypass_mask = ARIZONA_LDO1_BYPASS, 13373ee29460e5d0adbb46e4962df69ae2465746612Mark Brown .min_uV = 900000, 13473ee29460e5d0adbb46e4962df69ae2465746612Mark Brown .uV_step = 50000, 13573ee29460e5d0adbb46e4962df69ae2465746612Mark Brown .n_voltages = 8, 136ce1bcb7eabd1c6f6679b5d4a3fa3313c8da90715Mark Brown .enable_time = 1500, 13773ee29460e5d0adbb46e4962df69ae2465746612Mark Brown 13873ee29460e5d0adbb46e4962df69ae2465746612Mark Brown .owner = THIS_MODULE, 13973ee29460e5d0adbb46e4962df69ae2465746612Mark Brown}; 14073ee29460e5d0adbb46e4962df69ae2465746612Mark Brown 1411910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brownstatic struct regulator_ops arizona_ldo1_ops = { 1421910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown .list_voltage = regulator_list_voltage_linear, 1431910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown .map_voltage = regulator_map_voltage_linear, 1441910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown .get_voltage_sel = regulator_get_voltage_sel_regmap, 1451910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown .set_voltage_sel = regulator_set_voltage_sel_regmap, 1461910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown}; 1471910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown 1481910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brownstatic const struct regulator_desc arizona_ldo1 = { 1491910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown .name = "LDO1", 1501910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown .supply_name = "LDOVDD", 1511910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown .type = REGULATOR_VOLTAGE, 1521910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown .ops = &arizona_ldo1_ops, 1531910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown 1541910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown .vsel_reg = ARIZONA_LDO1_CONTROL_1, 1551910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown .vsel_mask = ARIZONA_LDO1_VSEL_MASK, 1561910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown .min_uV = 900000, 157a35ff2861690eaf9dbb38fa744a8a9e6f4ebfd61Charles Keepax .uV_step = 25000, 158a35ff2861690eaf9dbb38fa744a8a9e6f4ebfd61Charles Keepax .n_voltages = 13, 15986a14501180de78ccec1e513b031a06ea60c973fMark Brown .enable_time = 500, 1601910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown 1611910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown .owner = THIS_MODULE, 1621910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown}; 1631910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown 16455a18aef2e963c43d3a0ae20c1dfd404830aa6f9Mark Brownstatic const struct regulator_init_data arizona_ldo1_dvfs = { 16555a18aef2e963c43d3a0ae20c1dfd404830aa6f9Mark Brown .constraints = { 16655a18aef2e963c43d3a0ae20c1dfd404830aa6f9Mark Brown .min_uV = 1200000, 16755a18aef2e963c43d3a0ae20c1dfd404830aa6f9Mark Brown .max_uV = 1800000, 16855a18aef2e963c43d3a0ae20c1dfd404830aa6f9Mark Brown .valid_ops_mask = REGULATOR_CHANGE_STATUS | 16955a18aef2e963c43d3a0ae20c1dfd404830aa6f9Mark Brown REGULATOR_CHANGE_VOLTAGE, 17055a18aef2e963c43d3a0ae20c1dfd404830aa6f9Mark Brown }, 17155a18aef2e963c43d3a0ae20c1dfd404830aa6f9Mark Brown .num_consumer_supplies = 1, 17255a18aef2e963c43d3a0ae20c1dfd404830aa6f9Mark Brown}; 17355a18aef2e963c43d3a0ae20c1dfd404830aa6f9Mark Brown 1741910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brownstatic const struct regulator_init_data arizona_ldo1_default = { 175a9905b1d6fa80a07997520c7f554aedf3e1b47e7Mark Brown .constraints = { 176a9905b1d6fa80a07997520c7f554aedf3e1b47e7Mark Brown .valid_ops_mask = REGULATOR_CHANGE_STATUS, 177a9905b1d6fa80a07997520c7f554aedf3e1b47e7Mark Brown }, 1781910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown .num_consumer_supplies = 1, 1791910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown}; 1801910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown 1812cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepaxstatic int arizona_ldo1_of_get_pdata(struct arizona *arizona, 1822cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax struct regulator_config *config) 1834a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax{ 1844a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax struct arizona_pdata *pdata = &arizona->pdata; 1852cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax struct arizona_ldo1 *ldo1 = config->driver_data; 1862cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax struct device_node *init_node, *dcvdd_node; 1872cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax struct regulator_init_data *init_data; 1884a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax 1894a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax pdata->ldoena = arizona_of_get_named_gpio(arizona, "wlf,ldoena", true); 1904a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax 1912cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax init_node = of_get_child_by_name(arizona->dev->of_node, "ldo1"); 1922cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax dcvdd_node = of_parse_phandle(arizona->dev->of_node, "DCVDD-supply", 0); 1932cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax 1942cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax if (init_node) { 1952cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax config->of_node = init_node; 1962cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax 1972cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax init_data = of_get_regulator_init_data(arizona->dev, init_node); 1982cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax 1992cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax if (init_data) { 2002cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax init_data->consumer_supplies = &ldo1->supply; 2012cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax init_data->num_consumer_supplies = 1; 2022cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax 2032cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax if (dcvdd_node && dcvdd_node != init_node) 2042cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax arizona->external_dcvdd = true; 2052cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax 2062cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax pdata->ldo1 = init_data; 2072cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax } 2082cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax } else if (dcvdd_node) { 2092cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax arizona->external_dcvdd = true; 2102cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax } 2112cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax 2122cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax of_node_put(dcvdd_node); 2132cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax 2144a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax return 0; 2154a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax} 2164a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax 217a5023574d120ca3b9337cedd4e27de90cae9aff7Bill Pembertonstatic int arizona_ldo1_probe(struct platform_device *pdev) 2181910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown{ 2191910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); 22073ee29460e5d0adbb46e4962df69ae2465746612Mark Brown const struct regulator_desc *desc; 2211910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown struct regulator_config config = { }; 2221910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown struct arizona_ldo1 *ldo1; 2231910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown int ret; 2241910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown 2254a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax arizona->external_dcvdd = false; 2264a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax 2271910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL); 228f4a6c5b41ced4737c6b811e295d947a76a41262aSachin Kamat if (!ldo1) 2291910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown return -ENOMEM; 2301910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown 2311910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown ldo1->arizona = arizona; 2321910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown 2331910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown /* 2341910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown * Since the chip usually supplies itself we provide some 2351910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown * default init_data for it. This will be overridden with 2361910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown * platform data if provided. 2371910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown */ 23855a18aef2e963c43d3a0ae20c1dfd404830aa6f9Mark Brown switch (arizona->type) { 23955a18aef2e963c43d3a0ae20c1dfd404830aa6f9Mark Brown case WM5102: 240a35ff2861690eaf9dbb38fa744a8a9e6f4ebfd61Charles Keepax case WM8997: 24173ee29460e5d0adbb46e4962df69ae2465746612Mark Brown desc = &arizona_ldo1_hc; 24255a18aef2e963c43d3a0ae20c1dfd404830aa6f9Mark Brown ldo1->init_data = arizona_ldo1_dvfs; 24355a18aef2e963c43d3a0ae20c1dfd404830aa6f9Mark Brown break; 24455a18aef2e963c43d3a0ae20c1dfd404830aa6f9Mark Brown default: 24573ee29460e5d0adbb46e4962df69ae2465746612Mark Brown desc = &arizona_ldo1; 24655a18aef2e963c43d3a0ae20c1dfd404830aa6f9Mark Brown ldo1->init_data = arizona_ldo1_default; 24755a18aef2e963c43d3a0ae20c1dfd404830aa6f9Mark Brown break; 24855a18aef2e963c43d3a0ae20c1dfd404830aa6f9Mark Brown } 24955a18aef2e963c43d3a0ae20c1dfd404830aa6f9Mark Brown 2501910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown ldo1->init_data.consumer_supplies = &ldo1->supply; 2511910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown ldo1->supply.supply = "DCVDD"; 2521910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown ldo1->supply.dev_name = dev_name(arizona->dev); 2531910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown 2541910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown config.dev = arizona->dev; 2551910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown config.driver_data = ldo1; 2561910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown config.regmap = arizona->regmap; 2574a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax 2584a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax if (IS_ENABLED(CONFIG_OF)) { 2594a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax if (!dev_get_platdata(arizona->dev)) { 2602cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax ret = arizona_ldo1_of_get_pdata(arizona, &config); 2614a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax if (ret < 0) 2624a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax return ret; 2634a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax } 2644a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax } 2654a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax 266a9905b1d6fa80a07997520c7f554aedf3e1b47e7Mark Brown config.ena_gpio = arizona->pdata.ldoena; 2671910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown 2681910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown if (arizona->pdata.ldo1) 2691910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown config.init_data = arizona->pdata.ldo1; 2701910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown else 2711910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown config.init_data = &ldo1->init_data; 2721910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown 2734a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax /* 2744a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax * LDO1 can only be used to supply DCVDD so if it has no 2754a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax * consumers then DCVDD is supplied externally. 2764a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax */ 2774a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax if (config.init_data->num_consumer_supplies == 0) 2784a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax arizona->external_dcvdd = true; 2794a8c475f5fd5c1271dba36a453d666d5ed473aa6Charles Keepax 28014ffa8882bbd991497f2f87ce80382e5a1e6eb8fMark Brown ldo1->regulator = devm_regulator_register(&pdev->dev, desc, &config); 2811910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown if (IS_ERR(ldo1->regulator)) { 2821910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown ret = PTR_ERR(ldo1->regulator); 2831910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown dev_err(arizona->dev, "Failed to register LDO1 supply: %d\n", 2841910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown ret); 2851910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown return ret; 2861910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown } 2871910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown 2882cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax of_node_put(config.of_node); 2892cce4be9e6b885c595816c45a80bcce95dae6d30Charles Keepax 2901910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown platform_set_drvdata(pdev, ldo1); 2911910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown 2921910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown return 0; 2931910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown} 2941910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown 2951910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brownstatic struct platform_driver arizona_ldo1_driver = { 2961910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown .probe = arizona_ldo1_probe, 2971910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown .driver = { 2981910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown .name = "arizona-ldo1", 2991910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown .owner = THIS_MODULE, 3001910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown }, 3011910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown}; 3021910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown 3031910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brownmodule_platform_driver(arizona_ldo1_driver); 3041910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown 3051910efa1d0fdf8109b285d4486f6a0de810b5574Mark Brown/* Module information */ 3061910efa1d0fdf8109b285d4486f6a0de810b5574Mark BrownMODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 3071910efa1d0fdf8109b285d4486f6a0de810b5574Mark BrownMODULE_DESCRIPTION("Arizona LDO1 driver"); 3081910efa1d0fdf8109b285d4486f6a0de810b5574Mark BrownMODULE_LICENSE("GPL"); 3091910efa1d0fdf8109b285d4486f6a0de810b5574Mark BrownMODULE_ALIAS("platform:arizona-ldo1"); 310