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, |
