Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pcf50633-input.c
Go to the documentation of this file.
1 /* NXP PCF50633 Input Driver
2  *
3  * (C) 2006-2008 by Openmoko, Inc.
4  * Author: Balaji Rao <[email protected]>
5  * All rights reserved.
6  *
7  * Broken down from monstrous PCF50633 driver mainly by
8  * Harald Welte, Andy Green and Werner Almesberger
9  *
10  * This program is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU General Public License as published by the
12  * Free Software Foundation; either version 2 of the License, or (at your
13  * option) any later version.
14  *
15  */
16 
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/init.h>
20 #include <linux/device.h>
21 #include <linux/platform_device.h>
22 #include <linux/input.h>
23 #include <linux/slab.h>
24 
26 
27 #define PCF50633_OOCSTAT_ONKEY 0x01
28 #define PCF50633_REG_OOCSTAT 0x12
29 #define PCF50633_REG_OOCMODE 0x10
30 
32  struct pcf50633 *pcf;
34 };
35 
36 static void
37 pcf50633_input_irq(int irq, void *data)
38 {
39  struct pcf50633_input *input;
40  int onkey_released;
41 
42  input = data;
43 
44  /* We report only one event depending on the key press status */
45  onkey_released = pcf50633_reg_read(input->pcf, PCF50633_REG_OOCSTAT)
47 
48  if (irq == PCF50633_IRQ_ONKEYF && !onkey_released)
49  input_report_key(input->input_dev, KEY_POWER, 1);
50  else if (irq == PCF50633_IRQ_ONKEYR && onkey_released)
51  input_report_key(input->input_dev, KEY_POWER, 0);
52 
53  input_sync(input->input_dev);
54 }
55 
56 static int __devinit pcf50633_input_probe(struct platform_device *pdev)
57 {
58  struct pcf50633_input *input;
59  struct input_dev *input_dev;
60  int ret;
61 
62 
63  input = kzalloc(sizeof(*input), GFP_KERNEL);
64  if (!input)
65  return -ENOMEM;
66 
67  input_dev = input_allocate_device();
68  if (!input_dev) {
69  kfree(input);
70  return -ENOMEM;
71  }
72 
73  platform_set_drvdata(pdev, input);
74  input->pcf = dev_to_pcf50633(pdev->dev.parent);
75  input->input_dev = input_dev;
76 
77  input_dev->name = "PCF50633 PMU events";
78  input_dev->id.bustype = BUS_I2C;
79  input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_PWR);
80  set_bit(KEY_POWER, input_dev->keybit);
81 
82  ret = input_register_device(input_dev);
83  if (ret) {
84  input_free_device(input_dev);
85  kfree(input);
86  return ret;
87  }
89  pcf50633_input_irq, input);
91  pcf50633_input_irq, input);
92 
93  return 0;
94 }
95 
96 static int __devexit pcf50633_input_remove(struct platform_device *pdev)
97 {
98  struct pcf50633_input *input = platform_get_drvdata(pdev);
99 
102 
103  input_unregister_device(input->input_dev);
104  kfree(input);
105 
106  return 0;
107 }
108 
109 static struct platform_driver pcf50633_input_driver = {
110  .driver = {
111  .name = "pcf50633-input",
112  },
113  .probe = pcf50633_input_probe,
114  .remove = __devexit_p(pcf50633_input_remove),
115 };
116 module_platform_driver(pcf50633_input_driver);
117 
118 MODULE_AUTHOR("Balaji Rao <[email protected]>");
119 MODULE_DESCRIPTION("PCF50633 input driver");
120 MODULE_LICENSE("GPL");
121 MODULE_ALIAS("platform:pcf50633-input");