aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2014-07-23 13:03:10 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-07-24 15:39:52 -0400
commitf348f329562da89bcd9b6acc420bf69860019199 (patch)
tree0b9b7ce134394950bbe423f942ebff0d7167b59d
parent3ea7e551424bca5d7bbfc664446d9d9daa7f62de (diff)
Input: ipaq-micro-ts - introduce open/close
Wire up open/close so we do not try to send events until someone uses them; this also allows us to remove micro_ts_remove() and rely fully on managed resources. Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r--drivers/input/touchscreen/ipaq-micro-ts.c88
1 files changed, 56 insertions, 32 deletions
diff --git a/drivers/input/touchscreen/ipaq-micro-ts.c b/drivers/input/touchscreen/ipaq-micro-ts.c
index 53fa5c361be1..62c8976e616f 100644
--- a/drivers/input/touchscreen/ipaq-micro-ts.c
+++ b/drivers/input/touchscreen/ipaq-micro-ts.c
@@ -46,17 +46,50 @@ static void micro_ts_receive(void *data, int len, unsigned char *msg)
46 } 46 }
47} 47}
48 48
49static void micro_ts_toggle_receive(struct touchscreen_data *ts, bool enable)
50{
51 struct ipaq_micro *micro = ts->micro;
52
53 spin_lock_irq(&micro->lock);
54
55 if (enable) {
56 micro->ts = micro_ts_receive;
57 micro->ts_data = ts;
58 } else {
59 micro->ts = NULL;
60 micro->ts_data = NULL;
61 }
62
63 spin_unlock_irq(&ts->micro->lock);
64}
65
66static int micro_ts_open(struct input_dev *input)
67{
68 struct touchscreen_data *ts = input_get_drvdata(input);
69
70 micro_ts_toggle_receive(ts, true);
71
72 return 0;
73}
74
75static void micro_ts_close(struct input_dev *input)
76{
77 struct touchscreen_data *ts = input_get_drvdata(input);
78
79 micro_ts_toggle_receive(ts, false);
80}
81
49static int micro_ts_probe(struct platform_device *pdev) 82static int micro_ts_probe(struct platform_device *pdev)
50{ 83{
84 struct ipaq_micro *micro = dev_get_drvdata(pdev->dev.parent);
51 struct touchscreen_data *ts; 85 struct touchscreen_data *ts;
52 int ret; 86 int error;
53 87
54 ts = devm_kzalloc(&pdev->dev, sizeof(*ts), GFP_KERNEL); 88 ts = devm_kzalloc(&pdev->dev, sizeof(*ts), GFP_KERNEL);
55 if (!ts) 89 if (!ts)
56 return -ENOMEM; 90 return -ENOMEM;
57 ts->micro = dev_get_drvdata(pdev->dev.parent);
58 91
59 platform_set_drvdata(pdev, ts); 92 ts->micro = micro;
60 93
61 ts->input = devm_input_allocate_device(&pdev->dev); 94 ts->input = devm_input_allocate_device(&pdev->dev);
62 if (!ts->input) { 95 if (!ts->input) {
@@ -64,37 +97,27 @@ static int micro_ts_probe(struct platform_device *pdev)
64 return -ENOMEM; 97 return -ENOMEM;
65 } 98 }
66 99
100 ts->input->name = "ipaq micro ts";
101 ts->input->open = micro_ts_open;
102 ts->input->close = micro_ts_close;
103
104 input_set_drvdata(ts->input, ts);
105
67 input_set_capability(ts->input, EV_KEY, BTN_TOUCH); 106 input_set_capability(ts->input, EV_KEY, BTN_TOUCH);
68 input_set_capability(ts->input, EV_ABS, ABS_X); 107 input_set_capability(ts->input, EV_ABS, ABS_X);
69 input_set_capability(ts->input, EV_ABS, ABS_Y); 108 input_set_capability(ts->input, EV_ABS, ABS_Y);
70 input_set_abs_params(ts->input, ABS_X, 0, 1023, 0, 0); 109 input_set_abs_params(ts->input, ABS_X, 0, 1023, 0, 0);
71 input_set_abs_params(ts->input, ABS_Y, 0, 1023, 0, 0); 110 input_set_abs_params(ts->input, ABS_Y, 0, 1023, 0, 0);
72 111
73 ts->input->name = "ipaq micro ts"; 112 error = input_register_device(ts->input);
74 113 if (error) {
75 ret = input_register_device(ts->input);
76 if (ret) {
77 dev_err(&pdev->dev, "error registering touch input\n"); 114 dev_err(&pdev->dev, "error registering touch input\n");
78 return ret; 115 return error;
79 } 116 }
80 117
81 spin_lock_irq(&ts->micro->lock); 118 platform_set_drvdata(pdev, ts);
82 ts->micro->ts = micro_ts_receive;
83 ts->micro->ts_data = ts;
84 spin_unlock_irq(&ts->micro->lock);
85 119
86 dev_info(&pdev->dev, "iPAQ micro touchscreen\n"); 120 dev_info(&pdev->dev, "iPAQ micro touchscreen\n");
87 return 0;
88}
89
90static int micro_ts_remove(struct platform_device *pdev)
91{
92 struct touchscreen_data *ts = platform_get_drvdata(pdev);
93
94 spin_lock_irq(&ts->micro->lock);
95 ts->micro->ts = NULL;
96 ts->micro->ts_data = NULL;
97 spin_unlock_irq(&ts->micro->lock);
98 121
99 return 0; 122 return 0;
100} 123}
@@ -104,21 +127,23 @@ static int micro_ts_suspend(struct device *dev)
104{ 127{
105 struct touchscreen_data *ts = dev_get_drvdata(dev); 128 struct touchscreen_data *ts = dev_get_drvdata(dev);
106 129
107 spin_lock_irq(&ts->micro->lock); 130 micro_ts_toggle_receive(ts, false);
108 ts->micro->ts = NULL; 131
109 ts->micro->ts_data = NULL;
110 spin_unlock_irq(&ts->micro->lock);
111 return 0; 132 return 0;
112} 133}
113 134
114static int micro_ts_resume(struct device *dev) 135static int micro_ts_resume(struct device *dev)
115{ 136{
116 struct touchscreen_data *ts = dev_get_drvdata(dev); 137 struct touchscreen_data *ts = dev_get_drvdata(dev);
138 struct input_dev *input = ts->input;
139
140 mutex_lock(&input->mutex);
141
142 if (input->users)
143 micro_ts_toggle_receive(ts, true);
144
145 mutex_unlock(&input->mutex);
117 146
118 spin_lock_irq(&ts->micro->lock);
119 ts->micro->ts = micro_ts_receive;
120 ts->micro->ts_data = ts;
121 spin_unlock_irq(&ts->micro->lock);
122 return 0; 147 return 0;
123} 148}
124#endif 149#endif
@@ -133,7 +158,6 @@ static struct platform_driver micro_ts_device_driver = {
133 .pm = &micro_ts_dev_pm_ops, 158 .pm = &micro_ts_dev_pm_ops,
134 }, 159 },
135 .probe = micro_ts_probe, 160 .probe = micro_ts_probe,
136 .remove = micro_ts_remove,
137}; 161};
138module_platform_driver(micro_ts_device_driver); 162module_platform_driver(micro_ts_device_driver);
139 163