diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2015-02-06 01:50:16 -0500 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2015-02-15 19:06:29 -0500 |
commit | c8af781ebf3ffe37c18c34ca89e29c085560e561 (patch) | |
tree | bc8f55fe4fc75c04191b8f3e5a6c626cc359a11c | |
parent | f14d4df93a6bb5712a92666901198403900790a0 (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.c | 70 |
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 | ||
99 | static 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 | |||
120 | static 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 | |||
95 | static void bfin_rotary_free_action(void *data) | 128 | static 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 | ||
222 | static 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 | |||
232 | static int __maybe_unused bfin_rotary_suspend(struct device *dev) | 247 | static 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 | ||
268 | static struct platform_driver bfin_rotary_device_driver = { | 283 | static 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, |