aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2015-02-06 01:50:16 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2015-02-15 19:06:29 -0500
commitc8af781ebf3ffe37c18c34ca89e29c085560e561 (patch)
treebc8f55fe4fc75c04191b8f3e5a6c626cc359a11c
parentf14d4df93a6bb5712a92666901198403900790a0 (diff)
Input: bfin_rotary - introduce open and close methods
Introduce open and close methods for the input device to postpone enabling the device until it is needed. Acked-by: Sonic Zhang <sonic.zhang@analog.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r--drivers/input/misc/bfin_rotary.c70
1 files changed, 42 insertions, 28 deletions
diff --git a/drivers/input/misc/bfin_rotary.c b/drivers/input/misc/bfin_rotary.c
index ea8ed9c8dcbe..a0fc18fdfc0c 100644
--- a/drivers/input/misc/bfin_rotary.c
+++ b/drivers/input/misc/bfin_rotary.c
@@ -34,6 +34,10 @@ struct bfin_rot {
34 unsigned int down_key; 34 unsigned int down_key;
35 unsigned int button_key; 35 unsigned int button_key;
36 unsigned int rel_code; 36 unsigned int rel_code;
37
38 unsigned short mode;
39 unsigned short debounce;
40
37 unsigned short cnt_config; 41 unsigned short cnt_config;
38 unsigned short cnt_imask; 42 unsigned short cnt_imask;
39 unsigned short cnt_debounce; 43 unsigned short cnt_debounce;
@@ -92,6 +96,35 @@ static irqreturn_t bfin_rotary_isr(int irq, void *dev_id)
92 return IRQ_HANDLED; 96 return IRQ_HANDLED;
93} 97}
94 98
99static int bfin_rotary_open(struct input_dev *input)
100{
101 struct bfin_rot *rotary = input_get_drvdata(input);
102 unsigned short val;
103
104 if (rotary->mode & ROT_DEBE)
105 writew(rotary->debounce & DPRESCALE,
106 rotary->base + CNT_DEBOUNCE_OFF);
107
108 writew(rotary->mode & ~CNTE, rotary->base + CNT_CONFIG_OFF);
109
110 val = UCIE | DCIE;
111 if (rotary->button_key)
112 val |= CZMIE;
113 writew(val, rotary->base + CNT_IMASK_OFF);
114
115 writew(rotary->mode | CNTE, rotary->base + CNT_CONFIG_OFF);
116
117 return 0;
118}
119
120static void bfin_rotary_close(struct input_dev *input)
121{
122 struct bfin_rot *rotary = input_get_drvdata(input);
123
124 writew(0, rotary->base + CNT_CONFIG_OFF);
125 writew(0, rotary->base + CNT_IMASK_OFF);
126}
127
95static void bfin_rotary_free_action(void *data) 128static void bfin_rotary_free_action(void *data)
96{ 129{
97 peripheral_free_list(data); 130 peripheral_free_list(data);
@@ -151,6 +184,9 @@ static int bfin_rotary_probe(struct platform_device *pdev)
151 rotary->button_key = pdata->rotary_button_key; 184 rotary->button_key = pdata->rotary_button_key;
152 rotary->rel_code = pdata->rotary_rel_code; 185 rotary->rel_code = pdata->rotary_rel_code;
153 186
187 rotary->mode = pdata->mode;
188 rotary->debounce = pdata->debounce;
189
154 input->name = pdev->name; 190 input->name = pdev->name;
155 input->phys = "bfin-rotary/input0"; 191 input->phys = "bfin-rotary/input0";
156 input->dev.parent = &pdev->dev; 192 input->dev.parent = &pdev->dev;
@@ -162,6 +198,9 @@ static int bfin_rotary_probe(struct platform_device *pdev)
162 input->id.product = 0x0001; 198 input->id.product = 0x0001;
163 input->id.version = 0x0100; 199 input->id.version = 0x0100;
164 200
201 input->open = bfin_rotary_open;
202 input->close = bfin_rotary_close;
203
165 if (rotary->up_key) { 204 if (rotary->up_key) {
166 __set_bit(EV_KEY, input->evbit); 205 __set_bit(EV_KEY, input->evbit);
167 __set_bit(rotary->up_key, input->keybit); 206 __set_bit(rotary->up_key, input->keybit);
@@ -176,6 +215,9 @@ static int bfin_rotary_probe(struct platform_device *pdev)
176 __set_bit(rotary->button_key, input->keybit); 215 __set_bit(rotary->button_key, input->keybit);
177 } 216 }
178 217
218 /* Quiesce the device before requesting irq */
219 bfin_rotary_close(input);
220
179 rotary->irq = platform_get_irq(pdev, 0); 221 rotary->irq = platform_get_irq(pdev, 0);
180 if (rotary->irq < 0) { 222 if (rotary->irq < 0) {
181 dev_err(dev, "No rotary IRQ specified\n"); 223 dev_err(dev, "No rotary IRQ specified\n");
@@ -196,39 +238,12 @@ static int bfin_rotary_probe(struct platform_device *pdev)
196 return error; 238 return error;
197 } 239 }
198 240
199 if (pdata->rotary_button_key)
200 writew(CZMIE, rotary->base + CNT_IMASK_OFF);
201
202 if (pdata->mode & ROT_DEBE)
203 writew(pdata->debounce & DPRESCALE,
204 rotary->base + CNT_DEBOUNCE_OFF);
205
206 if (pdata->mode)
207 writew(readw(rotary->base + CNT_CONFIG_OFF) |
208 (pdata->mode & ~CNTE),
209 rotary->base + CNT_CONFIG_OFF);
210
211 writew(readw(rotary->base + CNT_IMASK_OFF) | UCIE | DCIE,
212 rotary->base + CNT_IMASK_OFF);
213 writew(readw(rotary->base + CNT_CONFIG_OFF) | CNTE,
214 rotary->base + CNT_CONFIG_OFF);
215
216 platform_set_drvdata(pdev, rotary); 241 platform_set_drvdata(pdev, rotary);
217 device_init_wakeup(&pdev->dev, 1); 242 device_init_wakeup(&pdev->dev, 1);
218 243
219 return 0; 244 return 0;
220} 245}
221 246
222static int bfin_rotary_remove(struct platform_device *pdev)
223{
224 struct bfin_rot *rotary = platform_get_drvdata(pdev);
225
226 writew(0, rotary->base + CNT_CONFIG_OFF);
227 writew(0, rotary->base + CNT_IMASK_OFF);
228
229 return 0;
230}
231
232static int __maybe_unused bfin_rotary_suspend(struct device *dev) 247static int __maybe_unused bfin_rotary_suspend(struct device *dev)
233{ 248{
234 struct platform_device *pdev = to_platform_device(dev); 249 struct platform_device *pdev = to_platform_device(dev);
@@ -267,7 +282,6 @@ static SIMPLE_DEV_PM_OPS(bfin_rotary_pm_ops,
267 282
268static struct platform_driver bfin_rotary_device_driver = { 283static struct platform_driver bfin_rotary_device_driver = {
269 .probe = bfin_rotary_probe, 284 .probe = bfin_rotary_probe,
270 .remove = bfin_rotary_remove,
271 .driver = { 285 .driver = {
272 .name = "bfin-rotary", 286 .name = "bfin-rotary",
273 .pm = &bfin_rotary_pm_ops, 287 .pm = &bfin_rotary_pm_ops,