diff options
author | Heungjun Kim <riverful.kim@samsung.com> | 2011-02-24 00:40:11 -0500 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-02-24 00:43:31 -0500 |
commit | adf779c1ee1d5556ebd83e39a7189022d4ebce3a (patch) | |
tree | add454348d5a2eca573fa6751fb20d576a5bce8e /drivers/input | |
parent | 5ad567ffbaf208bd35bff4341906346c1a1d4574 (diff) |
Input: mcs_touchkey - add support for suspend/resume
This adds support for system-level suspend/resume to the driver.
Signed-off-by: Heungjun Kim <riverful.kim@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/keyboard/mcs_touchkey.c | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/drivers/input/keyboard/mcs_touchkey.c b/drivers/input/keyboard/mcs_touchkey.c index 63b849d7e90b..03fa59a0b220 100644 --- a/drivers/input/keyboard/mcs_touchkey.c +++ b/drivers/input/keyboard/mcs_touchkey.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * mcs_touchkey.c - Touchkey driver for MELFAS MCS5000/5080 controller | 2 | * Touchkey driver for MELFAS MCS5000/5080 controller |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Samsung Electronics Co.Ltd | 4 | * Copyright (C) 2010 Samsung Electronics Co.Ltd |
5 | * Author: HeungJun Kim <riverful.kim@samsung.com> | 5 | * Author: HeungJun Kim <riverful.kim@samsung.com> |
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/input.h> | 19 | #include <linux/input.h> |
20 | #include <linux/irq.h> | 20 | #include <linux/irq.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/pm.h> | ||
22 | 23 | ||
23 | /* MCS5000 Touchkey */ | 24 | /* MCS5000 Touchkey */ |
24 | #define MCS5000_TOUCHKEY_STATUS 0x04 | 25 | #define MCS5000_TOUCHKEY_STATUS 0x04 |
@@ -45,6 +46,8 @@ struct mcs_touchkey_chip { | |||
45 | }; | 46 | }; |
46 | 47 | ||
47 | struct mcs_touchkey_data { | 48 | struct mcs_touchkey_data { |
49 | void (*poweron)(bool); | ||
50 | |||
48 | struct i2c_client *client; | 51 | struct i2c_client *client; |
49 | struct input_dev *input_dev; | 52 | struct input_dev *input_dev; |
50 | struct mcs_touchkey_chip chip; | 53 | struct mcs_touchkey_chip chip; |
@@ -169,6 +172,11 @@ static int __devinit mcs_touchkey_probe(struct i2c_client *client, | |||
169 | if (pdata->cfg_pin) | 172 | if (pdata->cfg_pin) |
170 | pdata->cfg_pin(); | 173 | pdata->cfg_pin(); |
171 | 174 | ||
175 | if (pdata->poweron) { | ||
176 | data->poweron = pdata->poweron; | ||
177 | data->poweron(true); | ||
178 | } | ||
179 | |||
172 | error = request_threaded_irq(client->irq, NULL, mcs_touchkey_interrupt, | 180 | error = request_threaded_irq(client->irq, NULL, mcs_touchkey_interrupt, |
173 | IRQF_TRIGGER_FALLING, client->dev.driver->name, data); | 181 | IRQF_TRIGGER_FALLING, client->dev.driver->name, data); |
174 | if (error) { | 182 | if (error) { |
@@ -196,12 +204,49 @@ static int __devexit mcs_touchkey_remove(struct i2c_client *client) | |||
196 | struct mcs_touchkey_data *data = i2c_get_clientdata(client); | 204 | struct mcs_touchkey_data *data = i2c_get_clientdata(client); |
197 | 205 | ||
198 | free_irq(client->irq, data); | 206 | free_irq(client->irq, data); |
207 | if (data->poweron) | ||
208 | data->poweron(false); | ||
199 | input_unregister_device(data->input_dev); | 209 | input_unregister_device(data->input_dev); |
200 | kfree(data); | 210 | kfree(data); |
201 | 211 | ||
202 | return 0; | 212 | return 0; |
203 | } | 213 | } |
204 | 214 | ||
215 | #ifdef CONFIG_PM_SLEEP | ||
216 | static int mcs_touchkey_suspend(struct device *dev) | ||
217 | { | ||
218 | struct mcs_touchkey_data *data = dev_get_drvdata(dev); | ||
219 | struct i2c_client *client = data->client; | ||
220 | |||
221 | /* Disable the work */ | ||
222 | disable_irq(client->irq); | ||
223 | |||
224 | /* Finally turn off the power */ | ||
225 | if (data->poweron) | ||
226 | data->poweron(false); | ||
227 | |||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | static int mcs_touchkey_resume(struct device *dev) | ||
232 | { | ||
233 | struct mcs_touchkey_data *data = dev_get_drvdata(dev); | ||
234 | struct i2c_client *client = data->client; | ||
235 | |||
236 | /* Enable the device first */ | ||
237 | if (data->poweron) | ||
238 | data->poweron(true); | ||
239 | |||
240 | /* Enable irq again */ | ||
241 | enable_irq(client->irq); | ||
242 | |||
243 | return 0; | ||
244 | } | ||
245 | #endif | ||
246 | |||
247 | static SIMPLE_DEV_PM_OPS(mcs_touchkey_pm_ops, | ||
248 | mcs_touchkey_suspend, mcs_touchkey_resume); | ||
249 | |||
205 | static const struct i2c_device_id mcs_touchkey_id[] = { | 250 | static const struct i2c_device_id mcs_touchkey_id[] = { |
206 | { "mcs5000_touchkey", MCS5000_TOUCHKEY }, | 251 | { "mcs5000_touchkey", MCS5000_TOUCHKEY }, |
207 | { "mcs5080_touchkey", MCS5080_TOUCHKEY }, | 252 | { "mcs5080_touchkey", MCS5080_TOUCHKEY }, |
@@ -213,6 +258,7 @@ static struct i2c_driver mcs_touchkey_driver = { | |||
213 | .driver = { | 258 | .driver = { |
214 | .name = "mcs_touchkey", | 259 | .name = "mcs_touchkey", |
215 | .owner = THIS_MODULE, | 260 | .owner = THIS_MODULE, |
261 | .pm = &mcs_touchkey_pm_ops, | ||
216 | }, | 262 | }, |
217 | .probe = mcs_touchkey_probe, | 263 | .probe = mcs_touchkey_probe, |
218 | .remove = __devexit_p(mcs_touchkey_remove), | 264 | .remove = __devexit_p(mcs_touchkey_remove), |