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 __devinit
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 resource
*res
;
160 dev_dbg(&pdev
->dev
, "Probing ISINK%d\n", id
+ 1);
162 if (pdata
== NULL
|| pdata
->isink
[id
] == NULL
)
165 isink
= devm_kzalloc(&pdev
->dev
, sizeof(struct wm831x_isink
),
168 dev_err(&pdev
->dev
, "Unable to allocate private data\n");
172 isink
->wm831x
= wm831x
;
174 res
= platform_get_resource(pdev
, IORESOURCE_IO
, 0);
176 dev_err(&pdev
->dev
, "No I/O resource\n");
180 isink
->reg
= res
->start
;
182 /* For current parts this is correct; probably need to revisit
185 snprintf(isink
->name
, sizeof(isink
->name
), "ISINK%d", id
+ 1);
186 isink
->desc
.name
= isink
->name
;
188 isink
->desc
.ops
= &wm831x_isink_ops
;
189 isink
->desc
.type
= REGULATOR_CURRENT
;
190 isink
->desc
.owner
= THIS_MODULE
;
192 isink
->regulator
= regulator_register(&isink
->desc
, &pdev
->dev
,
193 pdata
->isink
[id
], isink
, NULL
);
194 if (IS_ERR(isink
->regulator
)) {
195 ret
= PTR_ERR(isink
->regulator
);
196 dev_err(wm831x
->dev
, "Failed to register ISINK%d: %d\n",
201 irq
= platform_get_irq(pdev
, 0);
202 ret
= request_threaded_irq(irq
, NULL
, wm831x_isink_irq
,
203 IRQF_TRIGGER_RISING
, isink
->name
, isink
);
205 dev_err(&pdev
->dev
, "Failed to request ISINK IRQ %d: %d\n",
210 platform_set_drvdata(pdev
, isink
);
215 regulator_unregister(isink
->regulator
);
220 static __devexit
int wm831x_isink_remove(struct platform_device
*pdev
)
222 struct wm831x_isink
*isink
= platform_get_drvdata(pdev
);
224 platform_set_drvdata(pdev
, NULL
);
226 free_irq(platform_get_irq(pdev
, 0), isink
);
228 regulator_unregister(isink
->regulator
);
233 static struct platform_driver wm831x_isink_driver
= {
234 .probe
= wm831x_isink_probe
,
235 .remove
= __devexit_p(wm831x_isink_remove
),
237 .name
= "wm831x-isink",
238 .owner
= THIS_MODULE
,
242 static int __init
wm831x_isink_init(void)
245 ret
= platform_driver_register(&wm831x_isink_driver
);
247 pr_err("Failed to register WM831x ISINK driver: %d\n", ret
);
251 subsys_initcall(wm831x_isink_init
);
253 static void __exit
wm831x_isink_exit(void)
255 platform_driver_unregister(&wm831x_isink_driver
);
257 module_exit(wm831x_isink_exit
);
259 /* Module information */
260 MODULE_AUTHOR("Mark Brown");
261 MODULE_DESCRIPTION("WM831x current sink driver");
262 MODULE_LICENSE("GPL");
263 MODULE_ALIAS("platform:wm831x-isink");