tps65090-regulator.c 3.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
/*
 * Regulator driver for tps65090 power management chip.
 *
 * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.

 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.

 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.

 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/mfd/tps65090.h>
#include <linux/regulator/tps65090-regulator.h>

struct tps65090_regulator {
	int		id;
	/* used by regulator core */
	struct regulator_desc	desc;

	/* Device */
	struct device		*dev;
};

static struct regulator_ops tps65090_ops = {
39 40 41
	.enable = regulator_enable_regmap,
	.disable = regulator_disable_regmap,
	.is_enabled = regulator_is_enabled_regmap,
42 43
};

44
#define tps65090_REG(_id)				\
45 46 47 48 49
{							\
	.id		= TPS65090_ID_##_id,		\
	.desc = {					\
		.name = tps65090_rails(_id),		\
		.id = TPS65090_ID_##_id,		\
50
		.ops = &tps65090_ops,			\
51 52
		.type = REGULATOR_VOLTAGE,		\
		.owner = THIS_MODULE,			\
53 54
		.enable_reg = (TPS65090_ID_##_id) + 12,	\
		.enable_mask = BIT(0),			\
55 56 57 58
	},						\
}

static struct tps65090_regulator TPS65090_regulator[] = {
59 60 61 62 63 64 65 66 67 68
	tps65090_REG(DCDC1),
	tps65090_REG(DCDC2),
	tps65090_REG(DCDC3),
	tps65090_REG(FET1),
	tps65090_REG(FET2),
	tps65090_REG(FET3),
	tps65090_REG(FET4),
	tps65090_REG(FET5),
	tps65090_REG(FET6),
	tps65090_REG(FET7),
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
};

static inline struct tps65090_regulator *find_regulator_info(int id)
{
	struct tps65090_regulator *ri;
	int i;

	for (i = 0; i < ARRAY_SIZE(TPS65090_regulator); i++) {
		ri = &TPS65090_regulator[i];
		if (ri->desc.id == id)
			return ri;
	}
	return NULL;
}

static int __devinit tps65090_regulator_probe(struct platform_device *pdev)
{
86
	struct tps65090 *tps65090_mfd = dev_get_drvdata(pdev->dev.parent);
87
	struct tps65090_regulator *ri = NULL;
88
	struct regulator_config config = { };
89 90 91 92 93 94 95 96 97 98 99 100 101 102
	struct regulator_dev *rdev;
	struct tps65090_regulator_platform_data *tps_pdata;
	int id = pdev->id;

	dev_dbg(&pdev->dev, "Probing regulator %d\n", id);

	ri = find_regulator_info(id);
	if (ri == NULL) {
		dev_err(&pdev->dev, "invalid regulator ID specified\n");
		return -EINVAL;
	}
	tps_pdata = pdev->dev.platform_data;
	ri->dev = &pdev->dev;

103 104 105
	config.dev = &pdev->dev;
	config.init_data = &tps_pdata->regulator;
	config.driver_data = ri;
106
	config.regmap = tps65090_mfd->rmap;
107 108

	rdev = regulator_register(&ri->desc, &config);
109
	if (IS_ERR(rdev)) {
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
		dev_err(&pdev->dev, "failed to register regulator %s\n",
				ri->desc.name);
		return PTR_ERR(rdev);
	}

	platform_set_drvdata(pdev, rdev);
	return 0;
}

static int __devexit tps65090_regulator_remove(struct platform_device *pdev)
{
	struct regulator_dev *rdev = platform_get_drvdata(pdev);

	regulator_unregister(rdev);
	return 0;
}

static struct platform_driver tps65090_regulator_driver = {
	.driver	= {
		.name	= "tps65090-regulator",
		.owner	= THIS_MODULE,
	},
	.probe		= tps65090_regulator_probe,
	.remove		= __devexit_p(tps65090_regulator_remove),
};

static int __init tps65090_regulator_init(void)
{
	return platform_driver_register(&tps65090_regulator_driver);
}
subsys_initcall(tps65090_regulator_init);

static void __exit tps65090_regulator_exit(void)
{
	platform_driver_unregister(&tps65090_regulator_driver);
}
module_exit(tps65090_regulator_exit);

MODULE_DESCRIPTION("tps65090 regulator driver");
MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>");
MODULE_LICENSE("GPL v2");