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
= kzalloc(sizeof(struct wm831x_isink
), GFP_KERNEL
);
167 dev_err(&pdev
->dev
, "Unable to allocate private data\n");
171 isink
->wm831x
= wm831x
;
173 res
= platform_get_resource(pdev
, IORESOURCE_IO
, 0);
175 dev_err(&pdev
->dev
, "No I/O resource\n");
179 isink
->reg
= res
->start
;
181 /* For current parts this is correct; probably need to revisit
184 snprintf(isink
->name
, sizeof(isink
->name
), "ISINK%d", id
+ 1);
185 isink
->desc
.name
= isink
->name
;
187 isink
->desc
.ops
= &wm831x_isink_ops
;
188 isink
->desc
.type
= REGULATOR_CURRENT
;
189 isink
->desc
.owner
= THIS_MODULE
;
191 isink
->regulator
= regulator_register(&isink
->desc
, &pdev
->dev
,
192 pdata
->isink
[id
], isink
);
193 if (IS_ERR(isink
->regulator
)) {
194 ret
= PTR_ERR(isink
->regulator
);
195 dev_err(wm831x
->dev
, "Failed to register ISINK%d: %d\n",
200 irq
= platform_get_irq(pdev
, 0);
201 ret
= wm831x_request_irq(wm831x
, irq
, wm831x_isink_irq
,
202 IRQF_TRIGGER_RISING
, isink
->name
,
205 dev_err(&pdev
->dev
, "Failed to request ISINK IRQ %d: %d\n",
210 platform_set_drvdata(pdev
, isink
);
215 regulator_unregister(isink
->regulator
);
221 static __devexit
int wm831x_isink_remove(struct platform_device
*pdev
)
223 struct wm831x_isink
*isink
= platform_get_drvdata(pdev
);
224 struct wm831x
*wm831x
= isink
->wm831x
;
226 platform_set_drvdata(pdev
, NULL
);
228 wm831x_free_irq(wm831x
, platform_get_irq(pdev
, 0), isink
);
230 regulator_unregister(isink
->regulator
);
236 static struct platform_driver wm831x_isink_driver
= {
237 .probe
= wm831x_isink_probe
,
238 .remove
= __devexit_p(wm831x_isink_remove
),
240 .name
= "wm831x-isink",
241 .owner
= THIS_MODULE
,
245 static int __init
wm831x_isink_init(void)
248 ret
= platform_driver_register(&wm831x_isink_driver
);
250 pr_err("Failed to register WM831x ISINK driver: %d\n", ret
);
254 subsys_initcall(wm831x_isink_init
);
256 static void __exit
wm831x_isink_exit(void)
258 platform_driver_unregister(&wm831x_isink_driver
);
260 module_exit(wm831x_isink_exit
);
262 /* Module information */
263 MODULE_AUTHOR("Mark Brown");
264 MODULE_DESCRIPTION("WM831x current sink driver");
265 MODULE_LICENSE("GPL");
266 MODULE_ALIAS("platform:wm831x-isink");