2 * wm831x-isink.c -- Current sink driver for the WM831x series
4 * Copyright 2009 Wolfson Microelectronics PLC.
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
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.
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/i2c.h>
20 #include <linux/platform_device.h>
21 #include <linux/regulator/driver.h>
22 #include <linux/slab.h>
24 #include <linux/mfd/wm831x/core.h>
25 #include <linux/mfd/wm831x/regulator.h>
26 #include <linux/mfd/wm831x/pdata.h>
28 #define WM831X_ISINK_MAX_NAME 7
31 char name
[WM831X_ISINK_MAX_NAME
];
32 struct regulator_desc desc
;
34 struct wm831x
*wm831x
;
35 struct regulator_dev
*regulator
;
38 static int wm831x_isink_enable(struct regulator_dev
*rdev
)
40 struct wm831x_isink
*isink
= rdev_get_drvdata(rdev
);
41 struct wm831x
*wm831x
= isink
->wm831x
;
44 /* We have a two stage enable: first start the ISINK... */
45 ret
= wm831x_set_bits(wm831x
, isink
->reg
, WM831X_CS1_ENA
,
50 /* ...then enable drive */
51 ret
= wm831x_set_bits(wm831x
, isink
->reg
, WM831X_CS1_DRIVE
,
54 wm831x_set_bits(wm831x
, isink
->reg
, WM831X_CS1_ENA
, 0);
60 static int wm831x_isink_disable(struct regulator_dev
*rdev
)
62 struct wm831x_isink
*isink
= rdev_get_drvdata(rdev
);
63 struct wm831x
*wm831x
= isink
->wm831x
;
66 ret
= wm831x_set_bits(wm831x
, isink
->reg
, WM831X_CS1_DRIVE
, 0);
70 ret
= wm831x_set_bits(wm831x
, isink
->reg
, WM831X_CS1_ENA
, 0);
78 static int wm831x_isink_is_enabled(struct regulator_dev
*rdev
)
80 struct wm831x_isink
*isink
= rdev_get_drvdata(rdev
);
81 struct wm831x
*wm831x
= isink
->wm831x
;
84 ret
= wm831x_reg_read(wm831x
, isink
->reg
);
88 if ((ret
& (WM831X_CS1_ENA
| WM831X_CS1_DRIVE
)) ==
89 (WM831X_CS1_ENA
| WM831X_CS1_DRIVE
))
95 static int wm831x_isink_set_current(struct regulator_dev
*rdev
,
96 int min_uA
, int max_uA
)
98 struct wm831x_isink
*isink
= rdev_get_drvdata(rdev
);
99 struct wm831x
*wm831x
= isink
->wm831x
;
102 for (i
= 0; i
< ARRAY_SIZE(wm831x_isinkv_values
); i
++) {
103 int val
= wm831x_isinkv_values
[i
];
104 if (min_uA
<= val
&& val
<= max_uA
) {
105 ret
= wm831x_set_bits(wm831x
, isink
->reg
,
106 WM831X_CS1_ISEL_MASK
, i
);
114 static int wm831x_isink_get_current(struct regulator_dev
*rdev
)
116 struct wm831x_isink
*isink
= rdev_get_drvdata(rdev
);
117 struct wm831x
*wm831x
= isink
->wm831x
;
120 ret
= wm831x_reg_read(wm831x
, isink
->reg
);
124 ret
&= WM831X_CS1_ISEL_MASK
;
125 if (ret
> WM831X_ISINK_MAX_ISEL
)
126 ret
= WM831X_ISINK_MAX_ISEL
;
128 return wm831x_isinkv_values
[ret
];
131 static struct regulator_ops wm831x_isink_ops
= {
132 .is_enabled
= wm831x_isink_is_enabled
,
133 .enable
= wm831x_isink_enable
,
134 .disable
= wm831x_isink_disable
,
135 .set_current_limit
= wm831x_isink_set_current
,
136 .get_current_limit
= wm831x_isink_get_current
,
139 static irqreturn_t
wm831x_isink_irq(int irq
, void *data
)
141 struct wm831x_isink
*isink
= data
;
143 regulator_notifier_call_chain(isink
->regulator
,
144 REGULATOR_EVENT_OVER_CURRENT
,
151 static int wm831x_isink_probe(struct platform_device
*pdev
)
153 struct wm831x
*wm831x
= dev_get_drvdata(pdev
->dev
.parent
);
154 struct wm831x_pdata
*pdata
= wm831x
->dev
->platform_data
;
155 struct wm831x_isink
*isink
;
156 int id
= pdev
->id
% ARRAY_SIZE(pdata
->isink
);
157 struct regulator_config config
= { };
158 struct resource
*res
;
161 dev_dbg(&pdev
->dev
, "Probing ISINK%d\n", id
+ 1);
163 if (pdata
== NULL
|| pdata
->isink
[id
] == NULL
)
166 isink
= devm_kzalloc(&pdev
->dev
, sizeof(struct wm831x_isink
),
169 dev_err(&pdev
->dev
, "Unable to allocate private data\n");
173 isink
->wm831x
= wm831x
;
175 res
= platform_get_resource(pdev
, IORESOURCE_REG
, 0);
177 dev_err(&pdev
->dev
, "No REG resource\n");
181 isink
->reg
= res
->start
;
183 /* For current parts this is correct; probably need to revisit
186 snprintf(isink
->name
, sizeof(isink
->name
), "ISINK%d", id
+ 1);
187 isink
->desc
.name
= isink
->name
;
189 isink
->desc
.ops
= &wm831x_isink_ops
;
190 isink
->desc
.type
= REGULATOR_CURRENT
;
191 isink
->desc
.owner
= THIS_MODULE
;
193 config
.dev
= pdev
->dev
.parent
;
194 config
.init_data
= pdata
->isink
[id
];
195 config
.driver_data
= isink
;
197 isink
->regulator
= regulator_register(&isink
->desc
, &config
);
198 if (IS_ERR(isink
->regulator
)) {
199 ret
= PTR_ERR(isink
->regulator
);
200 dev_err(wm831x
->dev
, "Failed to register ISINK%d: %d\n",
205 irq
= wm831x_irq(wm831x
, platform_get_irq(pdev
, 0));
206 ret
= request_threaded_irq(irq
, NULL
, wm831x_isink_irq
,
207 IRQF_TRIGGER_RISING
, isink
->name
, isink
);
209 dev_err(&pdev
->dev
, "Failed to request ISINK IRQ %d: %d\n",
214 platform_set_drvdata(pdev
, isink
);
219 regulator_unregister(isink
->regulator
);
224 static int wm831x_isink_remove(struct platform_device
*pdev
)
226 struct wm831x_isink
*isink
= platform_get_drvdata(pdev
);
228 free_irq(wm831x_irq(isink
->wm831x
, platform_get_irq(pdev
, 0)), isink
);
230 regulator_unregister(isink
->regulator
);
235 static struct platform_driver wm831x_isink_driver
= {
236 .probe
= wm831x_isink_probe
,
237 .remove
= wm831x_isink_remove
,
239 .name
= "wm831x-isink",
240 .owner
= THIS_MODULE
,
244 static int __init
wm831x_isink_init(void)
247 ret
= platform_driver_register(&wm831x_isink_driver
);
249 pr_err("Failed to register WM831x ISINK driver: %d\n", ret
);
253 subsys_initcall(wm831x_isink_init
);
255 static void __exit
wm831x_isink_exit(void)
257 platform_driver_unregister(&wm831x_isink_driver
);
259 module_exit(wm831x_isink_exit
);
261 /* Module information */
262 MODULE_AUTHOR("Mark Brown");
263 MODULE_DESCRIPTION("WM831x current sink driver");
264 MODULE_LICENSE("GPL");
265 MODULE_ALIAS("platform:wm831x-isink");