Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
wm8994-regulator.c
Go to the documentation of this file.
1 /*
2  * wm8994-regulator.c -- Regulator driver for the WM8994
3  *
4  * Copyright 2009 Wolfson Microelectronics PLC.
5  *
6  * Author: Mark Brown <[email protected]>
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation; either version 2 of the License, or (at your
11  * option) any later version.
12  */
13 
14 #include <linux/module.h>
15 #include <linux/moduleparam.h>
16 #include <linux/init.h>
17 #include <linux/bitops.h>
18 #include <linux/err.h>
19 #include <linux/platform_device.h>
20 #include <linux/regulator/driver.h>
21 #include <linux/gpio.h>
22 #include <linux/slab.h>
23 
24 #include <linux/mfd/wm8994/core.h>
26 #include <linux/mfd/wm8994/pdata.h>
27 
28 struct wm8994_ldo {
30  struct wm8994 *wm8994;
31 };
32 
33 #define WM8994_LDO1_MAX_SELECTOR 0x7
34 #define WM8994_LDO2_MAX_SELECTOR 0x3
35 
36 static struct regulator_ops wm8994_ldo1_ops = {
37  .list_voltage = regulator_list_voltage_linear,
38  .map_voltage = regulator_map_voltage_linear,
39  .get_voltage_sel = regulator_get_voltage_sel_regmap,
40  .set_voltage_sel = regulator_set_voltage_sel_regmap,
41 };
42 
43 static int wm8994_ldo2_list_voltage(struct regulator_dev *rdev,
44  unsigned int selector)
45 {
46  struct wm8994_ldo *ldo = rdev_get_drvdata(rdev);
47 
48  if (selector > WM8994_LDO2_MAX_SELECTOR)
49  return -EINVAL;
50 
51  switch (ldo->wm8994->type) {
52  case WM8994:
53  return (selector * 100000) + 900000;
54  case WM8958:
55  return (selector * 100000) + 1000000;
56  case WM1811:
57  switch (selector) {
58  case 0:
59  return -EINVAL;
60  default:
61  return (selector * 100000) + 950000;
62  }
63  break;
64  default:
65  return -EINVAL;
66  }
67 }
68 
69 static struct regulator_ops wm8994_ldo2_ops = {
70  .list_voltage = wm8994_ldo2_list_voltage,
71  .get_voltage_sel = regulator_get_voltage_sel_regmap,
72  .set_voltage_sel = regulator_set_voltage_sel_regmap,
73 };
74 
75 static const struct regulator_desc wm8994_ldo_desc[] = {
76  {
77  .name = "LDO1",
78  .id = 1,
79  .type = REGULATOR_VOLTAGE,
80  .n_voltages = WM8994_LDO1_MAX_SELECTOR + 1,
81  .vsel_reg = WM8994_LDO_1,
82  .vsel_mask = WM8994_LDO1_VSEL_MASK,
83  .ops = &wm8994_ldo1_ops,
84  .min_uV = 2400000,
85  .uV_step = 100000,
86  .enable_time = 3000,
87  .owner = THIS_MODULE,
88  },
89  {
90  .name = "LDO2",
91  .id = 2,
92  .type = REGULATOR_VOLTAGE,
93  .n_voltages = WM8994_LDO2_MAX_SELECTOR + 1,
94  .vsel_reg = WM8994_LDO_2,
95  .vsel_mask = WM8994_LDO2_VSEL_MASK,
96  .ops = &wm8994_ldo2_ops,
97  .enable_time = 3000,
98  .owner = THIS_MODULE,
99  },
100 };
101 
102 static __devinit int wm8994_ldo_probe(struct platform_device *pdev)
103 {
104  struct wm8994 *wm8994 = dev_get_drvdata(pdev->dev.parent);
105  struct wm8994_pdata *pdata = wm8994->dev->platform_data;
106  int id = pdev->id % ARRAY_SIZE(pdata->ldo);
107  struct regulator_config config = { };
108  struct wm8994_ldo *ldo;
109  int ret;
110 
111  dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
112 
113  ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm8994_ldo), GFP_KERNEL);
114  if (ldo == NULL) {
115  dev_err(&pdev->dev, "Unable to allocate private data\n");
116  return -ENOMEM;
117  }
118 
119  ldo->wm8994 = wm8994;
120 
121  config.dev = wm8994->dev;
122  config.driver_data = ldo;
123  config.regmap = wm8994->regmap;
124  if (pdata) {
125  config.init_data = pdata->ldo[id].init_data;
126  config.ena_gpio = pdata->ldo[id].enable;
127  }
128 
129  ldo->regulator = regulator_register(&wm8994_ldo_desc[id], &config);
130  if (IS_ERR(ldo->regulator)) {
131  ret = PTR_ERR(ldo->regulator);
132  dev_err(wm8994->dev, "Failed to register LDO%d: %d\n",
133  id + 1, ret);
134  goto err;
135  }
136 
137  platform_set_drvdata(pdev, ldo);
138 
139  return 0;
140 
141 err:
142  return ret;
143 }
144 
145 static __devexit int wm8994_ldo_remove(struct platform_device *pdev)
146 {
147  struct wm8994_ldo *ldo = platform_get_drvdata(pdev);
148 
149  platform_set_drvdata(pdev, NULL);
150 
152 
153  return 0;
154 }
155 
156 static struct platform_driver wm8994_ldo_driver = {
157  .probe = wm8994_ldo_probe,
158  .remove = __devexit_p(wm8994_ldo_remove),
159  .driver = {
160  .name = "wm8994-ldo",
161  .owner = THIS_MODULE,
162  },
163 };
164 
165 static int __init wm8994_ldo_init(void)
166 {
167  int ret;
168 
169  ret = platform_driver_register(&wm8994_ldo_driver);
170  if (ret != 0)
171  pr_err("Failed to register Wm8994 GP LDO driver: %d\n", ret);
172 
173  return ret;
174 }
175 subsys_initcall(wm8994_ldo_init);
176 
177 static void __exit wm8994_ldo_exit(void)
178 {
179  platform_driver_unregister(&wm8994_ldo_driver);
180 }
181 module_exit(wm8994_ldo_exit);
182 
183 /* Module information */
184 MODULE_AUTHOR("Mark Brown <[email protected]>");
185 MODULE_DESCRIPTION("WM8994 LDO driver");
186 MODULE_LICENSE("GPL");
187 MODULE_ALIAS("platform:wm8994-ldo");