[go: nahoru, domu]

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