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>
23 #include <linux/mfd/wm831x/core.h>
24 #include <linux/mfd/wm831x/regulator.h>
25 #include <linux/mfd/wm831x/pdata.h>
27 #define WM831X_ISINK_MAX_NAME 7
30 char name
[WM831X_ISINK_MAX_NAME
];
31 struct regulator_desc desc
;
33 struct wm831x
*wm831x
;
34 struct regulator_dev
*regulator
;
37 static int wm831x_isink_enable(struct regulator_dev
*rdev
)
39 struct wm831x_isink
*isink
= rdev_get_drvdata(rdev
);
40 struct wm831x
*wm831x
= isink
->wm831x
;
43 /* We have a two stage enable: first start the ISINK... */
44 ret
= wm831x_set_bits(wm831x
, isink
->reg
, WM831X_CS1_ENA
,
49 /* ...then enable drive */
50 ret
= wm831x_set_bits(wm831x
, isink
->reg
, WM831X_CS1_DRIVE
,
53 wm831x_set_bits(wm831x
, isink
->reg
, WM831X_CS1_ENA
, 0);
59 static int wm831x_isink_disable(struct regulator_dev
*rdev
)
61 struct wm831x_isink
*isink
= rdev_get_drvdata(rdev
);
62 struct wm831x
*wm831x
= isink
->wm831x
;
65 ret
= wm831x_set_bits(wm831x
, isink
->reg
, WM831X_CS1_DRIVE
, 0);
69 ret
= wm831x_set_bits(wm831x
, isink
->reg
, WM831X_CS1_ENA
, 0);
77 static int wm831x_isink_is_enabled(struct regulator_dev
*rdev
)
79 struct wm831x_isink
*isink
= rdev_get_drvdata(rdev
);
80 struct wm831x
*wm831x
= isink
->wm831x
;
83 ret
= wm831x_reg_read(wm831x
, isink
->reg
);
87 if ((ret
& (WM831X_CS1_ENA
| WM831X_CS1_DRIVE
)) ==
88 (WM831X_CS1_ENA
| WM831X_CS1_DRIVE
))
94 static int wm831x_isink_set_current(struct regulator_dev
*rdev
,
95 int min_uA
, int max_uA
)
97 struct wm831x_isink
*isink
= rdev_get_drvdata(rdev
);
98 struct wm831x
*wm831x
= isink
->wm831x
;
101 for (i
= 0; i
< ARRAY_SIZE(wm831x_isinkv_values
); i
++) {
102 int val
= wm831x_isinkv_values
[i
];
103 if (min_uA
>= val
&& val
<= max_uA
) {
104 ret
= wm831x_set_bits(wm831x
, isink
->reg
,
105 WM831X_CS1_ISEL_MASK
, i
);
113 static int wm831x_isink_get_current(struct regulator_dev
*rdev
)
115 struct wm831x_isink
*isink
= rdev_get_drvdata(rdev
);
116 struct wm831x
*wm831x
= isink
->wm831x
;
119 ret
= wm831x_reg_read(wm831x
, isink
->reg
);
123 ret
&= WM831X_CS1_ISEL_MASK
;
124 if (ret
> WM831X_ISINK_MAX_ISEL
)
125 ret
= WM831X_ISINK_MAX_ISEL
;
127 return wm831x_isinkv_values
[ret
];
130 static struct regulator_ops wm831x_isink_ops
= {
131 .is_enabled
= wm831x_isink_is_enabled
,
132 .enable
= wm831x_isink_enable
,
133 .disable
= wm831x_isink_disable
,
134 .set_current_limit
= wm831x_isink_set_current
,
135 .get_current_limit
= wm831x_isink_get_current
,
138 static irqreturn_t
wm831x_isink_irq(int irq
, void *data
)
140 struct wm831x_isink
*isink
= data
;
142 regulator_notifier_call_chain(isink
->regulator
,
143 REGULATOR_EVENT_OVER_CURRENT
,
150 static __devinit
int wm831x_isink_probe(struct platform_device
*pdev
)
152 struct wm831x
*wm831x
= dev_get_drvdata(pdev
->dev
.parent
);
153 struct wm831x_pdata
*pdata
= wm831x
->dev
->platform_data
;
154 struct wm831x_isink
*isink
;
155 int id
= pdev
->id
% ARRAY_SIZE(pdata
->isink
);
156 struct resource
*res
;
159 dev_dbg(&pdev
->dev
, "Probing ISINK%d\n", id
+ 1);
161 if (pdata
== NULL
|| pdata
->isink
[id
] == NULL
)
164 isink
= kzalloc(sizeof(struct wm831x_isink
), GFP_KERNEL
);
166 dev_err(&pdev
->dev
, "Unable to allocate private data\n");
170 res
= platform_get_resource(pdev
, IORESOURCE_IO
, 0);
172 dev_err(&pdev
->dev
, "No I/O resource\n");
176 isink
->reg
= res
->start
;
178 /* For current parts this is correct; probably need to revisit
181 snprintf(isink
->name
, sizeof(isink
->name
), "ISINK%d", id
+ 1);
182 isink
->desc
.name
= isink
->name
;
184 isink
->desc
.ops
= &wm831x_isink_ops
;
185 isink
->desc
.type
= REGULATOR_CURRENT
;
186 isink
->desc
.owner
= THIS_MODULE
;
188 isink
->regulator
= regulator_register(&isink
->desc
, &pdev
->dev
,
189 pdata
->isink
[id
], isink
);
190 if (IS_ERR(isink
->regulator
)) {
191 ret
= PTR_ERR(isink
->regulator
);
192 dev_err(wm831x
->dev
, "Failed to register ISINK%d: %d\n",
197 irq
= platform_get_irq(pdev
, 0);
198 ret
= wm831x_request_irq(wm831x
, irq
, wm831x_isink_irq
,
199 IRQF_TRIGGER_RISING
, isink
->name
,
202 dev_err(&pdev
->dev
, "Failed to request ISINK IRQ %d: %d\n",
207 platform_set_drvdata(pdev
, isink
);
212 regulator_unregister(isink
->regulator
);
218 static __devexit
int wm831x_isink_remove(struct platform_device
*pdev
)
220 struct wm831x_isink
*isink
= platform_get_drvdata(pdev
);
221 struct wm831x
*wm831x
= isink
->wm831x
;
223 wm831x_free_irq(wm831x
, platform_get_irq(pdev
, 0), isink
);
225 regulator_unregister(isink
->regulator
);
231 static struct platform_driver wm831x_isink_driver
= {
232 .probe
= wm831x_isink_probe
,
233 .remove
= __devexit_p(wm831x_isink_remove
),
235 .name
= "wm831x-isink",
239 static int __init
wm831x_isink_init(void)
242 ret
= platform_driver_register(&wm831x_isink_driver
);
244 pr_err("Failed to register WM831x ISINK driver: %d\n", ret
);
248 subsys_initcall(wm831x_isink_init
);
250 static void __exit
wm831x_isink_exit(void)
252 platform_driver_unregister(&wm831x_isink_driver
);
254 module_exit(wm831x_isink_exit
);
256 /* Module information */
257 MODULE_AUTHOR("Mark Brown");
258 MODULE_DESCRIPTION("WM831x current sink driver");
259 MODULE_LICENSE("GPL");
260 MODULE_ALIAS("platform:wm831x-isink");