hwmon: (acpi_power_meter) Fix acpi_bus_get_device() return value check
[linux-drm-fsl-dcu.git] / drivers / media / rc / gpio-ir-recv.c
1 /* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 and
5  * only version 2 as published by the Free Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  */
12
13 #include <linux/kernel.h>
14 #include <linux/init.h>
15 #include <linux/module.h>
16 #include <linux/interrupt.h>
17 #include <linux/gpio.h>
18 #include <linux/slab.h>
19 #include <linux/of_gpio.h>
20 #include <linux/platform_device.h>
21 #include <linux/irq.h>
22 #include <media/rc-core.h>
23 #include <media/gpio-ir-recv.h>
24
25 #define GPIO_IR_DRIVER_NAME     "gpio-rc-recv"
26 #define GPIO_IR_DEVICE_NAME     "gpio_ir_recv"
27
28 struct gpio_rc_dev {
29         struct rc_dev *rcdev;
30         int gpio_nr;
31         bool active_low;
32 };
33
34 #ifdef CONFIG_OF
35 /*
36  * Translate OpenFirmware node properties into platform_data
37  */
38 static int gpio_ir_recv_get_devtree_pdata(struct device *dev,
39                                   struct gpio_ir_recv_platform_data *pdata)
40 {
41         struct device_node *np = dev->of_node;
42         enum of_gpio_flags flags;
43         int gpio;
44
45         gpio = of_get_gpio_flags(np, 0, &flags);
46         if (gpio < 0) {
47                 if (gpio != -EPROBE_DEFER)
48                         dev_err(dev, "Failed to get gpio flags (%d)\n", gpio);
49                 return gpio;
50         }
51
52         pdata->gpio_nr = gpio;
53         pdata->active_low = (flags & OF_GPIO_ACTIVE_LOW);
54         /* probe() takes care of map_name == NULL or allowed_protos == 0 */
55         pdata->map_name = of_get_property(np, "linux,rc-map-name", NULL);
56         pdata->allowed_protos = 0;
57
58         return 0;
59 }
60
61 static struct of_device_id gpio_ir_recv_of_match[] = {
62         { .compatible = "gpio-ir-receiver", },
63         { },
64 };
65 MODULE_DEVICE_TABLE(of, gpio_ir_recv_of_match);
66
67 #else /* !CONFIG_OF */
68
69 #define gpio_ir_recv_get_devtree_pdata(dev, pdata)      (-ENOSYS)
70
71 #endif
72
73 static irqreturn_t gpio_ir_recv_irq(int irq, void *dev_id)
74 {
75         struct gpio_rc_dev *gpio_dev = dev_id;
76         int gval;
77         int rc = 0;
78         enum raw_event_type type = IR_SPACE;
79
80         gval = gpio_get_value_cansleep(gpio_dev->gpio_nr);
81
82         if (gval < 0)
83                 goto err_get_value;
84
85         if (gpio_dev->active_low)
86                 gval = !gval;
87
88         if (gval == 1)
89                 type = IR_PULSE;
90
91         rc = ir_raw_event_store_edge(gpio_dev->rcdev, type);
92         if (rc < 0)
93                 goto err_get_value;
94
95         ir_raw_event_handle(gpio_dev->rcdev);
96
97 err_get_value:
98         return IRQ_HANDLED;
99 }
100
101 static int gpio_ir_recv_probe(struct platform_device *pdev)
102 {
103         struct gpio_rc_dev *gpio_dev;
104         struct rc_dev *rcdev;
105         const struct gpio_ir_recv_platform_data *pdata =
106                                         pdev->dev.platform_data;
107         int rc;
108
109         if (pdev->dev.of_node) {
110                 struct gpio_ir_recv_platform_data *dtpdata =
111                         devm_kzalloc(&pdev->dev, sizeof(*dtpdata), GFP_KERNEL);
112                 if (!dtpdata)
113                         return -ENOMEM;
114                 rc = gpio_ir_recv_get_devtree_pdata(&pdev->dev, dtpdata);
115                 if (rc)
116                         return rc;
117                 pdata = dtpdata;
118         }
119
120         if (!pdata)
121                 return -EINVAL;
122
123         if (pdata->gpio_nr < 0)
124                 return -EINVAL;
125
126         gpio_dev = kzalloc(sizeof(struct gpio_rc_dev), GFP_KERNEL);
127         if (!gpio_dev)
128                 return -ENOMEM;
129
130         rcdev = rc_allocate_device();
131         if (!rcdev) {
132                 rc = -ENOMEM;
133                 goto err_allocate_device;
134         }
135
136         rcdev->priv = gpio_dev;
137         rcdev->driver_type = RC_DRIVER_IR_RAW;
138         rcdev->input_name = GPIO_IR_DEVICE_NAME;
139         rcdev->input_phys = GPIO_IR_DEVICE_NAME "/input0";
140         rcdev->input_id.bustype = BUS_HOST;
141         rcdev->input_id.vendor = 0x0001;
142         rcdev->input_id.product = 0x0001;
143         rcdev->input_id.version = 0x0100;
144         rcdev->dev.parent = &pdev->dev;
145         rcdev->driver_name = GPIO_IR_DRIVER_NAME;
146         if (pdata->allowed_protos)
147                 rcdev->allowed_protos = pdata->allowed_protos;
148         else
149                 rcdev->allowed_protos = RC_BIT_ALL;
150         rcdev->map_name = pdata->map_name ?: RC_MAP_EMPTY;
151
152         gpio_dev->rcdev = rcdev;
153         gpio_dev->gpio_nr = pdata->gpio_nr;
154         gpio_dev->active_low = pdata->active_low;
155
156         rc = gpio_request(pdata->gpio_nr, "gpio-ir-recv");
157         if (rc < 0)
158                 goto err_gpio_request;
159         rc  = gpio_direction_input(pdata->gpio_nr);
160         if (rc < 0)
161                 goto err_gpio_direction_input;
162
163         rc = rc_register_device(rcdev);
164         if (rc < 0) {
165                 dev_err(&pdev->dev, "failed to register rc device\n");
166                 goto err_register_rc_device;
167         }
168
169         platform_set_drvdata(pdev, gpio_dev);
170
171         rc = request_any_context_irq(gpio_to_irq(pdata->gpio_nr),
172                                 gpio_ir_recv_irq,
173                         IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
174                                         "gpio-ir-recv-irq", gpio_dev);
175         if (rc < 0)
176                 goto err_request_irq;
177
178         return 0;
179
180 err_request_irq:
181         rc_unregister_device(rcdev);
182         rcdev = NULL;
183 err_register_rc_device:
184 err_gpio_direction_input:
185         gpio_free(pdata->gpio_nr);
186 err_gpio_request:
187         rc_free_device(rcdev);
188 err_allocate_device:
189         kfree(gpio_dev);
190         return rc;
191 }
192
193 static int gpio_ir_recv_remove(struct platform_device *pdev)
194 {
195         struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev);
196
197         free_irq(gpio_to_irq(gpio_dev->gpio_nr), gpio_dev);
198         rc_unregister_device(gpio_dev->rcdev);
199         gpio_free(gpio_dev->gpio_nr);
200         kfree(gpio_dev);
201         return 0;
202 }
203
204 #ifdef CONFIG_PM
205 static int gpio_ir_recv_suspend(struct device *dev)
206 {
207         struct platform_device *pdev = to_platform_device(dev);
208         struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev);
209
210         if (device_may_wakeup(dev))
211                 enable_irq_wake(gpio_to_irq(gpio_dev->gpio_nr));
212         else
213                 disable_irq(gpio_to_irq(gpio_dev->gpio_nr));
214
215         return 0;
216 }
217
218 static int gpio_ir_recv_resume(struct device *dev)
219 {
220         struct platform_device *pdev = to_platform_device(dev);
221         struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev);
222
223         if (device_may_wakeup(dev))
224                 disable_irq_wake(gpio_to_irq(gpio_dev->gpio_nr));
225         else
226                 enable_irq(gpio_to_irq(gpio_dev->gpio_nr));
227
228         return 0;
229 }
230
231 static const struct dev_pm_ops gpio_ir_recv_pm_ops = {
232         .suspend        = gpio_ir_recv_suspend,
233         .resume         = gpio_ir_recv_resume,
234 };
235 #endif
236
237 static struct platform_driver gpio_ir_recv_driver = {
238         .probe  = gpio_ir_recv_probe,
239         .remove = gpio_ir_recv_remove,
240         .driver = {
241                 .name   = GPIO_IR_DRIVER_NAME,
242                 .owner  = THIS_MODULE,
243                 .of_match_table = of_match_ptr(gpio_ir_recv_of_match),
244 #ifdef CONFIG_PM
245                 .pm     = &gpio_ir_recv_pm_ops,
246 #endif
247         },
248 };
249 module_platform_driver(gpio_ir_recv_driver);
250
251 MODULE_DESCRIPTION("GPIO IR Receiver driver");
252 MODULE_LICENSE("GPL v2");