diff options
Diffstat (limited to 'drivers/input')
28 files changed, 17066 insertions, 0 deletions
diff --git a/drivers/input/fixp-arith.h b/drivers/input/fixp-arith.h new file mode 100644 index 00000000000..3089d738232 --- /dev/null +++ b/drivers/input/fixp-arith.h | |||
@@ -0,0 +1,87 @@ | |||
1 | #ifndef _FIXP_ARITH_H | ||
2 | #define _FIXP_ARITH_H | ||
3 | |||
4 | /* | ||
5 | * Simplistic fixed-point arithmetics. | ||
6 | * Hmm, I'm probably duplicating some code :( | ||
7 | * | ||
8 | * Copyright (c) 2002 Johann Deneux | ||
9 | */ | ||
10 | |||
11 | /* | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
25 | * | ||
26 | * Should you need to contact me, the author, you can do so by | ||
27 | * e-mail - mail your message to <johann.deneux@gmail.com> | ||
28 | */ | ||
29 | |||
30 | #include <linux/types.h> | ||
31 | |||
32 | /* The type representing fixed-point values */ | ||
33 | typedef s16 fixp_t; | ||
34 | |||
35 | #define FRAC_N 8 | ||
36 | #define FRAC_MASK ((1<<FRAC_N)-1) | ||
37 | |||
38 | /* Not to be used directly. Use fixp_{cos,sin} */ | ||
39 | static const fixp_t cos_table[46] = { | ||
40 | 0x0100, 0x00FF, 0x00FF, 0x00FE, 0x00FD, 0x00FC, 0x00FA, 0x00F8, | ||
41 | 0x00F6, 0x00F3, 0x00F0, 0x00ED, 0x00E9, 0x00E6, 0x00E2, 0x00DD, | ||
42 | 0x00D9, 0x00D4, 0x00CF, 0x00C9, 0x00C4, 0x00BE, 0x00B8, 0x00B1, | ||
43 | 0x00AB, 0x00A4, 0x009D, 0x0096, 0x008F, 0x0087, 0x0080, 0x0078, | ||
44 | 0x0070, 0x0068, 0x005F, 0x0057, 0x004F, 0x0046, 0x003D, 0x0035, | ||
45 | 0x002C, 0x0023, 0x001A, 0x0011, 0x0008, 0x0000 | ||
46 | }; | ||
47 | |||
48 | |||
49 | /* a: 123 -> 123.0 */ | ||
50 | static inline fixp_t fixp_new(s16 a) | ||
51 | { | ||
52 | return a<<FRAC_N; | ||
53 | } | ||
54 | |||
55 | /* a: 0xFFFF -> -1.0 | ||
56 | 0x8000 -> 1.0 | ||
57 | 0x0000 -> 0.0 | ||
58 | */ | ||
59 | static inline fixp_t fixp_new16(s16 a) | ||
60 | { | ||
61 | return ((s32)a)>>(16-FRAC_N); | ||
62 | } | ||
63 | |||
64 | static inline fixp_t fixp_cos(unsigned int degrees) | ||
65 | { | ||
66 | int quadrant = (degrees / 90) & 3; | ||
67 | unsigned int i = degrees % 90; | ||
68 | |||
69 | if (quadrant == 1 || quadrant == 3) | ||
70 | i = 90 - i; | ||
71 | |||
72 | i >>= 1; | ||
73 | |||
74 | return (quadrant == 1 || quadrant == 2)? -cos_table[i] : cos_table[i]; | ||
75 | } | ||
76 | |||
77 | static inline fixp_t fixp_sin(unsigned int degrees) | ||
78 | { | ||
79 | return -fixp_cos(degrees + 90); | ||
80 | } | ||
81 | |||
82 | static inline fixp_t fixp_mult(fixp_t a, fixp_t b) | ||
83 | { | ||
84 | return ((s32)(a*b))>>FRAC_N; | ||
85 | } | ||
86 | |||
87 | #endif | ||
diff --git a/drivers/input/keyreset.c b/drivers/input/keyreset.c new file mode 100644 index 00000000000..36208fe0baa --- /dev/null +++ b/drivers/input/keyreset.c | |||
@@ -0,0 +1,239 @@ | |||
1 | /* drivers/input/keyreset.c | ||
2 | * | ||
3 | * Copyright (C) 2008 Google, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/input.h> | ||
17 | #include <linux/keyreset.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/reboot.h> | ||
21 | #include <linux/sched.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/syscalls.h> | ||
24 | |||
25 | |||
26 | struct keyreset_state { | ||
27 | struct input_handler input_handler; | ||
28 | unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; | ||
29 | unsigned long upbit[BITS_TO_LONGS(KEY_CNT)]; | ||
30 | unsigned long key[BITS_TO_LONGS(KEY_CNT)]; | ||
31 | spinlock_t lock; | ||
32 | int key_down_target; | ||
33 | int key_down; | ||
34 | int key_up; | ||
35 | int restart_disabled; | ||
36 | int (*reset_fn)(void); | ||
37 | }; | ||
38 | |||
39 | int restart_requested; | ||
40 | static void deferred_restart(struct work_struct *dummy) | ||
41 | { | ||
42 | restart_requested = 2; | ||
43 | sys_sync(); | ||
44 | restart_requested = 3; | ||
45 | kernel_restart(NULL); | ||
46 | } | ||
47 | static DECLARE_WORK(restart_work, deferred_restart); | ||
48 | |||
49 | static void keyreset_event(struct input_handle *handle, unsigned int type, | ||
50 | unsigned int code, int value) | ||
51 | { | ||
52 | unsigned long flags; | ||
53 | struct keyreset_state *state = handle->private; | ||
54 | |||
55 | if (type != EV_KEY) | ||
56 | return; | ||
57 | |||
58 | if (code >= KEY_MAX) | ||
59 | return; | ||
60 | |||
61 | if (!test_bit(code, state->keybit)) | ||
62 | return; | ||
63 | |||
64 | spin_lock_irqsave(&state->lock, flags); | ||
65 | if (!test_bit(code, state->key) == !value) | ||
66 | goto done; | ||
67 | __change_bit(code, state->key); | ||
68 | if (test_bit(code, state->upbit)) { | ||
69 | if (value) { | ||
70 | state->restart_disabled = 1; | ||
71 | state->key_up++; | ||
72 | } else | ||
73 | state->key_up--; | ||
74 | } else { | ||
75 | if (value) | ||
76 | state->key_down++; | ||
77 | else | ||
78 | state->key_down--; | ||
79 | } | ||
80 | if (state->key_down == 0 && state->key_up == 0) | ||
81 | state->restart_disabled = 0; | ||
82 | |||
83 | pr_debug("reset key changed %d %d new state %d-%d-%d\n", code, value, | ||
84 | state->key_down, state->key_up, state->restart_disabled); | ||
85 | |||
86 | if (value && !state->restart_disabled && | ||
87 | state->key_down == state->key_down_target) { | ||
88 | state->restart_disabled = 1; | ||
89 | if (restart_requested) | ||
90 | panic("keyboard reset failed, %d", restart_requested); | ||
91 | if (state->reset_fn) { | ||
92 | restart_requested = state->reset_fn(); | ||
93 | } else { | ||
94 | pr_info("keyboard reset\n"); | ||
95 | schedule_work(&restart_work); | ||
96 | restart_requested = 1; | ||
97 | } | ||
98 | } | ||
99 | done: | ||
100 | spin_unlock_irqrestore(&state->lock, flags); | ||
101 | } | ||
102 | |||
103 | static int keyreset_connect(struct input_handler *handler, | ||
104 | struct input_dev *dev, | ||
105 | const struct input_device_id *id) | ||
106 | { | ||
107 | int i; | ||
108 | int ret; | ||
109 | struct input_handle *handle; | ||
110 | struct keyreset_state *state = | ||
111 | container_of(handler, struct keyreset_state, input_handler); | ||
112 | |||
113 | for (i = 0; i < KEY_MAX; i++) { | ||
114 | if (test_bit(i, state->keybit) && test_bit(i, dev->keybit)) | ||
115 | break; | ||
116 | } | ||
117 | if (i == KEY_MAX) | ||
118 | return -ENODEV; | ||
119 | |||
120 | handle = kzalloc(sizeof(*handle), GFP_KERNEL); | ||
121 | if (!handle) | ||
122 | return -ENOMEM; | ||
123 | |||
124 | handle->dev = dev; | ||
125 | handle->handler = handler; | ||
126 | handle->name = "keyreset"; | ||
127 | handle->private = state; | ||
128 | |||
129 | ret = input_register_handle(handle); | ||
130 | if (ret) | ||
131 | goto err_input_register_handle; | ||
132 | |||
133 | ret = input_open_device(handle); | ||
134 | if (ret) | ||
135 | goto err_input_open_device; | ||
136 | |||
137 | pr_info("using input dev %s for key reset\n", dev->name); | ||
138 | |||
139 | return 0; | ||
140 | |||
141 | err_input_open_device: | ||
142 | input_unregister_handle(handle); | ||
143 | err_input_register_handle: | ||
144 | kfree(handle); | ||
145 | return ret; | ||
146 | } | ||
147 | |||
148 | static void keyreset_disconnect(struct input_handle *handle) | ||
149 | { | ||
150 | input_close_device(handle); | ||
151 | input_unregister_handle(handle); | ||
152 | kfree(handle); | ||
153 | } | ||
154 | |||
155 | static const struct input_device_id keyreset_ids[] = { | ||
156 | { | ||
157 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT, | ||
158 | .evbit = { BIT_MASK(EV_KEY) }, | ||
159 | }, | ||
160 | { }, | ||
161 | }; | ||
162 | MODULE_DEVICE_TABLE(input, keyreset_ids); | ||
163 | |||
164 | static int keyreset_probe(struct platform_device *pdev) | ||
165 | { | ||
166 | int ret; | ||
167 | int key, *keyp; | ||
168 | struct keyreset_state *state; | ||
169 | struct keyreset_platform_data *pdata = pdev->dev.platform_data; | ||
170 | |||
171 | if (!pdata) | ||
172 | return -EINVAL; | ||
173 | |||
174 | state = kzalloc(sizeof(*state), GFP_KERNEL); | ||
175 | if (!state) | ||
176 | return -ENOMEM; | ||
177 | |||
178 | spin_lock_init(&state->lock); | ||
179 | keyp = pdata->keys_down; | ||
180 | while ((key = *keyp++)) { | ||
181 | if (key >= KEY_MAX) | ||
182 | continue; | ||
183 | state->key_down_target++; | ||
184 | __set_bit(key, state->keybit); | ||
185 | } | ||
186 | if (pdata->keys_up) { | ||
187 | keyp = pdata->keys_up; | ||
188 | while ((key = *keyp++)) { | ||
189 | if (key >= KEY_MAX) | ||
190 | continue; | ||
191 | __set_bit(key, state->keybit); | ||
192 | __set_bit(key, state->upbit); | ||
193 | } | ||
194 | } | ||
195 | |||
196 | if (pdata->reset_fn) | ||
197 | state->reset_fn = pdata->reset_fn; | ||
198 | |||
199 | state->input_handler.event = keyreset_event; | ||
200 | state->input_handler.connect = keyreset_connect; | ||
201 | state->input_handler.disconnect = keyreset_disconnect; | ||
202 | state->input_handler.name = KEYRESET_NAME; | ||
203 | state->input_handler.id_table = keyreset_ids; | ||
204 | ret = input_register_handler(&state->input_handler); | ||
205 | if (ret) { | ||
206 | kfree(state); | ||
207 | return ret; | ||
208 | } | ||
209 | platform_set_drvdata(pdev, state); | ||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | int keyreset_remove(struct platform_device *pdev) | ||
214 | { | ||
215 | struct keyreset_state *state = platform_get_drvdata(pdev); | ||
216 | input_unregister_handler(&state->input_handler); | ||
217 | kfree(state); | ||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | |||
222 | struct platform_driver keyreset_driver = { | ||
223 | .driver.name = KEYRESET_NAME, | ||
224 | .probe = keyreset_probe, | ||
225 | .remove = keyreset_remove, | ||
226 | }; | ||
227 | |||
228 | static int __init keyreset_init(void) | ||
229 | { | ||
230 | return platform_driver_register(&keyreset_driver); | ||
231 | } | ||
232 | |||
233 | static void __exit keyreset_exit(void) | ||
234 | { | ||
235 | return platform_driver_unregister(&keyreset_driver); | ||
236 | } | ||
237 | |||
238 | module_init(keyreset_init); | ||
239 | module_exit(keyreset_exit); | ||
diff --git a/drivers/input/misc/alps_gpio_scrollwheel.c b/drivers/input/misc/alps_gpio_scrollwheel.c new file mode 100644 index 00000000000..4a789267c47 --- /dev/null +++ b/drivers/input/misc/alps_gpio_scrollwheel.c | |||
@@ -0,0 +1,428 @@ | |||
1 | /* | ||
2 | * kernel/drivers/input/misc/alps_gpio_scrollwheel.c | ||
3 | * | ||
4 | * Copyright (c) 2010, NVIDIA Corporation. | ||
5 | * | ||
6 | * Driver for ScrollWheel on GPIO lines capable of generating interrupts. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along | ||
19 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
20 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
21 | */ | ||
22 | |||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/fs.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/irq.h> | ||
29 | #include <linux/sched.h> | ||
30 | #include <linux/pm.h> | ||
31 | #include <linux/slab.h> | ||
32 | #include <linux/sysctl.h> | ||
33 | #include <linux/proc_fs.h> | ||
34 | #include <linux/delay.h> | ||
35 | #include <linux/platform_device.h> | ||
36 | #include <linux/input.h> | ||
37 | #include <linux/gpio_scrollwheel.h> | ||
38 | #include <linux/workqueue.h> | ||
39 | #include <linux/gpio.h> | ||
40 | |||
41 | struct scrollwheel_button_data { | ||
42 | struct gpio_scrollwheel_button *button; | ||
43 | struct input_dev *input; | ||
44 | struct timer_list timer; | ||
45 | struct work_struct work; | ||
46 | int timer_debounce; /* in msecs */ | ||
47 | int rotgpio; | ||
48 | bool disabled; | ||
49 | }; | ||
50 | |||
51 | struct gpio_scrollwheel_drvdata { | ||
52 | struct input_dev *input; | ||
53 | struct mutex disable_lock; | ||
54 | unsigned int n_buttons; | ||
55 | int (*enable)(struct device *dev); | ||
56 | void (*disable)(struct device *dev); | ||
57 | struct scrollwheel_button_data data[0]; | ||
58 | }; | ||
59 | |||
60 | static void scrollwheel_report_key(struct scrollwheel_button_data *bdata) | ||
61 | { | ||
62 | struct gpio_scrollwheel_button *button = bdata->button; | ||
63 | struct input_dev *input = bdata->input; | ||
64 | int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ \ | ||
65 | button->active_low; | ||
66 | int state2 = 0; | ||
67 | |||
68 | switch (button->pinaction) { | ||
69 | case GPIO_SCROLLWHEEL_PIN_PRESS: | ||
70 | input_report_key(input, KEY_ENTER, 1); | ||
71 | input_report_key(input, KEY_ENTER, 0); | ||
72 | input_sync(input); | ||
73 | break; | ||
74 | |||
75 | case GPIO_SCROLLWHEEL_PIN_ROT1: | ||
76 | case GPIO_SCROLLWHEEL_PIN_ROT2: | ||
77 | state2 = (gpio_get_value(bdata->rotgpio) ? 1 : 0) \ | ||
78 | ^ button->active_low; | ||
79 | if (state != state2) { | ||
80 | input_report_key(input, KEY_DOWN, 1); | ||
81 | input_report_key(input, KEY_DOWN, 0); | ||
82 | } else { | ||
83 | input_report_key(input, KEY_UP, 1); | ||
84 | input_report_key(input, KEY_UP, 0); | ||
85 | } | ||
86 | input_sync(input); | ||
87 | break; | ||
88 | |||
89 | default: | ||
90 | pr_err("%s:Line=%d, Invalid Pinaction\n", __func__, __LINE__); | ||
91 | } | ||
92 | } | ||
93 | |||
94 | static void scrollwheel_work_func(struct work_struct *work) | ||
95 | { | ||
96 | struct scrollwheel_button_data *bdata = | ||
97 | container_of(work, struct scrollwheel_button_data, work); | ||
98 | |||
99 | scrollwheel_report_key(bdata); | ||
100 | } | ||
101 | |||
102 | static void scrollwheel_timer(unsigned long _data) | ||
103 | { | ||
104 | struct scrollwheel_button_data *data = \ | ||
105 | (struct scrollwheel_button_data *)_data; | ||
106 | |||
107 | schedule_work(&data->work); | ||
108 | } | ||
109 | |||
110 | static irqreturn_t scrollwheel_isr(int irq, void *dev_id) | ||
111 | { | ||
112 | struct scrollwheel_button_data *bdata = dev_id; | ||
113 | struct gpio_scrollwheel_button *button = bdata->button; | ||
114 | |||
115 | BUG_ON(irq != gpio_to_irq(button->gpio)); | ||
116 | |||
117 | if (bdata->timer_debounce) | ||
118 | mod_timer(&bdata->timer, | ||
119 | jiffies + msecs_to_jiffies(bdata->timer_debounce)); | ||
120 | else | ||
121 | schedule_work(&bdata->work); | ||
122 | |||
123 | return IRQ_HANDLED; | ||
124 | } | ||
125 | |||
126 | static int __devinit gpio_scrollwheel_setup_key(struct platform_device *pdev, | ||
127 | struct scrollwheel_button_data *bdata, | ||
128 | struct gpio_scrollwheel_button *button) | ||
129 | { | ||
130 | char *desc = button->desc ? button->desc : "gpio_scrollwheel"; | ||
131 | struct device *dev = &pdev->dev; | ||
132 | unsigned long irqflags; | ||
133 | int irq, error; | ||
134 | |||
135 | setup_timer(&bdata->timer, scrollwheel_timer, (unsigned long)bdata); | ||
136 | INIT_WORK(&bdata->work, scrollwheel_work_func); | ||
137 | |||
138 | error = gpio_request(button->gpio, desc); | ||
139 | if (error < 0) { | ||
140 | dev_err(dev, "failed to request GPIO %d, error %d\n", | ||
141 | button->gpio, error); | ||
142 | return error; | ||
143 | } | ||
144 | |||
145 | error = gpio_direction_input(button->gpio); | ||
146 | if (error < 0) { | ||
147 | dev_err(dev, "failed to configure" | ||
148 | " direction for GPIO %d, error %d\n", | ||
149 | button->gpio, error); | ||
150 | goto fail; | ||
151 | } | ||
152 | |||
153 | if (button->debounce_interval) { | ||
154 | error = gpio_set_debounce(button->gpio, | ||
155 | button->debounce_interval * 1000); | ||
156 | /* use timer if gpiolib doesn't provide debounce */ | ||
157 | if (error < 0) | ||
158 | bdata->timer_debounce = button->debounce_interval; | ||
159 | } | ||
160 | |||
161 | irq = gpio_to_irq(button->gpio); | ||
162 | if (irq < 0) { | ||
163 | error = irq; | ||
164 | dev_err(dev, "Unable to get irq no for GPIO %d, error %d\n", | ||
165 | button->gpio, error); | ||
166 | goto fail; | ||
167 | } | ||
168 | |||
169 | irqflags = IRQF_TRIGGER_FALLING; | ||
170 | |||
171 | error = request_irq(irq, scrollwheel_isr, irqflags, desc, bdata); | ||
172 | if (error) { | ||
173 | dev_err(dev, "Unable to claim irq %d; error %d\n", | ||
174 | irq, error); | ||
175 | goto fail; | ||
176 | } | ||
177 | |||
178 | return 0; | ||
179 | |||
180 | fail: | ||
181 | return error; | ||
182 | } | ||
183 | |||
184 | static int gpio_scrollwheel_open(struct input_dev *input) | ||
185 | { | ||
186 | struct gpio_scrollwheel_drvdata *ddata = input_get_drvdata(input); | ||
187 | |||
188 | return ddata->enable ? ddata->enable(input->dev.parent) : 0; | ||
189 | } | ||
190 | |||
191 | static void gpio_scrollwheel_close(struct input_dev *input) | ||
192 | { | ||
193 | struct gpio_scrollwheel_drvdata *ddata = input_get_drvdata(input); | ||
194 | |||
195 | if (ddata->disable) | ||
196 | ddata->disable(input->dev.parent); | ||
197 | } | ||
198 | |||
199 | static int __devinit gpio_scrollwheel_probe(struct platform_device *pdev) | ||
200 | { | ||
201 | struct gpio_scrollwheel_platform_data *pdata = pdev->dev.platform_data; | ||
202 | struct gpio_scrollwheel_drvdata *ddata; | ||
203 | struct device *dev = &pdev->dev; | ||
204 | struct input_dev *input; | ||
205 | int i, error; | ||
206 | |||
207 | ddata = kzalloc(sizeof(struct gpio_scrollwheel_drvdata) + | ||
208 | pdata->nbuttons * sizeof(struct scrollwheel_button_data), | ||
209 | GFP_KERNEL); | ||
210 | if (ddata == NULL) { | ||
211 | dev_err(dev, "failed to allocate memory\n"); | ||
212 | error = -ENOMEM; | ||
213 | return error; | ||
214 | } | ||
215 | |||
216 | input = input_allocate_device(); | ||
217 | if (input == NULL) { | ||
218 | dev_err(dev, "failed to allocate input device\n"); | ||
219 | error = -ENOMEM; | ||
220 | kfree(ddata); | ||
221 | return error; | ||
222 | } | ||
223 | |||
224 | ddata->input = input; | ||
225 | ddata->n_buttons = pdata->nbuttons; | ||
226 | ddata->enable = pdata->enable; | ||
227 | ddata->disable = pdata->disable; | ||
228 | mutex_init(&ddata->disable_lock); | ||
229 | |||
230 | platform_set_drvdata(pdev, ddata); | ||
231 | input_set_drvdata(input, ddata); | ||
232 | |||
233 | input->name = pdev->name; | ||
234 | input->phys = "gpio-scrollwheel/input0"; | ||
235 | input->dev.parent = &pdev->dev; | ||
236 | input->open = gpio_scrollwheel_open; | ||
237 | input->close = gpio_scrollwheel_close; | ||
238 | |||
239 | input->id.bustype = BUS_HOST; | ||
240 | input->id.vendor = 0x0001; | ||
241 | input->id.product = 0x0001; | ||
242 | input->id.version = 0x0100; | ||
243 | |||
244 | /* Enable auto repeat feature of Linux input subsystem */ | ||
245 | if (pdata->rep) | ||
246 | __set_bit(EV_REP, input->evbit); | ||
247 | |||
248 | for (i = 0; i < pdata->nbuttons; i++) { | ||
249 | struct gpio_scrollwheel_button *button = &pdata->buttons[i]; | ||
250 | struct scrollwheel_button_data *bdata = &ddata->data[i]; | ||
251 | |||
252 | bdata->input = input; | ||
253 | bdata->button = button; | ||
254 | |||
255 | if (button->pinaction == GPIO_SCROLLWHEEL_PIN_PRESS || | ||
256 | button->pinaction == GPIO_SCROLLWHEEL_PIN_ROT1) { | ||
257 | error = gpio_scrollwheel_setup_key(pdev, bdata, button); | ||
258 | if (error) | ||
259 | goto fail; | ||
260 | } else { | ||
261 | if (button->pinaction == GPIO_SCROLLWHEEL_PIN_ONOFF) { | ||
262 | gpio_request(button->gpio, button->desc); | ||
263 | gpio_direction_output(button->gpio, 0); | ||
264 | } | ||
265 | |||
266 | if (button->pinaction == GPIO_SCROLLWHEEL_PIN_ROT2) { | ||
267 | gpio_request(button->gpio, button->desc); | ||
268 | gpio_direction_input(button->gpio); | ||
269 | /* Save rot2 gpio number in rot1 context */ | ||
270 | ddata->data[2].rotgpio = button->gpio; | ||
271 | } | ||
272 | } | ||
273 | } | ||
274 | |||
275 | /* set input capability */ | ||
276 | __set_bit(EV_KEY, input->evbit); | ||
277 | __set_bit(KEY_ENTER, input->keybit); | ||
278 | __set_bit(KEY_UP, input->keybit); | ||
279 | __set_bit(KEY_DOWN, input->keybit); | ||
280 | |||
281 | error = input_register_device(input); | ||
282 | if (error) { | ||
283 | dev_err(dev, "Unable to register input device, error: %d\n", | ||
284 | error); | ||
285 | goto fail; | ||
286 | } | ||
287 | |||
288 | input_sync(input); | ||
289 | |||
290 | return 0; | ||
291 | |||
292 | fail: | ||
293 | while (--i >= 0) { | ||
294 | if (pdata->buttons[i].pinaction == GPIO_SCROLLWHEEL_PIN_PRESS || | ||
295 | pdata->buttons[i].pinaction == GPIO_SCROLLWHEEL_PIN_ROT1) { | ||
296 | free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); | ||
297 | if (ddata->data[i].timer_debounce) | ||
298 | del_timer_sync(&ddata->data[i].timer); | ||
299 | cancel_work_sync(&ddata->data[i].work); | ||
300 | } | ||
301 | gpio_free(pdata->buttons[i].gpio); | ||
302 | } | ||
303 | |||
304 | platform_set_drvdata(pdev, NULL); | ||
305 | input_free_device(input); | ||
306 | kfree(ddata); | ||
307 | return error; | ||
308 | } | ||
309 | |||
310 | static int __devexit gpio_scrollwheel_remove(struct platform_device *pdev) | ||
311 | { | ||
312 | struct gpio_scrollwheel_platform_data *pdata = pdev->dev.platform_data; | ||
313 | struct gpio_scrollwheel_drvdata *ddata = platform_get_drvdata(pdev); | ||
314 | struct input_dev *input = ddata->input; | ||
315 | int i; | ||
316 | |||
317 | for (i = 0; i < pdata->nbuttons; i++) { | ||
318 | if (pdata->buttons[i].pinaction == GPIO_SCROLLWHEEL_PIN_PRESS || | ||
319 | pdata->buttons[i].pinaction == GPIO_SCROLLWHEEL_PIN_ROT1) { | ||
320 | int irq = gpio_to_irq(pdata->buttons[i].gpio); | ||
321 | free_irq(irq, &ddata->data[i]); | ||
322 | if (ddata->data[i].timer_debounce) | ||
323 | del_timer_sync(&ddata->data[i].timer); | ||
324 | cancel_work_sync(&ddata->data[i].work); | ||
325 | } | ||
326 | gpio_free(pdata->buttons[i].gpio); | ||
327 | } | ||
328 | |||
329 | input_unregister_device(input); | ||
330 | |||
331 | return 0; | ||
332 | } | ||
333 | |||
334 | |||
335 | #ifdef CONFIG_PM | ||
336 | static int gpio_scrollwheel_suspend(struct device *dev) | ||
337 | { | ||
338 | struct platform_device *pdev = to_platform_device(dev); | ||
339 | struct gpio_scrollwheel_platform_data *pdata = pdev->dev.platform_data; | ||
340 | struct gpio_scrollwheel_drvdata *ddata = platform_get_drvdata(pdev); | ||
341 | int i, irq; | ||
342 | |||
343 | for (i = 0; i < pdata->nbuttons; i++) { | ||
344 | if (pdata->buttons[i].pinaction == GPIO_SCROLLWHEEL_PIN_PRESS || | ||
345 | pdata->buttons[i].pinaction == GPIO_SCROLLWHEEL_PIN_ROT1) { | ||
346 | irq = gpio_to_irq(pdata->buttons[i].gpio); | ||
347 | disable_irq(irq); | ||
348 | if (ddata->data[i].timer_debounce) | ||
349 | del_timer_sync(&ddata->data[i].timer); | ||
350 | cancel_work_sync(&ddata->data[i].work); | ||
351 | } else { | ||
352 | if (pdata->buttons[i].pinaction == GPIO_SCROLLWHEEL_PIN_ONOFF) | ||
353 | gpio_direction_output(pdata->buttons[i].gpio, 1); | ||
354 | else { | ||
355 | irq = gpio_to_irq(pdata->buttons[i].gpio); | ||
356 | disable_irq(irq); | ||
357 | } | ||
358 | } | ||
359 | } | ||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | static int gpio_scrollwheel_resume(struct device *dev) | ||
364 | { | ||
365 | struct platform_device *pdev = to_platform_device(dev); | ||
366 | struct gpio_scrollwheel_platform_data *pdata = pdev->dev.platform_data; | ||
367 | struct gpio_scrollwheel_drvdata *ddata = platform_get_drvdata(pdev); | ||
368 | int i, irq; | ||
369 | |||
370 | for (i = 0; i < pdata->nbuttons; i++) { | ||
371 | if (pdata->buttons[i].pinaction == GPIO_SCROLLWHEEL_PIN_PRESS || | ||
372 | pdata->buttons[i].pinaction == GPIO_SCROLLWHEEL_PIN_ROT1) { | ||
373 | irq = gpio_to_irq(pdata->buttons[i].gpio); | ||
374 | enable_irq(irq); | ||
375 | if (ddata->data[i].timer_debounce) | ||
376 | setup_timer(&ddata->data[i].timer,\ | ||
377 | scrollwheel_timer, (unsigned long)&ddata->data[i]); | ||
378 | |||
379 | INIT_WORK(&ddata->data[i].work, scrollwheel_work_func); | ||
380 | } else { | ||
381 | if (pdata->buttons[i].pinaction == GPIO_SCROLLWHEEL_PIN_ONOFF) | ||
382 | gpio_direction_output(pdata->buttons[i].gpio, 0); | ||
383 | else { | ||
384 | irq = gpio_to_irq(pdata->buttons[i].gpio); | ||
385 | enable_irq(irq); | ||
386 | } | ||
387 | } | ||
388 | } | ||
389 | |||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | static const struct dev_pm_ops gpio_scrollwheel_pm_ops = { | ||
394 | .suspend = gpio_scrollwheel_suspend, | ||
395 | .resume = gpio_scrollwheel_resume, | ||
396 | }; | ||
397 | #endif | ||
398 | |||
399 | static struct platform_driver gpio_scrollwheel_device_driver = { | ||
400 | .probe = gpio_scrollwheel_probe, | ||
401 | .remove = __devexit_p(gpio_scrollwheel_remove), | ||
402 | .driver = { | ||
403 | .name = "alps-gpio-scrollwheel", | ||
404 | .owner = THIS_MODULE, | ||
405 | #ifdef CONFIG_PM | ||
406 | .pm = &gpio_scrollwheel_pm_ops, | ||
407 | #endif | ||
408 | } | ||
409 | }; | ||
410 | |||
411 | static int __init gpio_scrollwheel_init(void) | ||
412 | { | ||
413 | return platform_driver_register(&gpio_scrollwheel_device_driver); | ||
414 | } | ||
415 | |||
416 | static void __exit gpio_scrollwheel_exit(void) | ||
417 | { | ||
418 | platform_driver_unregister(&gpio_scrollwheel_device_driver); | ||
419 | } | ||
420 | |||
421 | module_init(gpio_scrollwheel_init); | ||
422 | module_exit(gpio_scrollwheel_exit); | ||
423 | |||
424 | MODULE_LICENSE("GPL"); | ||
425 | MODULE_AUTHOR("NVIDIA Corporation"); | ||
426 | MODULE_DESCRIPTION("Alps SRBE ScrollWheel driver"); | ||
427 | |||
428 | MODULE_ALIAS("platform:alps-gpio-scrollwheel"); | ||
diff --git a/drivers/input/misc/ati_remote.c b/drivers/input/misc/ati_remote.c new file mode 100644 index 00000000000..bce57129afb --- /dev/null +++ b/drivers/input/misc/ati_remote.c | |||
@@ -0,0 +1,867 @@ | |||
1 | /* | ||
2 | * USB ATI Remote support | ||
3 | * | ||
4 | * Version 2.2.0 Copyright (c) 2004 Torrey Hoffman <thoffman@arnor.net> | ||
5 | * Version 2.1.1 Copyright (c) 2002 Vladimir Dergachev | ||
6 | * | ||
7 | * This 2.2.0 version is a rewrite / cleanup of the 2.1.1 driver, including | ||
8 | * porting to the 2.6 kernel interfaces, along with other modification | ||
9 | * to better match the style of the existing usb/input drivers. However, the | ||
10 | * protocol and hardware handling is essentially unchanged from 2.1.1. | ||
11 | * | ||
12 | * The 2.1.1 driver was derived from the usbati_remote and usbkbd drivers by | ||
13 | * Vojtech Pavlik. | ||
14 | * | ||
15 | * Changes: | ||
16 | * | ||
17 | * Feb 2004: Torrey Hoffman <thoffman@arnor.net> | ||
18 | * Version 2.2.0 | ||
19 | * Jun 2004: Torrey Hoffman <thoffman@arnor.net> | ||
20 | * Version 2.2.1 | ||
21 | * Added key repeat support contributed by: | ||
22 | * Vincent Vanackere <vanackere@lif.univ-mrs.fr> | ||
23 | * Added support for the "Lola" remote contributed by: | ||
24 | * Seth Cohn <sethcohn@yahoo.com> | ||
25 | * | ||
26 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | ||
27 | * | ||
28 | * This program is free software; you can redistribute it and/or modify | ||
29 | * it under the terms of the GNU General Public License as published by | ||
30 | * the Free Software Foundation; either version 2 of the License, or | ||
31 | * (at your option) any later version. | ||
32 | * | ||
33 | * This program is distributed in the hope that it will be useful, | ||
34 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
35 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
36 | * GNU General Public License for more details. | ||
37 | * | ||
38 | * You should have received a copy of the GNU General Public License | ||
39 | * along with this program; if not, write to the Free Software | ||
40 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
41 | * | ||
42 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | ||
43 | * | ||
44 | * Hardware & software notes | ||
45 | * | ||
46 | * These remote controls are distributed by ATI as part of their | ||
47 | * "All-In-Wonder" video card packages. The receiver self-identifies as a | ||
48 | * "USB Receiver" with manufacturer "X10 Wireless Technology Inc". | ||
49 | * | ||
50 | * The "Lola" remote is available from X10. See: | ||
51 | * http://www.x10.com/products/lola_sg1.htm | ||
52 | * The Lola is similar to the ATI remote but has no mouse support, and slightly | ||
53 | * different keys. | ||
54 | * | ||
55 | * It is possible to use multiple receivers and remotes on multiple computers | ||
56 | * simultaneously by configuring them to use specific channels. | ||
57 | * | ||
58 | * The RF protocol used by the remote supports 16 distinct channels, 1 to 16. | ||
59 | * Actually, it may even support more, at least in some revisions of the | ||
60 | * hardware. | ||
61 | * | ||
62 | * Each remote can be configured to transmit on one channel as follows: | ||
63 | * - Press and hold the "hand icon" button. | ||
64 | * - When the red LED starts to blink, let go of the "hand icon" button. | ||
65 | * - When it stops blinking, input the channel code as two digits, from 01 | ||
66 | * to 16, and press the hand icon again. | ||
67 | * | ||
68 | * The timing can be a little tricky. Try loading the module with debug=1 | ||
69 | * to have the kernel print out messages about the remote control number | ||
70 | * and mask. Note: debugging prints remote numbers as zero-based hexadecimal. | ||
71 | * | ||
72 | * The driver has a "channel_mask" parameter. This bitmask specifies which | ||
73 | * channels will be ignored by the module. To mask out channels, just add | ||
74 | * all the 2^channel_number values together. | ||
75 | * | ||
76 | * For instance, set channel_mask = 2^4 = 16 (binary 10000) to make ati_remote | ||
77 | * ignore signals coming from remote controls transmitting on channel 4, but | ||
78 | * accept all other channels. | ||
79 | * | ||
80 | * Or, set channel_mask = 65533, (0xFFFD), and all channels except 1 will be | ||
81 | * ignored. | ||
82 | * | ||
83 | * The default is 0 (respond to all channels). Bit 0 and bits 17-32 of this | ||
84 | * parameter are unused. | ||
85 | * | ||
86 | */ | ||
87 | |||
88 | #include <linux/kernel.h> | ||
89 | #include <linux/errno.h> | ||
90 | #include <linux/init.h> | ||
91 | #include <linux/slab.h> | ||
92 | #include <linux/module.h> | ||
93 | #include <linux/usb/input.h> | ||
94 | #include <linux/wait.h> | ||
95 | #include <linux/jiffies.h> | ||
96 | |||
97 | /* | ||
98 | * Module and Version Information, Module Parameters | ||
99 | */ | ||
100 | |||
101 | #define ATI_REMOTE_VENDOR_ID 0x0bc7 | ||
102 | #define LOLA_REMOTE_PRODUCT_ID 0x0002 | ||
103 | #define LOLA2_REMOTE_PRODUCT_ID 0x0003 | ||
104 | #define ATI_REMOTE_PRODUCT_ID 0x0004 | ||
105 | #define NVIDIA_REMOTE_PRODUCT_ID 0x0005 | ||
106 | #define MEDION_REMOTE_PRODUCT_ID 0x0006 | ||
107 | |||
108 | #define DRIVER_VERSION "2.2.1" | ||
109 | #define DRIVER_AUTHOR "Torrey Hoffman <thoffman@arnor.net>" | ||
110 | #define DRIVER_DESC "ATI/X10 RF USB Remote Control" | ||
111 | |||
112 | #define NAME_BUFSIZE 80 /* size of product name, path buffers */ | ||
113 | #define DATA_BUFSIZE 63 /* size of URB data buffers */ | ||
114 | |||
115 | /* | ||
116 | * Duplicate event filtering time. | ||
117 | * Sequential, identical KIND_FILTERED inputs with less than | ||
118 | * FILTER_TIME milliseconds between them are considered as repeat | ||
119 | * events. The hardware generates 5 events for the first keypress | ||
120 | * and we have to take this into account for an accurate repeat | ||
121 | * behaviour. | ||
122 | */ | ||
123 | #define FILTER_TIME 60 /* msec */ | ||
124 | #define REPEAT_DELAY 500 /* msec */ | ||
125 | |||
126 | static unsigned long channel_mask; | ||
127 | module_param(channel_mask, ulong, 0644); | ||
128 | MODULE_PARM_DESC(channel_mask, "Bitmask of remote control channels to ignore"); | ||
129 | |||
130 | static int debug; | ||
131 | module_param(debug, int, 0644); | ||
132 | MODULE_PARM_DESC(debug, "Enable extra debug messages and information"); | ||
133 | |||
134 | static int repeat_filter = FILTER_TIME; | ||
135 | module_param(repeat_filter, int, 0644); | ||
136 | MODULE_PARM_DESC(repeat_filter, "Repeat filter time, default = 60 msec"); | ||
137 | |||
138 | static int repeat_delay = REPEAT_DELAY; | ||
139 | module_param(repeat_delay, int, 0644); | ||
140 | MODULE_PARM_DESC(repeat_delay, "Delay before sending repeats, default = 500 msec"); | ||
141 | |||
142 | #define dbginfo(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0) | ||
143 | #undef err | ||
144 | #define err(format, arg...) printk(KERN_ERR format , ## arg) | ||
145 | |||
146 | static struct usb_device_id ati_remote_table[] = { | ||
147 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID) }, | ||
148 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA2_REMOTE_PRODUCT_ID) }, | ||
149 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID) }, | ||
150 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, NVIDIA_REMOTE_PRODUCT_ID) }, | ||
151 | { USB_DEVICE(ATI_REMOTE_VENDOR_ID, MEDION_REMOTE_PRODUCT_ID) }, | ||
152 | {} /* Terminating entry */ | ||
153 | }; | ||
154 | |||
155 | MODULE_DEVICE_TABLE(usb, ati_remote_table); | ||
156 | |||
157 | /* Get hi and low bytes of a 16-bits int */ | ||
158 | #define HI(a) ((unsigned char)((a) >> 8)) | ||
159 | #define LO(a) ((unsigned char)((a) & 0xff)) | ||
160 | |||
161 | #define SEND_FLAG_IN_PROGRESS 1 | ||
162 | #define SEND_FLAG_COMPLETE 2 | ||
163 | |||
164 | /* Device initialization strings */ | ||
165 | static char init1[] = { 0x01, 0x00, 0x20, 0x14 }; | ||
166 | static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 }; | ||
167 | |||
168 | struct ati_remote { | ||
169 | struct input_dev *idev; | ||
170 | struct usb_device *udev; | ||
171 | struct usb_interface *interface; | ||
172 | |||
173 | struct urb *irq_urb; | ||
174 | struct urb *out_urb; | ||
175 | struct usb_endpoint_descriptor *endpoint_in; | ||
176 | struct usb_endpoint_descriptor *endpoint_out; | ||
177 | unsigned char *inbuf; | ||
178 | unsigned char *outbuf; | ||
179 | dma_addr_t inbuf_dma; | ||
180 | dma_addr_t outbuf_dma; | ||
181 | |||
182 | unsigned char old_data[2]; /* Detect duplicate events */ | ||
183 | unsigned long old_jiffies; | ||
184 | unsigned long acc_jiffies; /* handle acceleration */ | ||
185 | unsigned long first_jiffies; | ||
186 | |||
187 | unsigned int repeat_count; | ||
188 | |||
189 | char name[NAME_BUFSIZE]; | ||
190 | char phys[NAME_BUFSIZE]; | ||
191 | |||
192 | wait_queue_head_t wait; | ||
193 | int send_flags; | ||
194 | }; | ||
195 | |||
196 | /* "Kinds" of messages sent from the hardware to the driver. */ | ||
197 | #define KIND_END 0 | ||
198 | #define KIND_LITERAL 1 /* Simply pass to input system */ | ||
199 | #define KIND_FILTERED 2 /* Add artificial key-up events, drop keyrepeats */ | ||
200 | #define KIND_LU 3 /* Directional keypad diagonals - left up, */ | ||
201 | #define KIND_RU 4 /* right up, */ | ||
202 | #define KIND_LD 5 /* left down, */ | ||
203 | #define KIND_RD 6 /* right down */ | ||
204 | #define KIND_ACCEL 7 /* Directional keypad - left, right, up, down.*/ | ||
205 | |||
206 | /* Translation table from hardware messages to input events. */ | ||
207 | static const struct { | ||
208 | short kind; | ||
209 | unsigned char data1, data2; | ||
210 | int type; | ||
211 | unsigned int code; | ||
212 | int value; | ||
213 | } ati_remote_tbl[] = { | ||
214 | /* Directional control pad axes */ | ||
215 | {KIND_ACCEL, 0x35, 0x70, EV_REL, REL_X, -1}, /* left */ | ||
216 | {KIND_ACCEL, 0x36, 0x71, EV_REL, REL_X, 1}, /* right */ | ||
217 | {KIND_ACCEL, 0x37, 0x72, EV_REL, REL_Y, -1}, /* up */ | ||
218 | {KIND_ACCEL, 0x38, 0x73, EV_REL, REL_Y, 1}, /* down */ | ||
219 | /* Directional control pad diagonals */ | ||
220 | {KIND_LU, 0x39, 0x74, EV_REL, 0, 0}, /* left up */ | ||
221 | {KIND_RU, 0x3a, 0x75, EV_REL, 0, 0}, /* right up */ | ||
222 | {KIND_LD, 0x3c, 0x77, EV_REL, 0, 0}, /* left down */ | ||
223 | {KIND_RD, 0x3b, 0x76, EV_REL, 0, 0}, /* right down */ | ||
224 | |||
225 | /* "Mouse button" buttons */ | ||
226 | {KIND_LITERAL, 0x3d, 0x78, EV_KEY, BTN_LEFT, 1}, /* left btn down */ | ||
227 | {KIND_LITERAL, 0x3e, 0x79, EV_KEY, BTN_LEFT, 0}, /* left btn up */ | ||
228 | {KIND_LITERAL, 0x41, 0x7c, EV_KEY, BTN_RIGHT, 1},/* right btn down */ | ||
229 | {KIND_LITERAL, 0x42, 0x7d, EV_KEY, BTN_RIGHT, 0},/* right btn up */ | ||
230 | |||
231 | /* Artificial "doubleclick" events are generated by the hardware. | ||
232 | * They are mapped to the "side" and "extra" mouse buttons here. */ | ||
233 | {KIND_FILTERED, 0x3f, 0x7a, EV_KEY, BTN_SIDE, 1}, /* left dblclick */ | ||
234 | {KIND_FILTERED, 0x43, 0x7e, EV_KEY, BTN_EXTRA, 1},/* right dblclick */ | ||
235 | |||
236 | /* keyboard. */ | ||
237 | {KIND_FILTERED, 0xd2, 0x0d, EV_KEY, KEY_1, 1}, | ||
238 | {KIND_FILTERED, 0xd3, 0x0e, EV_KEY, KEY_2, 1}, | ||
239 | {KIND_FILTERED, 0xd4, 0x0f, EV_KEY, KEY_3, 1}, | ||
240 | {KIND_FILTERED, 0xd5, 0x10, EV_KEY, KEY_4, 1}, | ||
241 | {KIND_FILTERED, 0xd6, 0x11, EV_KEY, KEY_5, 1}, | ||
242 | {KIND_FILTERED, 0xd7, 0x12, EV_KEY, KEY_6, 1}, | ||
243 | {KIND_FILTERED, 0xd8, 0x13, EV_KEY, KEY_7, 1}, | ||
244 | {KIND_FILTERED, 0xd9, 0x14, EV_KEY, KEY_8, 1}, | ||
245 | {KIND_FILTERED, 0xda, 0x15, EV_KEY, KEY_9, 1}, | ||
246 | {KIND_FILTERED, 0xdc, 0x17, EV_KEY, KEY_0, 1}, | ||
247 | {KIND_FILTERED, 0xc5, 0x00, EV_KEY, KEY_A, 1}, | ||
248 | {KIND_FILTERED, 0xc6, 0x01, EV_KEY, KEY_B, 1}, | ||
249 | {KIND_FILTERED, 0xde, 0x19, EV_KEY, KEY_C, 1}, | ||
250 | {KIND_FILTERED, 0xe0, 0x1b, EV_KEY, KEY_D, 1}, | ||
251 | {KIND_FILTERED, 0xe6, 0x21, EV_KEY, KEY_E, 1}, | ||
252 | {KIND_FILTERED, 0xe8, 0x23, EV_KEY, KEY_F, 1}, | ||
253 | |||
254 | /* "special" keys */ | ||
255 | {KIND_FILTERED, 0xdd, 0x18, EV_KEY, KEY_KPENTER, 1}, /* "check" */ | ||
256 | {KIND_FILTERED, 0xdb, 0x16, EV_KEY, KEY_MENU, 1}, /* "menu" */ | ||
257 | {KIND_FILTERED, 0xc7, 0x02, EV_KEY, KEY_POWER, 1}, /* Power */ | ||
258 | {KIND_FILTERED, 0xc8, 0x03, EV_KEY, KEY_TV, 1}, /* TV */ | ||
259 | {KIND_FILTERED, 0xc9, 0x04, EV_KEY, KEY_DVD, 1}, /* DVD */ | ||
260 | {KIND_FILTERED, 0xca, 0x05, EV_KEY, KEY_WWW, 1}, /* WEB */ | ||
261 | {KIND_FILTERED, 0xcb, 0x06, EV_KEY, KEY_BOOKMARKS, 1}, /* "book" */ | ||
262 | {KIND_FILTERED, 0xcc, 0x07, EV_KEY, KEY_EDIT, 1}, /* "hand" */ | ||
263 | {KIND_FILTERED, 0xe1, 0x1c, EV_KEY, KEY_COFFEE, 1}, /* "timer" */ | ||
264 | {KIND_FILTERED, 0xe5, 0x20, EV_KEY, KEY_FRONT, 1}, /* "max" */ | ||
265 | {KIND_FILTERED, 0xe2, 0x1d, EV_KEY, KEY_LEFT, 1}, /* left */ | ||
266 | {KIND_FILTERED, 0xe4, 0x1f, EV_KEY, KEY_RIGHT, 1}, /* right */ | ||
267 | {KIND_FILTERED, 0xe7, 0x22, EV_KEY, KEY_DOWN, 1}, /* down */ | ||
268 | {KIND_FILTERED, 0xdf, 0x1a, EV_KEY, KEY_UP, 1}, /* up */ | ||
269 | {KIND_FILTERED, 0xe3, 0x1e, EV_KEY, KEY_OK, 1}, /* "OK" */ | ||
270 | {KIND_FILTERED, 0xce, 0x09, EV_KEY, KEY_VOLUMEDOWN, 1}, /* VOL + */ | ||
271 | {KIND_FILTERED, 0xcd, 0x08, EV_KEY, KEY_VOLUMEUP, 1}, /* VOL - */ | ||
272 | {KIND_FILTERED, 0xcf, 0x0a, EV_KEY, KEY_MUTE, 1}, /* MUTE */ | ||
273 | {KIND_FILTERED, 0xd0, 0x0b, EV_KEY, KEY_CHANNELUP, 1}, /* CH + */ | ||
274 | {KIND_FILTERED, 0xd1, 0x0c, EV_KEY, KEY_CHANNELDOWN, 1},/* CH - */ | ||
275 | {KIND_FILTERED, 0xec, 0x27, EV_KEY, KEY_RECORD, 1}, /* ( o) red */ | ||
276 | {KIND_FILTERED, 0xea, 0x25, EV_KEY, KEY_PLAY, 1}, /* ( >) */ | ||
277 | {KIND_FILTERED, 0xe9, 0x24, EV_KEY, KEY_REWIND, 1}, /* (<<) */ | ||
278 | {KIND_FILTERED, 0xeb, 0x26, EV_KEY, KEY_FORWARD, 1}, /* (>>) */ | ||
279 | {KIND_FILTERED, 0xed, 0x28, EV_KEY, KEY_STOP, 1}, /* ([]) */ | ||
280 | {KIND_FILTERED, 0xee, 0x29, EV_KEY, KEY_PAUSE, 1}, /* ('') */ | ||
281 | {KIND_FILTERED, 0xf0, 0x2b, EV_KEY, KEY_PREVIOUS, 1}, /* (<-) */ | ||
282 | {KIND_FILTERED, 0xef, 0x2a, EV_KEY, KEY_NEXT, 1}, /* (>+) */ | ||
283 | {KIND_FILTERED, 0xf2, 0x2D, EV_KEY, KEY_INFO, 1}, /* PLAYING */ | ||
284 | {KIND_FILTERED, 0xf3, 0x2E, EV_KEY, KEY_HOME, 1}, /* TOP */ | ||
285 | {KIND_FILTERED, 0xf4, 0x2F, EV_KEY, KEY_END, 1}, /* END */ | ||
286 | {KIND_FILTERED, 0xf5, 0x30, EV_KEY, KEY_SELECT, 1}, /* SELECT */ | ||
287 | |||
288 | {KIND_END, 0x00, 0x00, EV_MAX + 1, 0, 0} | ||
289 | }; | ||
290 | |||
291 | /* Local function prototypes */ | ||
292 | static int ati_remote_open (struct input_dev *inputdev); | ||
293 | static void ati_remote_close (struct input_dev *inputdev); | ||
294 | static int ati_remote_sendpacket (struct ati_remote *ati_remote, u16 cmd, unsigned char *data); | ||
295 | static void ati_remote_irq_out (struct urb *urb); | ||
296 | static void ati_remote_irq_in (struct urb *urb); | ||
297 | static void ati_remote_input_report (struct urb *urb); | ||
298 | static int ati_remote_initialize (struct ati_remote *ati_remote); | ||
299 | static int ati_remote_probe (struct usb_interface *interface, const struct usb_device_id *id); | ||
300 | static void ati_remote_disconnect (struct usb_interface *interface); | ||
301 | |||
302 | /* usb specific object to register with the usb subsystem */ | ||
303 | static struct usb_driver ati_remote_driver = { | ||
304 | .name = "ati_remote", | ||
305 | .probe = ati_remote_probe, | ||
306 | .disconnect = ati_remote_disconnect, | ||
307 | .id_table = ati_remote_table, | ||
308 | }; | ||
309 | |||
310 | /* | ||
311 | * ati_remote_dump_input | ||
312 | */ | ||
313 | static void ati_remote_dump(struct device *dev, unsigned char *data, | ||
314 | unsigned int len) | ||
315 | { | ||
316 | if ((len == 1) && (data[0] != (unsigned char)0xff) && (data[0] != 0x00)) | ||
317 | dev_warn(dev, "Weird byte 0x%02x\n", data[0]); | ||
318 | else if (len == 4) | ||
319 | dev_warn(dev, "Weird key %02x %02x %02x %02x\n", | ||
320 | data[0], data[1], data[2], data[3]); | ||
321 | else | ||
322 | dev_warn(dev, "Weird data, len=%d %02x %02x %02x %02x %02x %02x ...\n", | ||
323 | len, data[0], data[1], data[2], data[3], data[4], data[5]); | ||
324 | } | ||
325 | |||
326 | /* | ||
327 | * ati_remote_open | ||
328 | */ | ||
329 | static int ati_remote_open(struct input_dev *inputdev) | ||
330 | { | ||
331 | struct ati_remote *ati_remote = input_get_drvdata(inputdev); | ||
332 | |||
333 | /* On first open, submit the read urb which was set up previously. */ | ||
334 | ati_remote->irq_urb->dev = ati_remote->udev; | ||
335 | if (usb_submit_urb(ati_remote->irq_urb, GFP_KERNEL)) { | ||
336 | dev_err(&ati_remote->interface->dev, | ||
337 | "%s: usb_submit_urb failed!\n", __func__); | ||
338 | return -EIO; | ||
339 | } | ||
340 | |||
341 | return 0; | ||
342 | } | ||
343 | |||
344 | /* | ||
345 | * ati_remote_close | ||
346 | */ | ||
347 | static void ati_remote_close(struct input_dev *inputdev) | ||
348 | { | ||
349 | struct ati_remote *ati_remote = input_get_drvdata(inputdev); | ||
350 | |||
351 | usb_kill_urb(ati_remote->irq_urb); | ||
352 | } | ||
353 | |||
354 | /* | ||
355 | * ati_remote_irq_out | ||
356 | */ | ||
357 | static void ati_remote_irq_out(struct urb *urb) | ||
358 | { | ||
359 | struct ati_remote *ati_remote = urb->context; | ||
360 | |||
361 | if (urb->status) { | ||
362 | dev_dbg(&ati_remote->interface->dev, "%s: status %d\n", | ||
363 | __func__, urb->status); | ||
364 | return; | ||
365 | } | ||
366 | |||
367 | ati_remote->send_flags |= SEND_FLAG_COMPLETE; | ||
368 | wmb(); | ||
369 | wake_up(&ati_remote->wait); | ||
370 | } | ||
371 | |||
372 | /* | ||
373 | * ati_remote_sendpacket | ||
374 | * | ||
375 | * Used to send device initialization strings | ||
376 | */ | ||
377 | static int ati_remote_sendpacket(struct ati_remote *ati_remote, u16 cmd, unsigned char *data) | ||
378 | { | ||
379 | int retval = 0; | ||
380 | |||
381 | /* Set up out_urb */ | ||
382 | memcpy(ati_remote->out_urb->transfer_buffer + 1, data, LO(cmd)); | ||
383 | ((char *) ati_remote->out_urb->transfer_buffer)[0] = HI(cmd); | ||
384 | |||
385 | ati_remote->out_urb->transfer_buffer_length = LO(cmd) + 1; | ||
386 | ati_remote->out_urb->dev = ati_remote->udev; | ||
387 | ati_remote->send_flags = SEND_FLAG_IN_PROGRESS; | ||
388 | |||
389 | retval = usb_submit_urb(ati_remote->out_urb, GFP_ATOMIC); | ||
390 | if (retval) { | ||
391 | dev_dbg(&ati_remote->interface->dev, | ||
392 | "sendpacket: usb_submit_urb failed: %d\n", retval); | ||
393 | return retval; | ||
394 | } | ||
395 | |||
396 | wait_event_timeout(ati_remote->wait, | ||
397 | ((ati_remote->out_urb->status != -EINPROGRESS) || | ||
398 | (ati_remote->send_flags & SEND_FLAG_COMPLETE)), | ||
399 | HZ); | ||
400 | usb_kill_urb(ati_remote->out_urb); | ||
401 | |||
402 | return retval; | ||
403 | } | ||
404 | |||
405 | /* | ||
406 | * ati_remote_event_lookup | ||
407 | */ | ||
408 | static int ati_remote_event_lookup(int rem, unsigned char d1, unsigned char d2) | ||
409 | { | ||
410 | int i; | ||
411 | |||
412 | for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) { | ||
413 | /* | ||
414 | * Decide if the table entry matches the remote input. | ||
415 | */ | ||
416 | if ((((ati_remote_tbl[i].data1 & 0x0f) == (d1 & 0x0f))) && | ||
417 | ((((ati_remote_tbl[i].data1 >> 4) - | ||
418 | (d1 >> 4) + rem) & 0x0f) == 0x0f) && | ||
419 | (ati_remote_tbl[i].data2 == d2)) | ||
420 | return i; | ||
421 | |||
422 | } | ||
423 | return -1; | ||
424 | } | ||
425 | |||
426 | /* | ||
427 | * ati_remote_compute_accel | ||
428 | * | ||
429 | * Implements acceleration curve for directional control pad | ||
430 | * If elapsed time since last event is > 1/4 second, user "stopped", | ||
431 | * so reset acceleration. Otherwise, user is probably holding the control | ||
432 | * pad down, so we increase acceleration, ramping up over two seconds to | ||
433 | * a maximum speed. | ||
434 | */ | ||
435 | static int ati_remote_compute_accel(struct ati_remote *ati_remote) | ||
436 | { | ||
437 | static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 }; | ||
438 | unsigned long now = jiffies; | ||
439 | int acc; | ||
440 | |||
441 | if (time_after(now, ati_remote->old_jiffies + msecs_to_jiffies(250))) { | ||
442 | acc = 1; | ||
443 | ati_remote->acc_jiffies = now; | ||
444 | } | ||
445 | else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(125))) | ||
446 | acc = accel[0]; | ||
447 | else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(250))) | ||
448 | acc = accel[1]; | ||
449 | else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(500))) | ||
450 | acc = accel[2]; | ||
451 | else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(1000))) | ||
452 | acc = accel[3]; | ||
453 | else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(1500))) | ||
454 | acc = accel[4]; | ||
455 | else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(2000))) | ||
456 | acc = accel[5]; | ||
457 | else | ||
458 | acc = accel[6]; | ||
459 | |||
460 | return acc; | ||
461 | } | ||
462 | |||
463 | /* | ||
464 | * ati_remote_report_input | ||
465 | */ | ||
466 | static void ati_remote_input_report(struct urb *urb) | ||
467 | { | ||
468 | struct ati_remote *ati_remote = urb->context; | ||
469 | unsigned char *data= ati_remote->inbuf; | ||
470 | struct input_dev *dev = ati_remote->idev; | ||
471 | int index, acc; | ||
472 | int remote_num; | ||
473 | |||
474 | /* Deal with strange looking inputs */ | ||
475 | if ( (urb->actual_length != 4) || (data[0] != 0x14) || | ||
476 | ((data[3] & 0x0f) != 0x00) ) { | ||
477 | ati_remote_dump(&urb->dev->dev, data, urb->actual_length); | ||
478 | return; | ||
479 | } | ||
480 | |||
481 | /* Mask unwanted remote channels. */ | ||
482 | /* note: remote_num is 0-based, channel 1 on remote == 0 here */ | ||
483 | remote_num = (data[3] >> 4) & 0x0f; | ||
484 | if (channel_mask & (1 << (remote_num + 1))) { | ||
485 | dbginfo(&ati_remote->interface->dev, | ||
486 | "Masked input from channel 0x%02x: data %02x,%02x, mask= 0x%02lx\n", | ||
487 | remote_num, data[1], data[2], channel_mask); | ||
488 | return; | ||
489 | } | ||
490 | |||
491 | /* Look up event code index in translation table */ | ||
492 | index = ati_remote_event_lookup(remote_num, data[1], data[2]); | ||
493 | if (index < 0) { | ||
494 | dev_warn(&ati_remote->interface->dev, | ||
495 | "Unknown input from channel 0x%02x: data %02x,%02x\n", | ||
496 | remote_num, data[1], data[2]); | ||
497 | return; | ||
498 | } | ||
499 | dbginfo(&ati_remote->interface->dev, | ||
500 | "channel 0x%02x; data %02x,%02x; index %d; keycode %d\n", | ||
501 | remote_num, data[1], data[2], index, ati_remote_tbl[index].code); | ||
502 | |||
503 | if (ati_remote_tbl[index].kind == KIND_LITERAL) { | ||
504 | input_event(dev, ati_remote_tbl[index].type, | ||
505 | ati_remote_tbl[index].code, | ||
506 | ati_remote_tbl[index].value); | ||
507 | input_sync(dev); | ||
508 | |||
509 | ati_remote->old_jiffies = jiffies; | ||
510 | return; | ||
511 | } | ||
512 | |||
513 | if (ati_remote_tbl[index].kind == KIND_FILTERED) { | ||
514 | unsigned long now = jiffies; | ||
515 | |||
516 | /* Filter duplicate events which happen "too close" together. */ | ||
517 | if (ati_remote->old_data[0] == data[1] && | ||
518 | ati_remote->old_data[1] == data[2] && | ||
519 | time_before(now, ati_remote->old_jiffies + | ||
520 | msecs_to_jiffies(repeat_filter))) { | ||
521 | ati_remote->repeat_count++; | ||
522 | } else { | ||
523 | ati_remote->repeat_count = 0; | ||
524 | ati_remote->first_jiffies = now; | ||
525 | } | ||
526 | |||
527 | ati_remote->old_data[0] = data[1]; | ||
528 | ati_remote->old_data[1] = data[2]; | ||
529 | ati_remote->old_jiffies = now; | ||
530 | |||
531 | /* Ensure we skip at least the 4 first duplicate events (generated | ||
532 | * by a single keypress), and continue skipping until repeat_delay | ||
533 | * msecs have passed | ||
534 | */ | ||
535 | if (ati_remote->repeat_count > 0 && | ||
536 | (ati_remote->repeat_count < 5 || | ||
537 | time_before(now, ati_remote->first_jiffies + | ||
538 | msecs_to_jiffies(repeat_delay)))) | ||
539 | return; | ||
540 | |||
541 | |||
542 | input_event(dev, ati_remote_tbl[index].type, | ||
543 | ati_remote_tbl[index].code, 1); | ||
544 | input_sync(dev); | ||
545 | input_event(dev, ati_remote_tbl[index].type, | ||
546 | ati_remote_tbl[index].code, 0); | ||
547 | input_sync(dev); | ||
548 | |||
549 | } else { | ||
550 | |||
551 | /* | ||
552 | * Other event kinds are from the directional control pad, and have an | ||
553 | * acceleration factor applied to them. Without this acceleration, the | ||
554 | * control pad is mostly unusable. | ||
555 | */ | ||
556 | acc = ati_remote_compute_accel(ati_remote); | ||
557 | |||
558 | switch (ati_remote_tbl[index].kind) { | ||
559 | case KIND_ACCEL: | ||
560 | input_event(dev, ati_remote_tbl[index].type, | ||
561 | ati_remote_tbl[index].code, | ||
562 | ati_remote_tbl[index].value * acc); | ||
563 | break; | ||
564 | case KIND_LU: | ||
565 | input_report_rel(dev, REL_X, -acc); | ||
566 | input_report_rel(dev, REL_Y, -acc); | ||
567 | break; | ||
568 | case KIND_RU: | ||
569 | input_report_rel(dev, REL_X, acc); | ||
570 | input_report_rel(dev, REL_Y, -acc); | ||
571 | break; | ||
572 | case KIND_LD: | ||
573 | input_report_rel(dev, REL_X, -acc); | ||
574 | input_report_rel(dev, REL_Y, acc); | ||
575 | break; | ||
576 | case KIND_RD: | ||
577 | input_report_rel(dev, REL_X, acc); | ||
578 | input_report_rel(dev, REL_Y, acc); | ||
579 | break; | ||
580 | default: | ||
581 | dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n", | ||
582 | ati_remote_tbl[index].kind); | ||
583 | } | ||
584 | input_sync(dev); | ||
585 | |||
586 | ati_remote->old_jiffies = jiffies; | ||
587 | ati_remote->old_data[0] = data[1]; | ||
588 | ati_remote->old_data[1] = data[2]; | ||
589 | } | ||
590 | } | ||
591 | |||
592 | /* | ||
593 | * ati_remote_irq_in | ||
594 | */ | ||
595 | static void ati_remote_irq_in(struct urb *urb) | ||
596 | { | ||
597 | struct ati_remote *ati_remote = urb->context; | ||
598 | int retval; | ||
599 | |||
600 | switch (urb->status) { | ||
601 | case 0: /* success */ | ||
602 | ati_remote_input_report(urb); | ||
603 | break; | ||
604 | case -ECONNRESET: /* unlink */ | ||
605 | case -ENOENT: | ||
606 | case -ESHUTDOWN: | ||
607 | dev_dbg(&ati_remote->interface->dev, "%s: urb error status, unlink? \n", | ||
608 | __func__); | ||
609 | return; | ||
610 | default: /* error */ | ||
611 | dev_dbg(&ati_remote->interface->dev, "%s: Nonzero urb status %d\n", | ||
612 | __func__, urb->status); | ||
613 | } | ||
614 | |||
615 | retval = usb_submit_urb(urb, GFP_ATOMIC); | ||
616 | if (retval) | ||
617 | dev_err(&ati_remote->interface->dev, "%s: usb_submit_urb()=%d\n", | ||
618 | __func__, retval); | ||
619 | } | ||
620 | |||
621 | /* | ||
622 | * ati_remote_alloc_buffers | ||
623 | */ | ||
624 | static int ati_remote_alloc_buffers(struct usb_device *udev, | ||
625 | struct ati_remote *ati_remote) | ||
626 | { | ||
627 | ati_remote->inbuf = usb_alloc_coherent(udev, DATA_BUFSIZE, GFP_ATOMIC, | ||
628 | &ati_remote->inbuf_dma); | ||
629 | if (!ati_remote->inbuf) | ||
630 | return -1; | ||
631 | |||
632 | ati_remote->outbuf = usb_alloc_coherent(udev, DATA_BUFSIZE, GFP_ATOMIC, | ||
633 | &ati_remote->outbuf_dma); | ||
634 | if (!ati_remote->outbuf) | ||
635 | return -1; | ||
636 | |||
637 | ati_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
638 | if (!ati_remote->irq_urb) | ||
639 | return -1; | ||
640 | |||
641 | ati_remote->out_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
642 | if (!ati_remote->out_urb) | ||
643 | return -1; | ||
644 | |||
645 | return 0; | ||
646 | } | ||
647 | |||
648 | /* | ||
649 | * ati_remote_free_buffers | ||
650 | */ | ||
651 | static void ati_remote_free_buffers(struct ati_remote *ati_remote) | ||
652 | { | ||
653 | usb_free_urb(ati_remote->irq_urb); | ||
654 | usb_free_urb(ati_remote->out_urb); | ||
655 | |||
656 | usb_free_coherent(ati_remote->udev, DATA_BUFSIZE, | ||
657 | ati_remote->inbuf, ati_remote->inbuf_dma); | ||
658 | |||
659 | usb_free_coherent(ati_remote->udev, DATA_BUFSIZE, | ||
660 | ati_remote->outbuf, ati_remote->outbuf_dma); | ||
661 | } | ||
662 | |||
663 | static void ati_remote_input_init(struct ati_remote *ati_remote) | ||
664 | { | ||
665 | struct input_dev *idev = ati_remote->idev; | ||
666 | int i; | ||
667 | |||
668 | idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); | ||
669 | idev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | | ||
670 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA); | ||
671 | idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); | ||
672 | for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) | ||
673 | if (ati_remote_tbl[i].type == EV_KEY) | ||
674 | set_bit(ati_remote_tbl[i].code, idev->keybit); | ||
675 | |||
676 | input_set_drvdata(idev, ati_remote); | ||
677 | |||
678 | idev->open = ati_remote_open; | ||
679 | idev->close = ati_remote_close; | ||
680 | |||
681 | idev->name = ati_remote->name; | ||
682 | idev->phys = ati_remote->phys; | ||
683 | |||
684 | usb_to_input_id(ati_remote->udev, &idev->id); | ||
685 | idev->dev.parent = &ati_remote->udev->dev; | ||
686 | } | ||
687 | |||
688 | static int ati_remote_initialize(struct ati_remote *ati_remote) | ||
689 | { | ||
690 | struct usb_device *udev = ati_remote->udev; | ||
691 | int pipe, maxp; | ||
692 | |||
693 | init_waitqueue_head(&ati_remote->wait); | ||
694 | |||
695 | /* Set up irq_urb */ | ||
696 | pipe = usb_rcvintpipe(udev, ati_remote->endpoint_in->bEndpointAddress); | ||
697 | maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); | ||
698 | maxp = (maxp > DATA_BUFSIZE) ? DATA_BUFSIZE : maxp; | ||
699 | |||
700 | usb_fill_int_urb(ati_remote->irq_urb, udev, pipe, ati_remote->inbuf, | ||
701 | maxp, ati_remote_irq_in, ati_remote, | ||
702 | ati_remote->endpoint_in->bInterval); | ||
703 | ati_remote->irq_urb->transfer_dma = ati_remote->inbuf_dma; | ||
704 | ati_remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
705 | |||
706 | /* Set up out_urb */ | ||
707 | pipe = usb_sndintpipe(udev, ati_remote->endpoint_out->bEndpointAddress); | ||
708 | maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); | ||
709 | maxp = (maxp > DATA_BUFSIZE) ? DATA_BUFSIZE : maxp; | ||
710 | |||
711 | usb_fill_int_urb(ati_remote->out_urb, udev, pipe, ati_remote->outbuf, | ||
712 | maxp, ati_remote_irq_out, ati_remote, | ||
713 | ati_remote->endpoint_out->bInterval); | ||
714 | ati_remote->out_urb->transfer_dma = ati_remote->outbuf_dma; | ||
715 | ati_remote->out_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
716 | |||
717 | /* send initialization strings */ | ||
718 | if ((ati_remote_sendpacket(ati_remote, 0x8004, init1)) || | ||
719 | (ati_remote_sendpacket(ati_remote, 0x8007, init2))) { | ||
720 | dev_err(&ati_remote->interface->dev, | ||
721 | "Initializing ati_remote hardware failed.\n"); | ||
722 | return -EIO; | ||
723 | } | ||
724 | |||
725 | return 0; | ||
726 | } | ||
727 | |||
728 | /* | ||
729 | * ati_remote_probe | ||
730 | */ | ||
731 | static int ati_remote_probe(struct usb_interface *interface, const struct usb_device_id *id) | ||
732 | { | ||
733 | struct usb_device *udev = interface_to_usbdev(interface); | ||
734 | struct usb_host_interface *iface_host = interface->cur_altsetting; | ||
735 | struct usb_endpoint_descriptor *endpoint_in, *endpoint_out; | ||
736 | struct ati_remote *ati_remote; | ||
737 | struct input_dev *input_dev; | ||
738 | int err = -ENOMEM; | ||
739 | |||
740 | if (iface_host->desc.bNumEndpoints != 2) { | ||
741 | err("%s: Unexpected desc.bNumEndpoints\n", __func__); | ||
742 | return -ENODEV; | ||
743 | } | ||
744 | |||
745 | endpoint_in = &iface_host->endpoint[0].desc; | ||
746 | endpoint_out = &iface_host->endpoint[1].desc; | ||
747 | |||
748 | if (!usb_endpoint_is_int_in(endpoint_in)) { | ||
749 | err("%s: Unexpected endpoint_in\n", __func__); | ||
750 | return -ENODEV; | ||
751 | } | ||
752 | if (le16_to_cpu(endpoint_in->wMaxPacketSize) == 0) { | ||
753 | err("%s: endpoint_in message size==0? \n", __func__); | ||
754 | return -ENODEV; | ||
755 | } | ||
756 | |||
757 | ati_remote = kzalloc(sizeof (struct ati_remote), GFP_KERNEL); | ||
758 | input_dev = input_allocate_device(); | ||
759 | if (!ati_remote || !input_dev) | ||
760 | goto fail1; | ||
761 | |||
762 | /* Allocate URB buffers, URBs */ | ||
763 | if (ati_remote_alloc_buffers(udev, ati_remote)) | ||
764 | goto fail2; | ||
765 | |||
766 | ati_remote->endpoint_in = endpoint_in; | ||
767 | ati_remote->endpoint_out = endpoint_out; | ||
768 | ati_remote->udev = udev; | ||
769 | ati_remote->idev = input_dev; | ||
770 | ati_remote->interface = interface; | ||
771 | |||
772 | usb_make_path(udev, ati_remote->phys, sizeof(ati_remote->phys)); | ||
773 | strlcat(ati_remote->phys, "/input0", sizeof(ati_remote->phys)); | ||
774 | |||
775 | if (udev->manufacturer) | ||
776 | strlcpy(ati_remote->name, udev->manufacturer, sizeof(ati_remote->name)); | ||
777 | |||
778 | if (udev->product) | ||
779 | snprintf(ati_remote->name, sizeof(ati_remote->name), | ||
780 | "%s %s", ati_remote->name, udev->product); | ||
781 | |||
782 | if (!strlen(ati_remote->name)) | ||
783 | snprintf(ati_remote->name, sizeof(ati_remote->name), | ||
784 | DRIVER_DESC "(%04x,%04x)", | ||
785 | le16_to_cpu(ati_remote->udev->descriptor.idVendor), | ||
786 | le16_to_cpu(ati_remote->udev->descriptor.idProduct)); | ||
787 | |||
788 | ati_remote_input_init(ati_remote); | ||
789 | |||
790 | /* Device Hardware Initialization - fills in ati_remote->idev from udev. */ | ||
791 | err = ati_remote_initialize(ati_remote); | ||
792 | if (err) | ||
793 | goto fail3; | ||
794 | |||
795 | /* Set up and register input device */ | ||
796 | err = input_register_device(ati_remote->idev); | ||
797 | if (err) | ||
798 | goto fail3; | ||
799 | |||
800 | usb_set_intfdata(interface, ati_remote); | ||
801 | return 0; | ||
802 | |||
803 | fail3: usb_kill_urb(ati_remote->irq_urb); | ||
804 | usb_kill_urb(ati_remote->out_urb); | ||
805 | fail2: ati_remote_free_buffers(ati_remote); | ||
806 | fail1: input_free_device(input_dev); | ||
807 | kfree(ati_remote); | ||
808 | return err; | ||
809 | } | ||
810 | |||
811 | /* | ||
812 | * ati_remote_disconnect | ||
813 | */ | ||
814 | static void ati_remote_disconnect(struct usb_interface *interface) | ||
815 | { | ||
816 | struct ati_remote *ati_remote; | ||
817 | |||
818 | ati_remote = usb_get_intfdata(interface); | ||
819 | usb_set_intfdata(interface, NULL); | ||
820 | if (!ati_remote) { | ||
821 | dev_warn(&interface->dev, "%s - null device?\n", __func__); | ||
822 | return; | ||
823 | } | ||
824 | |||
825 | usb_kill_urb(ati_remote->irq_urb); | ||
826 | usb_kill_urb(ati_remote->out_urb); | ||
827 | input_unregister_device(ati_remote->idev); | ||
828 | ati_remote_free_buffers(ati_remote); | ||
829 | kfree(ati_remote); | ||
830 | } | ||
831 | |||
832 | /* | ||
833 | * ati_remote_init | ||
834 | */ | ||
835 | static int __init ati_remote_init(void) | ||
836 | { | ||
837 | int result; | ||
838 | |||
839 | result = usb_register(&ati_remote_driver); | ||
840 | if (result) | ||
841 | printk(KERN_ERR KBUILD_MODNAME | ||
842 | ": usb_register error #%d\n", result); | ||
843 | else | ||
844 | printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" | ||
845 | DRIVER_DESC "\n"); | ||
846 | |||
847 | return result; | ||
848 | } | ||
849 | |||
850 | /* | ||
851 | * ati_remote_exit | ||
852 | */ | ||
853 | static void __exit ati_remote_exit(void) | ||
854 | { | ||
855 | usb_deregister(&ati_remote_driver); | ||
856 | } | ||
857 | |||
858 | /* | ||
859 | * module specification | ||
860 | */ | ||
861 | |||
862 | module_init(ati_remote_init); | ||
863 | module_exit(ati_remote_exit); | ||
864 | |||
865 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
866 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
867 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/misc/cm3217.c b/drivers/input/misc/cm3217.c new file mode 100644 index 00000000000..9c9b60d6961 --- /dev/null +++ b/drivers/input/misc/cm3217.c | |||
@@ -0,0 +1,1081 @@ | |||
1 | /* drivers/input/misc/cm3217.c - cm3217 optical sensors driver | ||
2 | * | ||
3 | * Copyright (C) 2011 Capella Microsystems Inc. | ||
4 | * Author: Frank Hsieh <pengyueh@gmail.com> | ||
5 | * | ||
6 | * This software is licensed under the terms of the GNU General Public | ||
7 | * License version 2, as published by the Free Software Foundation, and | ||
8 | * may be copied, distributed, and modified under those terms. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | #include <linux/delay.h> | ||
18 | #include <linux/earlysuspend.h> | ||
19 | #include <linux/i2c.h> | ||
20 | #include <linux/input.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/workqueue.h> | ||
25 | #include <linux/irq.h> | ||
26 | #include <linux/errno.h> | ||
27 | #include <linux/err.h> | ||
28 | #include <linux/gpio.h> | ||
29 | #include <linux/miscdevice.h> | ||
30 | #include <linux/lightsensor.h> | ||
31 | #include <linux/slab.h> | ||
32 | #include <linux/uaccess.h> | ||
33 | #include <linux/cm3217.h> | ||
34 | #include <linux/wakelock.h> | ||
35 | #include <linux/jiffies.h> | ||
36 | #include <asm/mach-types.h> | ||
37 | #include <asm/setup.h> | ||
38 | |||
39 | #define D(x...) pr_info(x) | ||
40 | |||
41 | #define I2C_RETRY_COUNT 10 | ||
42 | |||
43 | #define LS_POLLING_DELAY 500 | ||
44 | |||
45 | static void report_do_work(struct work_struct *w); | ||
46 | static DECLARE_DELAYED_WORK(report_work, report_do_work); | ||
47 | |||
48 | struct cm3217_info { | ||
49 | struct class *cm3217_class; | ||
50 | struct device *ls_dev; | ||
51 | struct input_dev *ls_input_dev; | ||
52 | |||
53 | struct early_suspend early_suspend; | ||
54 | struct i2c_client *i2c_client; | ||
55 | struct workqueue_struct *lp_wq; | ||
56 | |||
57 | int als_enable; | ||
58 | int als_enabled_before_suspend; | ||
59 | uint16_t *adc_table; | ||
60 | uint16_t cali_table[10]; | ||
61 | int irq; | ||
62 | int ls_calibrate; | ||
63 | int (*power) (int, uint8_t); /* power to the chip */ | ||
64 | |||
65 | uint32_t als_kadc; | ||
66 | uint32_t als_gadc; | ||
67 | uint16_t golden_adc; | ||
68 | |||
69 | int lightsensor_opened; | ||
70 | int current_level; | ||
71 | uint16_t current_adc; | ||
72 | int polling_delay; | ||
73 | }; | ||
74 | |||
75 | struct cm3217_info *lp_info; | ||
76 | |||
77 | int enable_log; | ||
78 | int fLevel = -1; | ||
79 | |||
80 | static struct mutex als_enable_mutex, als_disable_mutex, als_get_adc_mutex; | ||
81 | |||
82 | static int lightsensor_enable(struct cm3217_info *lpi); | ||
83 | static int lightsensor_disable(struct cm3217_info *lpi); | ||
84 | |||
85 | int32_t als_kadc; | ||
86 | |||
87 | static int I2C_RxData(uint16_t slaveAddr, uint8_t *rxData, int length) | ||
88 | { | ||
89 | uint8_t loop_i; | ||
90 | |||
91 | struct i2c_msg msgs[] = { | ||
92 | { | ||
93 | .addr = slaveAddr, | ||
94 | .flags = I2C_M_RD, | ||
95 | .len = length, | ||
96 | .buf = rxData, | ||
97 | }, | ||
98 | }; | ||
99 | |||
100 | for (loop_i = 0; loop_i < I2C_RETRY_COUNT; loop_i++) { | ||
101 | if (i2c_transfer(lp_info->i2c_client->adapter, msgs, 1) > 0) | ||
102 | break; | ||
103 | msleep(10); | ||
104 | } | ||
105 | |||
106 | if (loop_i >= I2C_RETRY_COUNT) { | ||
107 | printk(KERN_ERR "[ERR][CM3217 error] %s retry over %d\n", | ||
108 | __func__, I2C_RETRY_COUNT); | ||
109 | return -EIO; | ||
110 | } | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static int I2C_TxData(uint16_t slaveAddr, uint8_t *txData, int length) | ||
116 | { | ||
117 | uint8_t loop_i; | ||
118 | |||
119 | struct i2c_msg msg[] = { | ||
120 | { | ||
121 | .addr = slaveAddr, | ||
122 | .flags = 0, | ||
123 | .len = length, | ||
124 | .buf = txData, | ||
125 | }, | ||
126 | }; | ||
127 | |||
128 | for (loop_i = 0; loop_i < I2C_RETRY_COUNT; loop_i++) { | ||
129 | if (i2c_transfer(lp_info->i2c_client->adapter, msg, 1) > 0) | ||
130 | break; | ||
131 | msleep(10); | ||
132 | } | ||
133 | |||
134 | if (loop_i >= I2C_RETRY_COUNT) { | ||
135 | printk(KERN_ERR "[ERR][CM3217 error] %s retry over %d\n", | ||
136 | __func__, I2C_RETRY_COUNT); | ||
137 | return -EIO; | ||
138 | } | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | static int _cm3217_I2C_Read_Byte(uint16_t slaveAddr, uint8_t *pdata) | ||
144 | { | ||
145 | uint8_t buffer = 0; | ||
146 | int ret = 0; | ||
147 | |||
148 | if (pdata == NULL) | ||
149 | return -EFAULT; | ||
150 | |||
151 | ret = I2C_RxData(slaveAddr, &buffer, 1); | ||
152 | if (ret < 0) { | ||
153 | pr_err("[ERR][CM3217 error]%s: I2C_RxData fail, slave addr: 0x%x\n", | ||
154 | __func__, slaveAddr); | ||
155 | return ret; | ||
156 | } | ||
157 | |||
158 | *pdata = buffer; | ||
159 | |||
160 | #if 0 | ||
161 | /* Debug use */ | ||
162 | printk(KERN_DEBUG "[CM3217] %s: I2C_RxData[0x%x] = 0x%x\n", | ||
163 | __func__, slaveAddr, buffer); | ||
164 | #endif | ||
165 | |||
166 | return ret; | ||
167 | } | ||
168 | |||
169 | static int _cm3217_I2C_Write_Byte(uint16_t SlaveAddress, uint8_t data) | ||
170 | { | ||
171 | char buffer[2]; | ||
172 | int ret = 0; | ||
173 | |||
174 | #if 0 | ||
175 | /* Debug use */ | ||
176 | printk(KERN_DEBUG | ||
177 | "[CM3217] %s: _cm3217_I2C_Write_Byte[0x%x, 0x%x, 0x%x]\n", | ||
178 | __func__, SlaveAddress, cmd, data); | ||
179 | #endif | ||
180 | |||
181 | buffer[0] = data; | ||
182 | |||
183 | ret = I2C_TxData(SlaveAddress, buffer, 1); | ||
184 | if (ret < 0) { | ||
185 | pr_err("[ERR][CM3217 error]%s: I2C_TxData fail\n", __func__); | ||
186 | return -EIO; | ||
187 | } | ||
188 | |||
189 | return ret; | ||
190 | } | ||
191 | |||
192 | static int get_ls_adc_value(uint16_t *als_step, bool resume) | ||
193 | { | ||
194 | uint8_t lsb, msb; | ||
195 | int ret = 0; | ||
196 | struct cm3217_info *lpi = lp_info; | ||
197 | |||
198 | if (als_step == NULL) | ||
199 | return -EFAULT; | ||
200 | |||
201 | /* Read ALS data: LSB */ | ||
202 | ret = _cm3217_I2C_Read_Byte(ALS_R_LSB_addr, &lsb); | ||
203 | if (ret < 0) { | ||
204 | pr_err("[LS][CM3217 error]%s: _cm3217_I2C_Read_Byte LSB fail\n", | ||
205 | __func__); | ||
206 | return -EIO; | ||
207 | } | ||
208 | |||
209 | /* Read ALS data: MSB */ | ||
210 | ret = _cm3217_I2C_Read_Byte(ALS_R_MSB_addr, &msb); | ||
211 | if (ret < 0) { | ||
212 | pr_err("[LS][CM3217 error]%s: _cm3217_I2C_Read_Byte MSB fail\n", | ||
213 | __func__); | ||
214 | return -EIO; | ||
215 | } | ||
216 | |||
217 | *als_step = (uint16_t) msb; | ||
218 | *als_step <<= 8; | ||
219 | *als_step |= (uint16_t) lsb; | ||
220 | |||
221 | D("[LS][CM3217] %s: raw adc = 0x%X\n", __func__, *als_step); | ||
222 | |||
223 | if (!lpi->ls_calibrate) { | ||
224 | *als_step = (*als_step) * lpi->als_gadc / lpi->als_kadc; | ||
225 | if (*als_step > 0xFFFF) | ||
226 | *als_step = 0xFFFF; | ||
227 | } | ||
228 | |||
229 | return ret; | ||
230 | } | ||
231 | |||
232 | static void report_lsensor_input_event(struct cm3217_info *lpi, bool resume) | ||
233 | { | ||
234 | uint16_t adc_value = 0; | ||
235 | int level = 0, i, ret = 0; | ||
236 | |||
237 | mutex_lock(&als_get_adc_mutex); | ||
238 | |||
239 | ret = get_ls_adc_value(&adc_value, resume); | ||
240 | |||
241 | if (lpi->ls_calibrate) { | ||
242 | for (i = 0; i < 10; i++) { | ||
243 | if (adc_value <= (*(lpi->cali_table + i))) { | ||
244 | level = i; | ||
245 | if (*(lpi->cali_table + i)) | ||
246 | break; | ||
247 | } | ||
248 | /* avoid i = 10, because 'cali_table' of size is 10 */ | ||
249 | if (i == 9) { | ||
250 | level = i; | ||
251 | break; | ||
252 | } | ||
253 | } | ||
254 | } else { | ||
255 | for (i = 0; i < 10; i++) { | ||
256 | if (adc_value <= (*(lpi->adc_table + i))) { | ||
257 | level = i; | ||
258 | if (*(lpi->adc_table + i)) | ||
259 | break; | ||
260 | } | ||
261 | /* avoid i = 10, because 'cali_table' of size is 10 */ | ||
262 | if (i == 9) { | ||
263 | level = i; | ||
264 | break; | ||
265 | } | ||
266 | } | ||
267 | } | ||
268 | |||
269 | if ((i == 0) || (adc_value == 0)) | ||
270 | D("[LS][CM3217] %s: ADC=0x%03X, Level=%d, l_thd equal 0, " | ||
271 | "h_thd = 0x%x\n", __func__, adc_value, level, | ||
272 | *(lpi->cali_table + i)); | ||
273 | else | ||
274 | D("[LS][CM3217] %s: ADC=0x%03X, Level=%d, l_thd = 0x%x, " | ||
275 | "h_thd = 0x%x\n", __func__, adc_value, level, | ||
276 | *(lpi->cali_table + (i - 1)) + 1, *(lpi->cali_table + i)); | ||
277 | |||
278 | lpi->current_level = level; | ||
279 | lpi->current_adc = adc_value; | ||
280 | |||
281 | /* | ||
282 | D("[CM3217] %s: *(lpi->cali_table + (i - 1)) + 1 = 0x%X, " | ||
283 | "*(lpi->cali_table + i) = 0x%x\n", __func__, | ||
284 | *(lpi->cali_table + (i - 1)) + 1, *(lpi->cali_table + i)); | ||
285 | */ | ||
286 | |||
287 | if (fLevel >= 0) { | ||
288 | D("[LS][CM3217] L-sensor force level enable level=%d " | ||
289 | "fLevel=%d\n", level, fLevel); | ||
290 | level = fLevel; | ||
291 | } | ||
292 | |||
293 | input_report_abs(lpi->ls_input_dev, ABS_MISC, level); | ||
294 | input_sync(lpi->ls_input_dev); | ||
295 | |||
296 | mutex_unlock(&als_get_adc_mutex); | ||
297 | } | ||
298 | |||
299 | static void report_do_work(struct work_struct *work) | ||
300 | { | ||
301 | struct cm3217_info *lpi = lp_info; | ||
302 | |||
303 | if (enable_log) | ||
304 | D("[CM3217] %s\n", __func__); | ||
305 | |||
306 | report_lsensor_input_event(lpi, 0); | ||
307 | |||
308 | queue_delayed_work(lpi->lp_wq, &report_work, lpi->polling_delay); | ||
309 | } | ||
310 | |||
311 | static int als_power(int enable) | ||
312 | { | ||
313 | struct cm3217_info *lpi = lp_info; | ||
314 | |||
315 | if (lpi->power) | ||
316 | lpi->power(LS_PWR_ON, 1); | ||
317 | |||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | void lightsensor_set_kvalue(struct cm3217_info *lpi) | ||
322 | { | ||
323 | if (!lpi) { | ||
324 | pr_err("[LS][CM3217 error]%s: ls_info is empty\n", __func__); | ||
325 | return; | ||
326 | } | ||
327 | |||
328 | D("[LS][CM3217] %s: ALS calibrated als_kadc=0x%x\n", | ||
329 | __func__, als_kadc); | ||
330 | |||
331 | if (als_kadc >> 16 == ALS_CALIBRATED) | ||
332 | lpi->als_kadc = als_kadc & 0xFFFF; | ||
333 | else { | ||
334 | lpi->als_kadc = 0; | ||
335 | D("[LS][CM3217] %s: no ALS calibrated\n", __func__); | ||
336 | } | ||
337 | |||
338 | if (lpi->als_kadc && lpi->golden_adc > 0) { | ||
339 | lpi->als_kadc = (lpi->als_kadc > 0 && lpi->als_kadc < 0x1000) ? | ||
340 | lpi->als_kadc : lpi->golden_adc; | ||
341 | lpi->als_gadc = lpi->golden_adc; | ||
342 | } else { | ||
343 | lpi->als_kadc = 1; | ||
344 | lpi->als_gadc = 1; | ||
345 | } | ||
346 | |||
347 | D("[LS][CM3217] %s: als_kadc=0x%x, als_gadc=0x%x\n", | ||
348 | __func__, lpi->als_kadc, lpi->als_gadc); | ||
349 | } | ||
350 | |||
351 | static int lightsensor_update_table(struct cm3217_info *lpi) | ||
352 | { | ||
353 | uint32_t tmpData[10]; | ||
354 | int i; | ||
355 | |||
356 | for (i = 0; i < 10; i++) { | ||
357 | tmpData[i] = (uint32_t) (*(lpi->adc_table + i)) | ||
358 | * lpi->als_kadc / lpi->als_gadc; | ||
359 | if (tmpData[i] <= 0xFFFF) | ||
360 | lpi->cali_table[i] = (uint16_t) tmpData[i]; | ||
361 | else | ||
362 | lpi->cali_table[i] = 0xFFFF; | ||
363 | D("[LS][CM3217] %s: Calibrated adc_table: data[%d], %x\n", | ||
364 | __func__, i, lpi->cali_table[i]); | ||
365 | } | ||
366 | |||
367 | return 0; | ||
368 | } | ||
369 | |||
370 | static int lightsensor_enable(struct cm3217_info *lpi) | ||
371 | { | ||
372 | int ret = 0; | ||
373 | uint8_t cmd = 0; | ||
374 | |||
375 | mutex_lock(&als_enable_mutex); | ||
376 | |||
377 | D("[LS][CM3217] %s\n", __func__); | ||
378 | |||
379 | cmd = (CM3217_ALS_IT_2_T | CM3217_ALS_BIT5_Default_1 | | ||
380 | CM3217_ALS_WDM_DEFAULT_1); | ||
381 | ret = _cm3217_I2C_Write_Byte(ALS_W_CMD1_addr, cmd); | ||
382 | if (ret < 0) | ||
383 | pr_err("[LS][CM3217 error]%s: set auto light sensor fail\n", | ||
384 | __func__); | ||
385 | else { | ||
386 | msleep(50); /* wait for 50 ms for the first report adc */ | ||
387 | |||
388 | /* report an invalid value first to ensure we | ||
389 | * trigger an event when adc_level is zero. | ||
390 | */ | ||
391 | input_report_abs(lpi->ls_input_dev, ABS_MISC, -1); | ||
392 | input_sync(lpi->ls_input_dev); | ||
393 | /* resume, IOCTL and DEVICE_ATTR */ | ||
394 | report_lsensor_input_event(lpi, 1); | ||
395 | lpi->als_enable = 1; | ||
396 | } | ||
397 | |||
398 | queue_delayed_work(lpi->lp_wq, &report_work, lpi->polling_delay); | ||
399 | lpi->als_enable = 1; | ||
400 | |||
401 | mutex_unlock(&als_enable_mutex); | ||
402 | |||
403 | return ret; | ||
404 | } | ||
405 | |||
406 | static int lightsensor_disable(struct cm3217_info *lpi) | ||
407 | { | ||
408 | int ret = 0; | ||
409 | char cmd = 0; | ||
410 | |||
411 | mutex_lock(&als_disable_mutex); | ||
412 | |||
413 | D("[LS][CM3217] %s\n", __func__); | ||
414 | |||
415 | cmd = (CM3217_ALS_IT_2_T | CM3217_ALS_BIT5_Default_1 | | ||
416 | CM3217_ALS_WDM_DEFAULT_1 | CM3217_ALS_SD); | ||
417 | ret = _cm3217_I2C_Write_Byte(ALS_W_CMD1_addr, cmd); | ||
418 | if (ret < 0) | ||
419 | pr_err("[LS][CM3217 error]%s: disable auto light sensor fail\n", | ||
420 | __func__); | ||
421 | else { | ||
422 | lpi->als_enable = 0; | ||
423 | } | ||
424 | |||
425 | cancel_delayed_work(&report_work); | ||
426 | lpi->als_enable = 0; | ||
427 | |||
428 | mutex_unlock(&als_disable_mutex); | ||
429 | |||
430 | return ret; | ||
431 | } | ||
432 | |||
433 | static int lightsensor_open(struct inode *inode, struct file *file) | ||
434 | { | ||
435 | struct cm3217_info *lpi = lp_info; | ||
436 | int rc = 0; | ||
437 | |||
438 | D("[LS][CM3217] %s\n", __func__); | ||
439 | if (lpi->lightsensor_opened) { | ||
440 | pr_err("[LS][CM3217 error]%s: already opened\n", __func__); | ||
441 | rc = -EBUSY; | ||
442 | } | ||
443 | lpi->lightsensor_opened = 1; | ||
444 | |||
445 | return rc; | ||
446 | } | ||
447 | |||
448 | static int lightsensor_release(struct inode *inode, struct file *file) | ||
449 | { | ||
450 | struct cm3217_info *lpi = lp_info; | ||
451 | |||
452 | D("[LS][CM3217] %s\n", __func__); | ||
453 | lpi->lightsensor_opened = 0; | ||
454 | |||
455 | return 0; | ||
456 | } | ||
457 | |||
458 | static long lightsensor_ioctl(struct file *file, unsigned int cmd, | ||
459 | unsigned long arg) | ||
460 | { | ||
461 | int rc, val; | ||
462 | struct cm3217_info *lpi = lp_info; | ||
463 | |||
464 | /* D("[CM3217] %s cmd %d\n", __func__, _IOC_NR(cmd)); */ | ||
465 | |||
466 | switch (cmd) { | ||
467 | case LIGHTSENSOR_IOCTL_ENABLE: | ||
468 | if (get_user(val, (unsigned long __user *)arg)) { | ||
469 | rc = -EFAULT; | ||
470 | break; | ||
471 | } | ||
472 | D("[LS][CM3217] %s LIGHTSENSOR_IOCTL_ENABLE, value = %d\n", | ||
473 | __func__, val); | ||
474 | rc = val ? lightsensor_enable(lpi) : lightsensor_disable(lpi); | ||
475 | break; | ||
476 | |||
477 | case LIGHTSENSOR_IOCTL_GET_ENABLED: | ||
478 | val = lpi->als_enable; | ||
479 | D("[LS][CM3217] %s LIGHTSENSOR_IOCTL_GET_ENABLED, enabled %d\n", | ||
480 | __func__, val); | ||
481 | rc = put_user(val, (unsigned long __user *)arg); | ||
482 | break; | ||
483 | |||
484 | default: | ||
485 | pr_err("[LS][CM3217 error]%s: invalid cmd %d\n", | ||
486 | __func__, _IOC_NR(cmd)); | ||
487 | rc = -EINVAL; | ||
488 | } | ||
489 | |||
490 | return rc; | ||
491 | } | ||
492 | |||
493 | static const struct file_operations lightsensor_fops = { | ||
494 | .owner = THIS_MODULE, | ||
495 | .open = lightsensor_open, | ||
496 | .release = lightsensor_release, | ||
497 | .unlocked_ioctl = lightsensor_ioctl | ||
498 | }; | ||
499 | |||
500 | static struct miscdevice lightsensor_misc = { | ||
501 | .minor = MISC_DYNAMIC_MINOR, | ||
502 | .name = "lightsensor", | ||
503 | .fops = &lightsensor_fops | ||
504 | }; | ||
505 | |||
506 | static ssize_t ls_adc_show(struct device *dev, | ||
507 | struct device_attribute *attr, char *buf) | ||
508 | { | ||
509 | int ret; | ||
510 | struct cm3217_info *lpi = lp_info; | ||
511 | |||
512 | D("[LS][CM3217] %s: ADC = 0x%04X, Level = %d\n", | ||
513 | __func__, lpi->current_adc, lpi->current_level); | ||
514 | |||
515 | ret = sprintf(buf, "ADC[0x%04X] => level %d\n", | ||
516 | lpi->current_adc, lpi->current_level); | ||
517 | |||
518 | return ret; | ||
519 | } | ||
520 | |||
521 | static DEVICE_ATTR(ls_adc, 0664, ls_adc_show, NULL); | ||
522 | |||
523 | static ssize_t ls_enable_show(struct device *dev, | ||
524 | struct device_attribute *attr, char *buf) | ||
525 | { | ||
526 | int ret = 0; | ||
527 | struct cm3217_info *lpi = lp_info; | ||
528 | |||
529 | ret = sprintf(buf, "Light sensor Auto Enable = %d\n", lpi->als_enable); | ||
530 | |||
531 | return ret; | ||
532 | } | ||
533 | |||
534 | static ssize_t ls_enable_store(struct device *dev, | ||
535 | struct device_attribute *attr, | ||
536 | const char *buf, size_t count) | ||
537 | { | ||
538 | int ret = 0; | ||
539 | int ls_auto; | ||
540 | struct cm3217_info *lpi = lp_info; | ||
541 | |||
542 | ls_auto = -1; | ||
543 | sscanf(buf, "%d", &ls_auto); | ||
544 | |||
545 | if (ls_auto != 0 && ls_auto != 1) | ||
546 | return -EINVAL; | ||
547 | |||
548 | if (ls_auto) | ||
549 | ret = lightsensor_enable(lpi); | ||
550 | else | ||
551 | ret = lightsensor_disable(lpi); | ||
552 | |||
553 | D("[LS][CM3217] %s: lpi->als_enable = %d, lpi->ls_calibrate = %d, " | ||
554 | "ls_auto=%d\n", __func__, lpi->als_enable, lpi->ls_calibrate, | ||
555 | ls_auto); | ||
556 | |||
557 | if (ret < 0) | ||
558 | pr_err("[LS][CM3217 error]%s: set auto light sensor fail\n", | ||
559 | __func__); | ||
560 | |||
561 | return count; | ||
562 | } | ||
563 | |||
564 | static DEVICE_ATTR(ls_auto, 0664, ls_enable_show, ls_enable_store); | ||
565 | |||
566 | static ssize_t ls_kadc_show(struct device *dev, | ||
567 | struct device_attribute *attr, char *buf) | ||
568 | { | ||
569 | struct cm3217_info *lpi = lp_info; | ||
570 | int ret; | ||
571 | |||
572 | ret = sprintf(buf, "kadc = 0x%x", lpi->als_kadc); | ||
573 | |||
574 | return ret; | ||
575 | } | ||
576 | |||
577 | static ssize_t ls_kadc_store(struct device *dev, | ||
578 | struct device_attribute *attr, | ||
579 | const char *buf, size_t count) | ||
580 | { | ||
581 | struct cm3217_info *lpi = lp_info; | ||
582 | int kadc_temp = 0; | ||
583 | |||
584 | sscanf(buf, "%d", &kadc_temp); | ||
585 | |||
586 | /* if (kadc_temp <= 0 || lpi->golden_adc <= 0) { | ||
587 | printk(KERN_ERR "[LS][CM3217 error] %s: kadc_temp=0x%x, " | ||
588 | "als_gadc=0x%x\n", __func__, kadc_temp, | ||
589 | lpi->golden_adc); | ||
590 | return -EINVAL; | ||
591 | } */ | ||
592 | |||
593 | mutex_lock(&als_get_adc_mutex); | ||
594 | |||
595 | if (kadc_temp != 0) { | ||
596 | lpi->als_kadc = kadc_temp; | ||
597 | if (lpi->als_gadc != 0) { | ||
598 | if (lightsensor_update_table(lpi) < 0) | ||
599 | printk(KERN_ERR | ||
600 | "[LS][CM3217 error] %s: " | ||
601 | "update ls table fail\n", __func__); | ||
602 | } else { | ||
603 | printk(KERN_INFO | ||
604 | "[LS]%s: als_gadc =0x%x wait to be set\n", | ||
605 | __func__, lpi->als_gadc); | ||
606 | } | ||
607 | } else { | ||
608 | printk(KERN_INFO "[LS]%s: als_kadc can't be set to zero\n", | ||
609 | __func__); | ||
610 | } | ||
611 | |||
612 | mutex_unlock(&als_get_adc_mutex); | ||
613 | |||
614 | return count; | ||
615 | } | ||
616 | |||
617 | static DEVICE_ATTR(ls_kadc, 0664, ls_kadc_show, ls_kadc_store); | ||
618 | |||
619 | static ssize_t ls_gadc_show(struct device *dev, | ||
620 | struct device_attribute *attr, char *buf) | ||
621 | { | ||
622 | struct cm3217_info *lpi = lp_info; | ||
623 | int ret; | ||
624 | |||
625 | ret = sprintf(buf, "gadc = 0x%x\n", lpi->als_gadc); | ||
626 | |||
627 | return ret; | ||
628 | } | ||
629 | |||
630 | static ssize_t ls_gadc_store(struct device *dev, | ||
631 | struct device_attribute *attr, | ||
632 | const char *buf, size_t count) | ||
633 | { | ||
634 | struct cm3217_info *lpi = lp_info; | ||
635 | int gadc_temp = 0; | ||
636 | |||
637 | sscanf(buf, "%d", &gadc_temp); | ||
638 | |||
639 | /* if (gadc_temp <= 0 || lpi->golden_adc <= 0) { | ||
640 | printk(KERN_ERR "[LS][CM3217 error] %s: kadc_temp=0x%x, " | ||
641 | "als_gadc=0x%x\n", __func__, kadc_temp, | ||
642 | lpi->golden_adc); | ||
643 | return -EINVAL; | ||
644 | } */ | ||
645 | |||
646 | mutex_lock(&als_get_adc_mutex); | ||
647 | |||
648 | if (gadc_temp != 0) { | ||
649 | lpi->als_gadc = gadc_temp; | ||
650 | if (lpi->als_kadc != 0) { | ||
651 | if (lightsensor_update_table(lpi) < 0) | ||
652 | printk(KERN_ERR | ||
653 | "[LS][CM3217 error] %s: " | ||
654 | "update ls table fail\n", __func__); | ||
655 | } else { | ||
656 | printk(KERN_INFO | ||
657 | "[LS]%s: als_kadc =0x%x wait to be set\n", | ||
658 | __func__, lpi->als_kadc); | ||
659 | } | ||
660 | } else { | ||
661 | printk(KERN_INFO "[LS]%s: als_gadc can't be set to zero\n", | ||
662 | __func__); | ||
663 | } | ||
664 | |||
665 | mutex_unlock(&als_get_adc_mutex); | ||
666 | |||
667 | return count; | ||
668 | } | ||
669 | |||
670 | static DEVICE_ATTR(ls_gadc, 0664, ls_gadc_show, ls_gadc_store); | ||
671 | |||
672 | static ssize_t ls_adc_table_show(struct device *dev, | ||
673 | struct device_attribute *attr, char *buf) | ||
674 | { | ||
675 | unsigned length = 0; | ||
676 | int i; | ||
677 | |||
678 | for (i = 0; i < 10; i++) { | ||
679 | length += sprintf(buf + length, | ||
680 | "[CM3217]Get adc_table[%d] = 0x%x ; %d, " | ||
681 | "Get cali_table[%d] = 0x%x ; %d,\n", | ||
682 | i, *(lp_info->adc_table + i), | ||
683 | *(lp_info->adc_table + i), | ||
684 | i, *(lp_info->cali_table + i), | ||
685 | *(lp_info->cali_table + i)); | ||
686 | } | ||
687 | |||
688 | return length; | ||
689 | } | ||
690 | |||
691 | static ssize_t ls_adc_table_store(struct device *dev, | ||
692 | struct device_attribute *attr, | ||
693 | const char *buf, size_t count) | ||
694 | { | ||
695 | struct cm3217_info *lpi = lp_info; | ||
696 | char *token[10]; | ||
697 | unsigned long tempdata[10]; | ||
698 | int i, r; | ||
699 | |||
700 | printk(KERN_INFO "[LS][CM3217]%s\n", buf); | ||
701 | for (i = 0; i < 10; i++) { | ||
702 | token[i] = strsep((char **)&buf, " "); | ||
703 | r = kstrtoul(token[i], 16, &tempdata[i]); | ||
704 | if (tempdata[i] < 1 || tempdata[i] > 0xffff || r) { | ||
705 | printk(KERN_ERR | ||
706 | "[LS][CM3217 error] adc_table[%d] = " | ||
707 | "0x%lx Err\n", i, tempdata[i]); | ||
708 | return count; | ||
709 | } | ||
710 | } | ||
711 | |||
712 | mutex_lock(&als_get_adc_mutex); | ||
713 | |||
714 | for (i = 0; i < 10; i++) { | ||
715 | lpi->adc_table[i] = tempdata[i]; | ||
716 | printk(KERN_INFO | ||
717 | "[LS][CM3217]Set lpi->adc_table[%d] = 0x%x\n", | ||
718 | i, *(lp_info->adc_table + i)); | ||
719 | } | ||
720 | if (lightsensor_update_table(lpi) < 0) | ||
721 | printk(KERN_ERR "[LS][CM3217 error] %s: update ls table fail\n", | ||
722 | __func__); | ||
723 | |||
724 | mutex_unlock(&als_get_adc_mutex); | ||
725 | |||
726 | D("[LS][CM3217] %s\n", __func__); | ||
727 | |||
728 | return count; | ||
729 | } | ||
730 | |||
731 | static DEVICE_ATTR(ls_adc_table, 0664, ls_adc_table_show, ls_adc_table_store); | ||
732 | |||
733 | static uint8_t ALS_CONF1; | ||
734 | |||
735 | static ssize_t ls_conf1_show(struct device *dev, | ||
736 | struct device_attribute *attr, char *buf) | ||
737 | { | ||
738 | return sprintf(buf, "ALS_CONF1 = %x\n", ALS_CONF1); | ||
739 | } | ||
740 | |||
741 | static ssize_t ls_conf1_store(struct device *dev, | ||
742 | struct device_attribute *attr, | ||
743 | const char *buf, size_t count) | ||
744 | { | ||
745 | int value = 0; | ||
746 | |||
747 | sscanf(buf, "0x%x", &value); | ||
748 | |||
749 | ALS_CONF1 = value; | ||
750 | printk(KERN_INFO "[LS]set ALS_CONF1 = %x\n", ALS_CONF1); | ||
751 | _cm3217_I2C_Write_Byte(ALS_W_CMD1_addr, ALS_CONF1); | ||
752 | |||
753 | return count; | ||
754 | } | ||
755 | |||
756 | static DEVICE_ATTR(ls_conf1, 0664, ls_conf1_show, ls_conf1_store); | ||
757 | |||
758 | static uint8_t ALS_CONF2; | ||
759 | static ssize_t ls_conf2_show(struct device *dev, | ||
760 | struct device_attribute *attr, char *buf) | ||
761 | { | ||
762 | return sprintf(buf, "ALS_CONF2 = %x\n", ALS_CONF2); | ||
763 | } | ||
764 | |||
765 | static ssize_t ls_conf2_store(struct device *dev, | ||
766 | struct device_attribute *attr, | ||
767 | const char *buf, size_t count) | ||
768 | { | ||
769 | int value = 0; | ||
770 | |||
771 | sscanf(buf, "0x%x", &value); | ||
772 | |||
773 | ALS_CONF2 = value; | ||
774 | printk(KERN_INFO "[LS]set ALS_CONF2 = %x\n", ALS_CONF2); | ||
775 | _cm3217_I2C_Write_Byte(ALS_W_CMD2_addr, ALS_CONF2); | ||
776 | |||
777 | return count; | ||
778 | } | ||
779 | |||
780 | static DEVICE_ATTR(ls_conf2, 0664, ls_conf2_show, ls_conf2_store); | ||
781 | |||
782 | static ssize_t ls_fLevel_show(struct device *dev, | ||
783 | struct device_attribute *attr, char *buf) | ||
784 | { | ||
785 | return sprintf(buf, "fLevel = %d\n", fLevel); | ||
786 | } | ||
787 | |||
788 | static ssize_t ls_fLevel_store(struct device *dev, | ||
789 | struct device_attribute *attr, | ||
790 | const char *buf, size_t count) | ||
791 | { | ||
792 | struct cm3217_info *lpi = lp_info; | ||
793 | int value = 0; | ||
794 | |||
795 | sscanf(buf, "%d", &value); | ||
796 | (value >= 0) ? (value = min(value, 10)) : (value = max(value, -1)); | ||
797 | fLevel = value; | ||
798 | |||
799 | input_report_abs(lpi->ls_input_dev, ABS_MISC, fLevel); | ||
800 | input_sync(lpi->ls_input_dev); | ||
801 | |||
802 | printk(KERN_INFO "[LS]set fLevel = %d\n", fLevel); | ||
803 | |||
804 | msleep(1000); | ||
805 | fLevel = -1; | ||
806 | |||
807 | return count; | ||
808 | } | ||
809 | |||
810 | static DEVICE_ATTR(ls_flevel, 0664, ls_fLevel_show, ls_fLevel_store); | ||
811 | |||
812 | static int lightsensor_setup(struct cm3217_info *lpi) | ||
813 | { | ||
814 | int ret; | ||
815 | |||
816 | lpi->ls_input_dev = input_allocate_device(); | ||
817 | if (!lpi->ls_input_dev) { | ||
818 | pr_err("[LS][CM3217 error]%s: " | ||
819 | "could not allocate ls input device\n", __func__); | ||
820 | return -ENOMEM; | ||
821 | } | ||
822 | lpi->ls_input_dev->name = "cm3217-ls"; | ||
823 | set_bit(EV_ABS, lpi->ls_input_dev->evbit); | ||
824 | input_set_abs_params(lpi->ls_input_dev, ABS_MISC, 0, 9, 0, 0); | ||
825 | |||
826 | ret = input_register_device(lpi->ls_input_dev); | ||
827 | if (ret < 0) { | ||
828 | pr_err("[LS][CM3217 error]%s: " | ||
829 | "can not register ls input device\n", __func__); | ||
830 | goto err_free_ls_input_device; | ||
831 | } | ||
832 | |||
833 | ret = misc_register(&lightsensor_misc); | ||
834 | if (ret < 0) { | ||
835 | pr_err("[LS][CM3217 error]%s: " | ||
836 | "can not register ls misc device\n", __func__); | ||
837 | goto err_unregister_ls_input_device; | ||
838 | } | ||
839 | |||
840 | return ret; | ||
841 | |||
842 | err_unregister_ls_input_device: | ||
843 | input_unregister_device(lpi->ls_input_dev); | ||
844 | err_free_ls_input_device: | ||
845 | input_free_device(lpi->ls_input_dev); | ||
846 | return ret; | ||
847 | } | ||
848 | |||
849 | static int cm3217_setup(struct cm3217_info *lpi) | ||
850 | { | ||
851 | int ret = 0; | ||
852 | |||
853 | als_power(1); | ||
854 | msleep(5); | ||
855 | |||
856 | ret = _cm3217_I2C_Write_Byte(ALS_W_CMD2_addr, | ||
857 | CM3217_ALS_WDM_DEFAULT_1 | ||
858 | | CM3217_ALS_IT_2_T | ||
859 | | CM3217_ALS_BIT5_Default_1); | ||
860 | if (ret < 0) | ||
861 | return ret; | ||
862 | |||
863 | ret = _cm3217_I2C_Write_Byte(ALS_W_CMD2_addr, CM3217_ALS_IT_100ms); | ||
864 | msleep(10); | ||
865 | |||
866 | return ret; | ||
867 | } | ||
868 | |||
869 | static void cm3217_early_suspend(struct early_suspend *h) | ||
870 | { | ||
871 | struct cm3217_info *lpi = lp_info; | ||
872 | |||
873 | D("[LS][CM3217] %s\n", __func__); | ||
874 | |||
875 | lpi->als_enabled_before_suspend = lpi->als_enable; | ||
876 | if (lpi->als_enable) | ||
877 | lightsensor_disable(lpi); | ||
878 | } | ||
879 | |||
880 | static void cm3217_late_resume(struct early_suspend *h) | ||
881 | { | ||
882 | struct cm3217_info *lpi = lp_info; | ||
883 | |||
884 | D("[LS][CM3217] %s\n", __func__); | ||
885 | |||
886 | if (lpi->als_enabled_before_suspend) | ||
887 | lightsensor_enable(lpi); | ||
888 | } | ||
889 | |||
890 | static int cm3217_probe(struct i2c_client *client, | ||
891 | const struct i2c_device_id *id) | ||
892 | { | ||
893 | int ret = 0; | ||
894 | struct cm3217_info *lpi; | ||
895 | struct cm3217_platform_data *pdata; | ||
896 | |||
897 | D("[CM3217] %s\n", __func__); | ||
898 | |||
899 | lpi = kzalloc(sizeof(struct cm3217_info), GFP_KERNEL); | ||
900 | if (!lpi) | ||
901 | return -ENOMEM; | ||
902 | |||
903 | /* D("[CM3217] %s: client->irq = %d\n", __func__, client->irq); */ | ||
904 | |||
905 | lpi->i2c_client = client; | ||
906 | pdata = client->dev.platform_data; | ||
907 | if (!pdata) { | ||
908 | pr_err("[CM3217 error]%s: Assign platform_data error!!\n", | ||
909 | __func__); | ||
910 | ret = -EBUSY; | ||
911 | goto err_platform_data_null; | ||
912 | } | ||
913 | |||
914 | lpi->irq = client->irq; | ||
915 | |||
916 | i2c_set_clientdata(client, lpi); | ||
917 | lpi->adc_table = pdata->levels; | ||
918 | lpi->golden_adc = pdata->golden_adc; | ||
919 | lpi->power = pdata->power; | ||
920 | |||
921 | lpi->polling_delay = msecs_to_jiffies(LS_POLLING_DELAY); | ||
922 | |||
923 | lp_info = lpi; | ||
924 | |||
925 | mutex_init(&als_enable_mutex); | ||
926 | mutex_init(&als_disable_mutex); | ||
927 | mutex_init(&als_get_adc_mutex); | ||
928 | |||
929 | ret = lightsensor_setup(lpi); | ||
930 | if (ret < 0) { | ||
931 | pr_err("[LS][CM3217 error]%s: lightsensor_setup error!!\n", | ||
932 | __func__); | ||
933 | goto err_lightsensor_setup; | ||
934 | } | ||
935 | |||
936 | /* SET LUX STEP FACTOR HERE | ||
937 | * if adc raw value one step = 0.3 lux | ||
938 | * the following will set the factor 0.3 = 3/10 | ||
939 | * and lpi->golden_adc = 3; | ||
940 | * set als_kadc = (ALS_CALIBRATED <<16) | 10; */ | ||
941 | |||
942 | als_kadc = (ALS_CALIBRATED << 16) | 10; | ||
943 | lpi->golden_adc = 3; | ||
944 | |||
945 | /* ls calibrate always set to 1 */ | ||
946 | lpi->ls_calibrate = 1; | ||
947 | |||
948 | lightsensor_set_kvalue(lpi); | ||
949 | ret = lightsensor_update_table(lpi); | ||
950 | if (ret < 0) { | ||
951 | pr_err("[LS][CM3217 error]%s: update ls table fail\n", | ||
952 | __func__); | ||
953 | goto err_lightsensor_update_table; | ||
954 | } | ||
955 | |||
956 | lpi->lp_wq = create_singlethread_workqueue("cm3217_wq"); | ||
957 | if (!lpi->lp_wq) { | ||
958 | pr_err("[CM3217 error]%s: can't create workqueue\n", __func__); | ||
959 | ret = -ENOMEM; | ||
960 | goto err_create_singlethread_workqueue; | ||
961 | } | ||
962 | |||
963 | ret = cm3217_setup(lpi); | ||
964 | if (ret < 0) { | ||
965 | pr_err("[ERR][CM3217 error]%s: cm3217_setup error!\n", | ||
966 | __func__); | ||
967 | goto err_cm3217_setup; | ||
968 | } | ||
969 | |||
970 | lpi->cm3217_class = class_create(THIS_MODULE, "optical_sensors"); | ||
971 | if (IS_ERR(lpi->cm3217_class)) { | ||
972 | ret = PTR_ERR(lpi->cm3217_class); | ||
973 | lpi->cm3217_class = NULL; | ||
974 | goto err_create_class; | ||
975 | } | ||
976 | |||
977 | lpi->ls_dev = device_create(lpi->cm3217_class, | ||
978 | NULL, 0, "%s", "lightsensor"); | ||
979 | if (unlikely(IS_ERR(lpi->ls_dev))) { | ||
980 | ret = PTR_ERR(lpi->ls_dev); | ||
981 | lpi->ls_dev = NULL; | ||
982 | goto err_create_ls_device; | ||
983 | } | ||
984 | |||
985 | /* register the attributes */ | ||
986 | ret = device_create_file(lpi->ls_dev, &dev_attr_ls_adc); | ||
987 | if (ret) | ||
988 | goto err_create_ls_device_file; | ||
989 | |||
990 | /* register the attributes */ | ||
991 | ret = device_create_file(lpi->ls_dev, &dev_attr_ls_auto); | ||
992 | if (ret) | ||
993 | goto err_create_ls_device_file; | ||
994 | |||
995 | /* register the attributes */ | ||
996 | ret = device_create_file(lpi->ls_dev, &dev_attr_ls_kadc); | ||
997 | if (ret) | ||
998 | goto err_create_ls_device_file; | ||
999 | |||
1000 | ret = device_create_file(lpi->ls_dev, &dev_attr_ls_gadc); | ||
1001 | if (ret) | ||
1002 | goto err_create_ls_device_file; | ||
1003 | |||
1004 | ret = device_create_file(lpi->ls_dev, &dev_attr_ls_adc_table); | ||
1005 | if (ret) | ||
1006 | goto err_create_ls_device_file; | ||
1007 | |||
1008 | ret = device_create_file(lpi->ls_dev, &dev_attr_ls_conf1); | ||
1009 | if (ret) | ||
1010 | goto err_create_ls_device_file; | ||
1011 | |||
1012 | ret = device_create_file(lpi->ls_dev, &dev_attr_ls_conf2); | ||
1013 | if (ret) | ||
1014 | goto err_create_ls_device_file; | ||
1015 | |||
1016 | ret = device_create_file(lpi->ls_dev, &dev_attr_ls_flevel); | ||
1017 | if (ret) | ||
1018 | goto err_create_ls_device_file; | ||
1019 | |||
1020 | lpi->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; | ||
1021 | lpi->early_suspend.suspend = cm3217_early_suspend; | ||
1022 | lpi->early_suspend.resume = cm3217_late_resume; | ||
1023 | register_early_suspend(&lpi->early_suspend); | ||
1024 | |||
1025 | lpi->als_enable = 0; | ||
1026 | lpi->als_enabled_before_suspend = 0; | ||
1027 | D("[CM3217] %s: Probe success!\n", __func__); | ||
1028 | |||
1029 | return ret; | ||
1030 | |||
1031 | err_create_ls_device_file: | ||
1032 | device_unregister(lpi->ls_dev); | ||
1033 | err_create_ls_device: | ||
1034 | class_destroy(lpi->cm3217_class); | ||
1035 | err_create_class: | ||
1036 | err_cm3217_setup: | ||
1037 | destroy_workqueue(lpi->lp_wq); | ||
1038 | mutex_destroy(&als_enable_mutex); | ||
1039 | mutex_destroy(&als_disable_mutex); | ||
1040 | mutex_destroy(&als_get_adc_mutex); | ||
1041 | input_unregister_device(lpi->ls_input_dev); | ||
1042 | input_free_device(lpi->ls_input_dev); | ||
1043 | err_create_singlethread_workqueue: | ||
1044 | err_lightsensor_update_table: | ||
1045 | misc_deregister(&lightsensor_misc); | ||
1046 | err_lightsensor_setup: | ||
1047 | err_platform_data_null: | ||
1048 | kfree(lpi); | ||
1049 | return ret; | ||
1050 | } | ||
1051 | |||
1052 | static const struct i2c_device_id cm3217_i2c_id[] = { | ||
1053 | {CM3217_I2C_NAME, 0}, | ||
1054 | {} | ||
1055 | }; | ||
1056 | |||
1057 | static struct i2c_driver cm3217_driver = { | ||
1058 | .id_table = cm3217_i2c_id, | ||
1059 | .probe = cm3217_probe, | ||
1060 | .driver = { | ||
1061 | .name = CM3217_I2C_NAME, | ||
1062 | .owner = THIS_MODULE, | ||
1063 | }, | ||
1064 | }; | ||
1065 | |||
1066 | static int __init cm3217_init(void) | ||
1067 | { | ||
1068 | return i2c_add_driver(&cm3217_driver); | ||
1069 | } | ||
1070 | |||
1071 | static void __exit cm3217_exit(void) | ||
1072 | { | ||
1073 | i2c_del_driver(&cm3217_driver); | ||
1074 | } | ||
1075 | |||
1076 | module_init(cm3217_init); | ||
1077 | module_exit(cm3217_exit); | ||
1078 | |||
1079 | MODULE_LICENSE("GPL"); | ||
1080 | MODULE_DESCRIPTION("CM3217 Driver"); | ||
1081 | MODULE_AUTHOR("Frank Hsieh <pengyueh@gmail.com>"); | ||
diff --git a/drivers/input/misc/gpio_axis.c b/drivers/input/misc/gpio_axis.c new file mode 100644 index 00000000000..0acf4a576f5 --- /dev/null +++ b/drivers/input/misc/gpio_axis.c | |||
@@ -0,0 +1,192 @@ | |||
1 | /* drivers/input/misc/gpio_axis.c | ||
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/gpio.h> | ||
18 | #include <linux/gpio_event.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/slab.h> | ||
21 | |||
22 | struct gpio_axis_state { | ||
23 | struct gpio_event_input_devs *input_devs; | ||
24 | struct gpio_event_axis_info *info; | ||
25 | uint32_t pos; | ||
26 | }; | ||
27 | |||
28 | uint16_t gpio_axis_4bit_gray_map_table[] = { | ||
29 | [0x0] = 0x0, [0x1] = 0x1, /* 0000 0001 */ | ||
30 | [0x3] = 0x2, [0x2] = 0x3, /* 0011 0010 */ | ||
31 | [0x6] = 0x4, [0x7] = 0x5, /* 0110 0111 */ | ||
32 | [0x5] = 0x6, [0x4] = 0x7, /* 0101 0100 */ | ||
33 | [0xc] = 0x8, [0xd] = 0x9, /* 1100 1101 */ | ||
34 | [0xf] = 0xa, [0xe] = 0xb, /* 1111 1110 */ | ||
35 | [0xa] = 0xc, [0xb] = 0xd, /* 1010 1011 */ | ||
36 | [0x9] = 0xe, [0x8] = 0xf, /* 1001 1000 */ | ||
37 | }; | ||
38 | uint16_t gpio_axis_4bit_gray_map(struct gpio_event_axis_info *info, uint16_t in) | ||
39 | { | ||
40 | return gpio_axis_4bit_gray_map_table[in]; | ||
41 | } | ||
42 | |||
43 | uint16_t gpio_axis_5bit_singletrack_map_table[] = { | ||
44 | [0x10] = 0x00, [0x14] = 0x01, [0x1c] = 0x02, /* 10000 10100 11100 */ | ||
45 | [0x1e] = 0x03, [0x1a] = 0x04, [0x18] = 0x05, /* 11110 11010 11000 */ | ||
46 | [0x08] = 0x06, [0x0a] = 0x07, [0x0e] = 0x08, /* 01000 01010 01110 */ | ||
47 | [0x0f] = 0x09, [0x0d] = 0x0a, [0x0c] = 0x0b, /* 01111 01101 01100 */ | ||
48 | [0x04] = 0x0c, [0x05] = 0x0d, [0x07] = 0x0e, /* 00100 00101 00111 */ | ||
49 | [0x17] = 0x0f, [0x16] = 0x10, [0x06] = 0x11, /* 10111 10110 00110 */ | ||
50 | [0x02] = 0x12, [0x12] = 0x13, [0x13] = 0x14, /* 00010 10010 10011 */ | ||
51 | [0x1b] = 0x15, [0x0b] = 0x16, [0x03] = 0x17, /* 11011 01011 00011 */ | ||
52 | [0x01] = 0x18, [0x09] = 0x19, [0x19] = 0x1a, /* 00001 01001 11001 */ | ||
53 | [0x1d] = 0x1b, [0x15] = 0x1c, [0x11] = 0x1d, /* 11101 10101 10001 */ | ||
54 | }; | ||
55 | uint16_t gpio_axis_5bit_singletrack_map( | ||
56 | struct gpio_event_axis_info *info, uint16_t in) | ||
57 | { | ||
58 | return gpio_axis_5bit_singletrack_map_table[in]; | ||
59 | } | ||
60 | |||
61 | static void gpio_event_update_axis(struct gpio_axis_state *as, int report) | ||
62 | { | ||
63 | struct gpio_event_axis_info *ai = as->info; | ||
64 | int i; | ||
65 | int change; | ||
66 | uint16_t state = 0; | ||
67 | uint16_t pos; | ||
68 | uint16_t old_pos = as->pos; | ||
69 | for (i = ai->count - 1; i >= 0; i--) | ||
70 | state = (state << 1) | gpio_get_value(ai->gpio[i]); | ||
71 | pos = ai->map(ai, state); | ||
72 | if (ai->flags & GPIOEAF_PRINT_RAW) | ||
73 | pr_info("axis %d-%d raw %x, pos %d -> %d\n", | ||
74 | ai->type, ai->code, state, old_pos, pos); | ||
75 | if (report && pos != old_pos) { | ||
76 | if (ai->type == EV_REL) { | ||
77 | change = (ai->decoded_size + pos - old_pos) % | ||
78 | ai->decoded_size; | ||
79 | if (change > ai->decoded_size / 2) | ||
80 | change -= ai->decoded_size; | ||
81 | if (change == ai->decoded_size / 2) { | ||
82 | if (ai->flags & GPIOEAF_PRINT_EVENT) | ||
83 | pr_info("axis %d-%d unknown direction, " | ||
84 | "pos %d -> %d\n", ai->type, | ||
85 | ai->code, old_pos, pos); | ||
86 | change = 0; /* no closest direction */ | ||
87 | } | ||
88 | if (ai->flags & GPIOEAF_PRINT_EVENT) | ||
89 | pr_info("axis %d-%d change %d\n", | ||
90 | ai->type, ai->code, change); | ||
91 | input_report_rel(as->input_devs->dev[ai->dev], | ||
92 | ai->code, change); | ||
93 | } else { | ||
94 | if (ai->flags & GPIOEAF_PRINT_EVENT) | ||
95 | pr_info("axis %d-%d now %d\n", | ||
96 | ai->type, ai->code, pos); | ||
97 | input_event(as->input_devs->dev[ai->dev], | ||
98 | ai->type, ai->code, pos); | ||
99 | } | ||
100 | input_sync(as->input_devs->dev[ai->dev]); | ||
101 | } | ||
102 | as->pos = pos; | ||
103 | } | ||
104 | |||
105 | static irqreturn_t gpio_axis_irq_handler(int irq, void *dev_id) | ||
106 | { | ||
107 | struct gpio_axis_state *as = dev_id; | ||
108 | gpio_event_update_axis(as, 1); | ||
109 | return IRQ_HANDLED; | ||
110 | } | ||
111 | |||
112 | int gpio_event_axis_func(struct gpio_event_input_devs *input_devs, | ||
113 | struct gpio_event_info *info, void **data, int func) | ||
114 | { | ||
115 | int ret; | ||
116 | int i; | ||
117 | int irq; | ||
118 | struct gpio_event_axis_info *ai; | ||
119 | struct gpio_axis_state *as; | ||
120 | |||
121 | ai = container_of(info, struct gpio_event_axis_info, info); | ||
122 | if (func == GPIO_EVENT_FUNC_SUSPEND) { | ||
123 | for (i = 0; i < ai->count; i++) | ||
124 | disable_irq(gpio_to_irq(ai->gpio[i])); | ||
125 | return 0; | ||
126 | } | ||
127 | if (func == GPIO_EVENT_FUNC_RESUME) { | ||
128 | for (i = 0; i < ai->count; i++) | ||
129 | enable_irq(gpio_to_irq(ai->gpio[i])); | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | if (func == GPIO_EVENT_FUNC_INIT) { | ||
134 | *data = as = kmalloc(sizeof(*as), GFP_KERNEL); | ||
135 | if (as == NULL) { | ||
136 | ret = -ENOMEM; | ||
137 | goto err_alloc_axis_state_failed; | ||
138 | } | ||
139 | as->input_devs = input_devs; | ||
140 | as->info = ai; | ||
141 | if (ai->dev >= input_devs->count) { | ||
142 | pr_err("gpio_event_axis: bad device index %d >= %d " | ||
143 | "for %d:%d\n", ai->dev, input_devs->count, | ||
144 | ai->type, ai->code); | ||
145 | ret = -EINVAL; | ||
146 | goto err_bad_device_index; | ||
147 | } | ||
148 | |||
149 | input_set_capability(input_devs->dev[ai->dev], | ||
150 | ai->type, ai->code); | ||
151 | if (ai->type == EV_ABS) { | ||
152 | input_set_abs_params(input_devs->dev[ai->dev], ai->code, | ||
153 | 0, ai->decoded_size - 1, 0, 0); | ||
154 | } | ||
155 | for (i = 0; i < ai->count; i++) { | ||
156 | ret = gpio_request(ai->gpio[i], "gpio_event_axis"); | ||
157 | if (ret < 0) | ||
158 | goto err_request_gpio_failed; | ||
159 | ret = gpio_direction_input(ai->gpio[i]); | ||
160 | if (ret < 0) | ||
161 | goto err_gpio_direction_input_failed; | ||
162 | ret = irq = gpio_to_irq(ai->gpio[i]); | ||
163 | if (ret < 0) | ||
164 | goto err_get_irq_num_failed; | ||
165 | ret = request_irq(irq, gpio_axis_irq_handler, | ||
166 | IRQF_TRIGGER_RISING | | ||
167 | IRQF_TRIGGER_FALLING, | ||
168 | "gpio_event_axis", as); | ||
169 | if (ret < 0) | ||
170 | goto err_request_irq_failed; | ||
171 | } | ||
172 | gpio_event_update_axis(as, 0); | ||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | ret = 0; | ||
177 | as = *data; | ||
178 | for (i = ai->count - 1; i >= 0; i--) { | ||
179 | free_irq(gpio_to_irq(ai->gpio[i]), as); | ||
180 | err_request_irq_failed: | ||
181 | err_get_irq_num_failed: | ||
182 | err_gpio_direction_input_failed: | ||
183 | gpio_free(ai->gpio[i]); | ||
184 | err_request_gpio_failed: | ||
185 | ; | ||
186 | } | ||
187 | err_bad_device_index: | ||
188 | kfree(as); | ||
189 | *data = NULL; | ||
190 | err_alloc_axis_state_failed: | ||
191 | return ret; | ||
192 | } | ||
diff --git a/drivers/input/misc/gpio_event.c b/drivers/input/misc/gpio_event.c new file mode 100644 index 00000000000..a98be67d1ab --- /dev/null +++ b/drivers/input/misc/gpio_event.c | |||
@@ -0,0 +1,260 @@ | |||
1 | /* drivers/input/misc/gpio_event.c | ||
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/earlysuspend.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/input.h> | ||
19 | #include <linux/gpio_event.h> | ||
20 | #include <linux/hrtimer.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/slab.h> | ||
23 | |||
24 | struct gpio_event { | ||
25 | struct gpio_event_input_devs *input_devs; | ||
26 | const struct gpio_event_platform_data *info; | ||
27 | struct early_suspend early_suspend; | ||
28 | void *state[0]; | ||
29 | }; | ||
30 | |||
31 | static int gpio_input_event( | ||
32 | struct input_dev *dev, unsigned int type, unsigned int code, int value) | ||
33 | { | ||
34 | int i; | ||
35 | int devnr; | ||
36 | int ret = 0; | ||
37 | int tmp_ret; | ||
38 | struct gpio_event_info **ii; | ||
39 | struct gpio_event *ip = input_get_drvdata(dev); | ||
40 | |||
41 | for (devnr = 0; devnr < ip->input_devs->count; devnr++) | ||
42 | if (ip->input_devs->dev[devnr] == dev) | ||
43 | break; | ||
44 | if (devnr == ip->input_devs->count) { | ||
45 | pr_err("gpio_input_event: unknown device %p\n", dev); | ||
46 | return -EIO; | ||
47 | } | ||
48 | |||
49 | for (i = 0, ii = ip->info->info; i < ip->info->info_count; i++, ii++) { | ||
50 | if ((*ii)->event) { | ||
51 | tmp_ret = (*ii)->event(ip->input_devs, *ii, | ||
52 | &ip->state[i], | ||
53 | devnr, type, code, value); | ||
54 | if (tmp_ret) | ||
55 | ret = tmp_ret; | ||
56 | } | ||
57 | } | ||
58 | return ret; | ||
59 | } | ||
60 | |||
61 | static int gpio_event_call_all_func(struct gpio_event *ip, int func) | ||
62 | { | ||
63 | int i; | ||
64 | int ret; | ||
65 | struct gpio_event_info **ii; | ||
66 | |||
67 | if (func == GPIO_EVENT_FUNC_INIT || func == GPIO_EVENT_FUNC_RESUME) { | ||
68 | ii = ip->info->info; | ||
69 | for (i = 0; i < ip->info->info_count; i++, ii++) { | ||
70 | if ((*ii)->func == NULL) { | ||
71 | ret = -ENODEV; | ||
72 | pr_err("gpio_event_probe: Incomplete pdata, " | ||
73 | "no function\n"); | ||
74 | goto err_no_func; | ||
75 | } | ||
76 | if (func == GPIO_EVENT_FUNC_RESUME && (*ii)->no_suspend) | ||
77 | continue; | ||
78 | ret = (*ii)->func(ip->input_devs, *ii, &ip->state[i], | ||
79 | func); | ||
80 | if (ret) { | ||
81 | pr_err("gpio_event_probe: function failed\n"); | ||
82 | goto err_func_failed; | ||
83 | } | ||
84 | } | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | ret = 0; | ||
89 | i = ip->info->info_count; | ||
90 | ii = ip->info->info + i; | ||
91 | while (i > 0) { | ||
92 | i--; | ||
93 | ii--; | ||
94 | if ((func & ~1) == GPIO_EVENT_FUNC_SUSPEND && (*ii)->no_suspend) | ||
95 | continue; | ||
96 | (*ii)->func(ip->input_devs, *ii, &ip->state[i], func & ~1); | ||
97 | err_func_failed: | ||
98 | err_no_func: | ||
99 | ; | ||
100 | } | ||
101 | return ret; | ||
102 | } | ||
103 | |||
104 | #ifdef CONFIG_HAS_EARLYSUSPEND | ||
105 | void gpio_event_suspend(struct early_suspend *h) | ||
106 | { | ||
107 | struct gpio_event *ip; | ||
108 | ip = container_of(h, struct gpio_event, early_suspend); | ||
109 | gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_SUSPEND); | ||
110 | ip->info->power(ip->info, 0); | ||
111 | } | ||
112 | |||
113 | void gpio_event_resume(struct early_suspend *h) | ||
114 | { | ||
115 | struct gpio_event *ip; | ||
116 | ip = container_of(h, struct gpio_event, early_suspend); | ||
117 | ip->info->power(ip->info, 1); | ||
118 | gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_RESUME); | ||
119 | } | ||
120 | #endif | ||
121 | |||
122 | static int gpio_event_probe(struct platform_device *pdev) | ||
123 | { | ||
124 | int err; | ||
125 | struct gpio_event *ip; | ||
126 | struct gpio_event_platform_data *event_info; | ||
127 | int dev_count = 1; | ||
128 | int i; | ||
129 | int registered = 0; | ||
130 | |||
131 | event_info = pdev->dev.platform_data; | ||
132 | if (event_info == NULL) { | ||
133 | pr_err("gpio_event_probe: No pdata\n"); | ||
134 | return -ENODEV; | ||
135 | } | ||
136 | if ((!event_info->name && !event_info->names[0]) || | ||
137 | !event_info->info || !event_info->info_count) { | ||
138 | pr_err("gpio_event_probe: Incomplete pdata\n"); | ||
139 | return -ENODEV; | ||
140 | } | ||
141 | if (!event_info->name) | ||
142 | while (event_info->names[dev_count]) | ||
143 | dev_count++; | ||
144 | ip = kzalloc(sizeof(*ip) + | ||
145 | sizeof(ip->state[0]) * event_info->info_count + | ||
146 | sizeof(*ip->input_devs) + | ||
147 | sizeof(ip->input_devs->dev[0]) * dev_count, GFP_KERNEL); | ||
148 | if (ip == NULL) { | ||
149 | err = -ENOMEM; | ||
150 | pr_err("gpio_event_probe: Failed to allocate private data\n"); | ||
151 | goto err_kp_alloc_failed; | ||
152 | } | ||
153 | ip->input_devs = (void*)&ip->state[event_info->info_count]; | ||
154 | platform_set_drvdata(pdev, ip); | ||
155 | |||
156 | for (i = 0; i < dev_count; i++) { | ||
157 | struct input_dev *input_dev = input_allocate_device(); | ||
158 | if (input_dev == NULL) { | ||
159 | err = -ENOMEM; | ||
160 | pr_err("gpio_event_probe: " | ||
161 | "Failed to allocate input device\n"); | ||
162 | goto err_input_dev_alloc_failed; | ||
163 | } | ||
164 | input_set_drvdata(input_dev, ip); | ||
165 | input_dev->name = event_info->name ? | ||
166 | event_info->name : event_info->names[i]; | ||
167 | input_dev->event = gpio_input_event; | ||
168 | ip->input_devs->dev[i] = input_dev; | ||
169 | } | ||
170 | ip->input_devs->count = dev_count; | ||
171 | ip->info = event_info; | ||
172 | if (event_info->power) { | ||
173 | #ifdef CONFIG_HAS_EARLYSUSPEND | ||
174 | ip->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; | ||
175 | ip->early_suspend.suspend = gpio_event_suspend; | ||
176 | ip->early_suspend.resume = gpio_event_resume; | ||
177 | register_early_suspend(&ip->early_suspend); | ||
178 | #endif | ||
179 | ip->info->power(ip->info, 1); | ||
180 | } | ||
181 | |||
182 | err = gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_INIT); | ||
183 | if (err) | ||
184 | goto err_call_all_func_failed; | ||
185 | |||
186 | for (i = 0; i < dev_count; i++) { | ||
187 | err = input_register_device(ip->input_devs->dev[i]); | ||
188 | if (err) { | ||
189 | pr_err("gpio_event_probe: Unable to register %s " | ||
190 | "input device\n", ip->input_devs->dev[i]->name); | ||
191 | goto err_input_register_device_failed; | ||
192 | } | ||
193 | registered++; | ||
194 | } | ||
195 | |||
196 | return 0; | ||
197 | |||
198 | err_input_register_device_failed: | ||
199 | gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT); | ||
200 | err_call_all_func_failed: | ||
201 | if (event_info->power) { | ||
202 | #ifdef CONFIG_HAS_EARLYSUSPEND | ||
203 | unregister_early_suspend(&ip->early_suspend); | ||
204 | #endif | ||
205 | ip->info->power(ip->info, 0); | ||
206 | } | ||
207 | for (i = 0; i < registered; i++) | ||
208 | input_unregister_device(ip->input_devs->dev[i]); | ||
209 | for (i = dev_count - 1; i >= registered; i--) { | ||
210 | input_free_device(ip->input_devs->dev[i]); | ||
211 | err_input_dev_alloc_failed: | ||
212 | ; | ||
213 | } | ||
214 | kfree(ip); | ||
215 | err_kp_alloc_failed: | ||
216 | return err; | ||
217 | } | ||
218 | |||
219 | static int gpio_event_remove(struct platform_device *pdev) | ||
220 | { | ||
221 | struct gpio_event *ip = platform_get_drvdata(pdev); | ||
222 | int i; | ||
223 | |||
224 | gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT); | ||
225 | if (ip->info->power) { | ||
226 | #ifdef CONFIG_HAS_EARLYSUSPEND | ||
227 | unregister_early_suspend(&ip->early_suspend); | ||
228 | #endif | ||
229 | ip->info->power(ip->info, 0); | ||
230 | } | ||
231 | for (i = 0; i < ip->input_devs->count; i++) | ||
232 | input_unregister_device(ip->input_devs->dev[i]); | ||
233 | kfree(ip); | ||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | static struct platform_driver gpio_event_driver = { | ||
238 | .probe = gpio_event_probe, | ||
239 | .remove = gpio_event_remove, | ||
240 | .driver = { | ||
241 | .name = GPIO_EVENT_DEV_NAME, | ||
242 | }, | ||
243 | }; | ||
244 | |||
245 | static int __devinit gpio_event_init(void) | ||
246 | { | ||
247 | return platform_driver_register(&gpio_event_driver); | ||
248 | } | ||
249 | |||
250 | static void __exit gpio_event_exit(void) | ||
251 | { | ||
252 | platform_driver_unregister(&gpio_event_driver); | ||
253 | } | ||
254 | |||
255 | module_init(gpio_event_init); | ||
256 | module_exit(gpio_event_exit); | ||
257 | |||
258 | MODULE_DESCRIPTION("GPIO Event Driver"); | ||
259 | MODULE_LICENSE("GPL"); | ||
260 | |||
diff --git a/drivers/input/misc/gpio_input.c b/drivers/input/misc/gpio_input.c new file mode 100644 index 00000000000..6a0c3151096 --- /dev/null +++ b/drivers/input/misc/gpio_input.c | |||
@@ -0,0 +1,376 @@ | |||
1 | /* drivers/input/misc/gpio_input.c | ||
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/gpio.h> | ||
18 | #include <linux/gpio_event.h> | ||
19 | #include <linux/hrtimer.h> | ||
20 | #include <linux/input.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/wakelock.h> | ||
24 | |||
25 | enum { | ||
26 | DEBOUNCE_UNSTABLE = BIT(0), /* Got irq, while debouncing */ | ||
27 | DEBOUNCE_PRESSED = BIT(1), | ||
28 | DEBOUNCE_NOTPRESSED = BIT(2), | ||
29 | DEBOUNCE_WAIT_IRQ = BIT(3), /* Stable irq state */ | ||
30 | DEBOUNCE_POLL = BIT(4), /* Stable polling state */ | ||
31 | |||
32 | DEBOUNCE_UNKNOWN = | ||
33 | DEBOUNCE_PRESSED | DEBOUNCE_NOTPRESSED, | ||
34 | }; | ||
35 | |||
36 | struct gpio_key_state { | ||
37 | struct gpio_input_state *ds; | ||
38 | uint8_t debounce; | ||
39 | }; | ||
40 | |||
41 | struct gpio_input_state { | ||
42 | struct gpio_event_input_devs *input_devs; | ||
43 | const struct gpio_event_input_info *info; | ||
44 | struct hrtimer timer; | ||
45 | int use_irq; | ||
46 | int debounce_count; | ||
47 | spinlock_t irq_lock; | ||
48 | struct wake_lock wake_lock; | ||
49 | struct gpio_key_state key_state[0]; | ||
50 | }; | ||
51 | |||
52 | static enum hrtimer_restart gpio_event_input_timer_func(struct hrtimer *timer) | ||
53 | { | ||
54 | int i; | ||
55 | int pressed; | ||
56 | struct gpio_input_state *ds = | ||
57 | container_of(timer, struct gpio_input_state, timer); | ||
58 | unsigned gpio_flags = ds->info->flags; | ||
59 | unsigned npolarity; | ||
60 | int nkeys = ds->info->keymap_size; | ||
61 | const struct gpio_event_direct_entry *key_entry; | ||
62 | struct gpio_key_state *key_state; | ||
63 | unsigned long irqflags; | ||
64 | uint8_t debounce; | ||
65 | bool sync_needed; | ||
66 | |||
67 | #if 0 | ||
68 | key_entry = kp->keys_info->keymap; | ||
69 | key_state = kp->key_state; | ||
70 | for (i = 0; i < nkeys; i++, key_entry++, key_state++) | ||
71 | pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio, | ||
72 | gpio_read_detect_status(key_entry->gpio)); | ||
73 | #endif | ||
74 | key_entry = ds->info->keymap; | ||
75 | key_state = ds->key_state; | ||
76 | sync_needed = false; | ||
77 | spin_lock_irqsave(&ds->irq_lock, irqflags); | ||
78 | for (i = 0; i < nkeys; i++, key_entry++, key_state++) { | ||
79 | debounce = key_state->debounce; | ||
80 | if (debounce & DEBOUNCE_WAIT_IRQ) | ||
81 | continue; | ||
82 | if (key_state->debounce & DEBOUNCE_UNSTABLE) { | ||
83 | debounce = key_state->debounce = DEBOUNCE_UNKNOWN; | ||
84 | enable_irq(gpio_to_irq(key_entry->gpio)); | ||
85 | if (gpio_flags & GPIOEDF_PRINT_KEY_UNSTABLE) | ||
86 | pr_info("gpio_keys_scan_keys: key %x-%x, %d " | ||
87 | "(%d) continue debounce\n", | ||
88 | ds->info->type, key_entry->code, | ||
89 | i, key_entry->gpio); | ||
90 | } | ||
91 | npolarity = !(gpio_flags & GPIOEDF_ACTIVE_HIGH); | ||
92 | pressed = gpio_get_value(key_entry->gpio) ^ npolarity; | ||
93 | if (debounce & DEBOUNCE_POLL) { | ||
94 | if (pressed == !(debounce & DEBOUNCE_PRESSED)) { | ||
95 | ds->debounce_count++; | ||
96 | key_state->debounce = DEBOUNCE_UNKNOWN; | ||
97 | if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE) | ||
98 | pr_info("gpio_keys_scan_keys: key %x-" | ||
99 | "%x, %d (%d) start debounce\n", | ||
100 | ds->info->type, key_entry->code, | ||
101 | i, key_entry->gpio); | ||
102 | } | ||
103 | continue; | ||
104 | } | ||
105 | if (pressed && (debounce & DEBOUNCE_NOTPRESSED)) { | ||
106 | if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE) | ||
107 | pr_info("gpio_keys_scan_keys: key %x-%x, %d " | ||
108 | "(%d) debounce pressed 1\n", | ||
109 | ds->info->type, key_entry->code, | ||
110 | i, key_entry->gpio); | ||
111 | key_state->debounce = DEBOUNCE_PRESSED; | ||
112 | continue; | ||
113 | } | ||
114 | if (!pressed && (debounce & DEBOUNCE_PRESSED)) { | ||
115 | if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE) | ||
116 | pr_info("gpio_keys_scan_keys: key %x-%x, %d " | ||
117 | "(%d) debounce pressed 0\n", | ||
118 | ds->info->type, key_entry->code, | ||
119 | i, key_entry->gpio); | ||
120 | key_state->debounce = DEBOUNCE_NOTPRESSED; | ||
121 | continue; | ||
122 | } | ||
123 | /* key is stable */ | ||
124 | ds->debounce_count--; | ||
125 | if (ds->use_irq) | ||
126 | key_state->debounce |= DEBOUNCE_WAIT_IRQ; | ||
127 | else | ||
128 | key_state->debounce |= DEBOUNCE_POLL; | ||
129 | if (gpio_flags & GPIOEDF_PRINT_KEYS) | ||
130 | pr_info("gpio_keys_scan_keys: key %x-%x, %d (%d) " | ||
131 | "changed to %d\n", ds->info->type, | ||
132 | key_entry->code, i, key_entry->gpio, pressed); | ||
133 | input_event(ds->input_devs->dev[key_entry->dev], ds->info->type, | ||
134 | key_entry->code, pressed); | ||
135 | sync_needed = true; | ||
136 | } | ||
137 | if (sync_needed) { | ||
138 | for (i = 0; i < ds->input_devs->count; i++) | ||
139 | input_sync(ds->input_devs->dev[i]); | ||
140 | } | ||
141 | |||
142 | #if 0 | ||
143 | key_entry = kp->keys_info->keymap; | ||
144 | key_state = kp->key_state; | ||
145 | for (i = 0; i < nkeys; i++, key_entry++, key_state++) { | ||
146 | pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio, | ||
147 | gpio_read_detect_status(key_entry->gpio)); | ||
148 | } | ||
149 | #endif | ||
150 | |||
151 | if (ds->debounce_count) | ||
152 | hrtimer_start(timer, ds->info->debounce_time, HRTIMER_MODE_REL); | ||
153 | else if (!ds->use_irq) | ||
154 | hrtimer_start(timer, ds->info->poll_time, HRTIMER_MODE_REL); | ||
155 | else | ||
156 | wake_unlock(&ds->wake_lock); | ||
157 | |||
158 | spin_unlock_irqrestore(&ds->irq_lock, irqflags); | ||
159 | |||
160 | return HRTIMER_NORESTART; | ||
161 | } | ||
162 | |||
163 | static irqreturn_t gpio_event_input_irq_handler(int irq, void *dev_id) | ||
164 | { | ||
165 | struct gpio_key_state *ks = dev_id; | ||
166 | struct gpio_input_state *ds = ks->ds; | ||
167 | int keymap_index = ks - ds->key_state; | ||
168 | const struct gpio_event_direct_entry *key_entry; | ||
169 | unsigned long irqflags; | ||
170 | int pressed; | ||
171 | |||
172 | if (!ds->use_irq) | ||
173 | return IRQ_HANDLED; | ||
174 | |||
175 | key_entry = &ds->info->keymap[keymap_index]; | ||
176 | |||
177 | if (ds->info->debounce_time.tv64) { | ||
178 | spin_lock_irqsave(&ds->irq_lock, irqflags); | ||
179 | if (ks->debounce & DEBOUNCE_WAIT_IRQ) { | ||
180 | ks->debounce = DEBOUNCE_UNKNOWN; | ||
181 | if (ds->debounce_count++ == 0) { | ||
182 | wake_lock(&ds->wake_lock); | ||
183 | hrtimer_start( | ||
184 | &ds->timer, ds->info->debounce_time, | ||
185 | HRTIMER_MODE_REL); | ||
186 | } | ||
187 | if (ds->info->flags & GPIOEDF_PRINT_KEY_DEBOUNCE) | ||
188 | pr_info("gpio_event_input_irq_handler: " | ||
189 | "key %x-%x, %d (%d) start debounce\n", | ||
190 | ds->info->type, key_entry->code, | ||
191 | keymap_index, key_entry->gpio); | ||
192 | } else { | ||
193 | disable_irq_nosync(irq); | ||
194 | ks->debounce = DEBOUNCE_UNSTABLE; | ||
195 | } | ||
196 | spin_unlock_irqrestore(&ds->irq_lock, irqflags); | ||
197 | } else { | ||
198 | pressed = gpio_get_value(key_entry->gpio) ^ | ||
199 | !(ds->info->flags & GPIOEDF_ACTIVE_HIGH); | ||
200 | if (ds->info->flags & GPIOEDF_PRINT_KEYS) | ||
201 | pr_info("gpio_event_input_irq_handler: key %x-%x, %d " | ||
202 | "(%d) changed to %d\n", | ||
203 | ds->info->type, key_entry->code, keymap_index, | ||
204 | key_entry->gpio, pressed); | ||
205 | input_event(ds->input_devs->dev[key_entry->dev], ds->info->type, | ||
206 | key_entry->code, pressed); | ||
207 | input_sync(ds->input_devs->dev[key_entry->dev]); | ||
208 | } | ||
209 | return IRQ_HANDLED; | ||
210 | } | ||
211 | |||
212 | static int gpio_event_input_request_irqs(struct gpio_input_state *ds) | ||
213 | { | ||
214 | int i; | ||
215 | int err; | ||
216 | unsigned int irq; | ||
217 | unsigned long req_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; | ||
218 | |||
219 | for (i = 0; i < ds->info->keymap_size; i++) { | ||
220 | err = irq = gpio_to_irq(ds->info->keymap[i].gpio); | ||
221 | if (err < 0) | ||
222 | goto err_gpio_get_irq_num_failed; | ||
223 | err = request_irq(irq, gpio_event_input_irq_handler, | ||
224 | req_flags, "gpio_keys", &ds->key_state[i]); | ||
225 | if (err) { | ||
226 | pr_err("gpio_event_input_request_irqs: request_irq " | ||
227 | "failed for input %d, irq %d\n", | ||
228 | ds->info->keymap[i].gpio, irq); | ||
229 | goto err_request_irq_failed; | ||
230 | } | ||
231 | if (ds->info->info.no_suspend) { | ||
232 | err = enable_irq_wake(irq); | ||
233 | if (err) { | ||
234 | pr_err("gpio_event_input_request_irqs: " | ||
235 | "enable_irq_wake failed for input %d, " | ||
236 | "irq %d\n", | ||
237 | ds->info->keymap[i].gpio, irq); | ||
238 | goto err_enable_irq_wake_failed; | ||
239 | } | ||
240 | } | ||
241 | } | ||
242 | return 0; | ||
243 | |||
244 | for (i = ds->info->keymap_size - 1; i >= 0; i--) { | ||
245 | irq = gpio_to_irq(ds->info->keymap[i].gpio); | ||
246 | if (ds->info->info.no_suspend) | ||
247 | disable_irq_wake(irq); | ||
248 | err_enable_irq_wake_failed: | ||
249 | free_irq(irq, &ds->key_state[i]); | ||
250 | err_request_irq_failed: | ||
251 | err_gpio_get_irq_num_failed: | ||
252 | ; | ||
253 | } | ||
254 | return err; | ||
255 | } | ||
256 | |||
257 | int gpio_event_input_func(struct gpio_event_input_devs *input_devs, | ||
258 | struct gpio_event_info *info, void **data, int func) | ||
259 | { | ||
260 | int ret; | ||
261 | int i; | ||
262 | unsigned long irqflags; | ||
263 | struct gpio_event_input_info *di; | ||
264 | struct gpio_input_state *ds = *data; | ||
265 | |||
266 | di = container_of(info, struct gpio_event_input_info, info); | ||
267 | |||
268 | if (func == GPIO_EVENT_FUNC_SUSPEND) { | ||
269 | if (ds->use_irq) | ||
270 | for (i = 0; i < di->keymap_size; i++) | ||
271 | disable_irq(gpio_to_irq(di->keymap[i].gpio)); | ||
272 | hrtimer_cancel(&ds->timer); | ||
273 | return 0; | ||
274 | } | ||
275 | if (func == GPIO_EVENT_FUNC_RESUME) { | ||
276 | spin_lock_irqsave(&ds->irq_lock, irqflags); | ||
277 | if (ds->use_irq) | ||
278 | for (i = 0; i < di->keymap_size; i++) | ||
279 | enable_irq(gpio_to_irq(di->keymap[i].gpio)); | ||
280 | hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL); | ||
281 | spin_unlock_irqrestore(&ds->irq_lock, irqflags); | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | if (func == GPIO_EVENT_FUNC_INIT) { | ||
286 | if (ktime_to_ns(di->poll_time) <= 0) | ||
287 | di->poll_time = ktime_set(0, 20 * NSEC_PER_MSEC); | ||
288 | |||
289 | *data = ds = kzalloc(sizeof(*ds) + sizeof(ds->key_state[0]) * | ||
290 | di->keymap_size, GFP_KERNEL); | ||
291 | if (ds == NULL) { | ||
292 | ret = -ENOMEM; | ||
293 | pr_err("gpio_event_input_func: " | ||
294 | "Failed to allocate private data\n"); | ||
295 | goto err_ds_alloc_failed; | ||
296 | } | ||
297 | ds->debounce_count = di->keymap_size; | ||
298 | ds->input_devs = input_devs; | ||
299 | ds->info = di; | ||
300 | wake_lock_init(&ds->wake_lock, WAKE_LOCK_SUSPEND, "gpio_input"); | ||
301 | spin_lock_init(&ds->irq_lock); | ||
302 | |||
303 | for (i = 0; i < di->keymap_size; i++) { | ||
304 | int dev = di->keymap[i].dev; | ||
305 | if (dev >= input_devs->count) { | ||
306 | pr_err("gpio_event_input_func: bad device " | ||
307 | "index %d >= %d for key code %d\n", | ||
308 | dev, input_devs->count, | ||
309 | di->keymap[i].code); | ||
310 | ret = -EINVAL; | ||
311 | goto err_bad_keymap; | ||
312 | } | ||
313 | input_set_capability(input_devs->dev[dev], di->type, | ||
314 | di->keymap[i].code); | ||
315 | ds->key_state[i].ds = ds; | ||
316 | ds->key_state[i].debounce = DEBOUNCE_UNKNOWN; | ||
317 | } | ||
318 | |||
319 | for (i = 0; i < di->keymap_size; i++) { | ||
320 | ret = gpio_request(di->keymap[i].gpio, "gpio_kp_in"); | ||
321 | if (ret) { | ||
322 | pr_err("gpio_event_input_func: gpio_request " | ||
323 | "failed for %d\n", di->keymap[i].gpio); | ||
324 | goto err_gpio_request_failed; | ||
325 | } | ||
326 | ret = gpio_direction_input(di->keymap[i].gpio); | ||
327 | if (ret) { | ||
328 | pr_err("gpio_event_input_func: " | ||
329 | "gpio_direction_input failed for %d\n", | ||
330 | di->keymap[i].gpio); | ||
331 | goto err_gpio_configure_failed; | ||
332 | } | ||
333 | } | ||
334 | |||
335 | ret = gpio_event_input_request_irqs(ds); | ||
336 | |||
337 | spin_lock_irqsave(&ds->irq_lock, irqflags); | ||
338 | ds->use_irq = ret == 0; | ||
339 | |||
340 | pr_info("GPIO Input Driver: Start gpio inputs for %s%s in %s " | ||
341 | "mode\n", input_devs->dev[0]->name, | ||
342 | (input_devs->count > 1) ? "..." : "", | ||
343 | ret == 0 ? "interrupt" : "polling"); | ||
344 | |||
345 | hrtimer_init(&ds->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
346 | ds->timer.function = gpio_event_input_timer_func; | ||
347 | hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL); | ||
348 | spin_unlock_irqrestore(&ds->irq_lock, irqflags); | ||
349 | return 0; | ||
350 | } | ||
351 | |||
352 | ret = 0; | ||
353 | spin_lock_irqsave(&ds->irq_lock, irqflags); | ||
354 | hrtimer_cancel(&ds->timer); | ||
355 | if (ds->use_irq) { | ||
356 | for (i = di->keymap_size - 1; i >= 0; i--) { | ||
357 | int irq = gpio_to_irq(di->keymap[i].gpio); | ||
358 | if (ds->info->info.no_suspend) | ||
359 | disable_irq_wake(irq); | ||
360 | free_irq(irq, &ds->key_state[i]); | ||
361 | } | ||
362 | } | ||
363 | spin_unlock_irqrestore(&ds->irq_lock, irqflags); | ||
364 | |||
365 | for (i = di->keymap_size - 1; i >= 0; i--) { | ||
366 | err_gpio_configure_failed: | ||
367 | gpio_free(di->keymap[i].gpio); | ||
368 | err_gpio_request_failed: | ||
369 | ; | ||
370 | } | ||
371 | err_bad_keymap: | ||
372 | wake_lock_destroy(&ds->wake_lock); | ||
373 | kfree(ds); | ||
374 | err_ds_alloc_failed: | ||
375 | return ret; | ||
376 | } | ||
diff --git a/drivers/input/misc/gpio_matrix.c b/drivers/input/misc/gpio_matrix.c new file mode 100644 index 00000000000..eaa9e89d473 --- /dev/null +++ b/drivers/input/misc/gpio_matrix.c | |||
@@ -0,0 +1,441 @@ | |||
1 | /* drivers/input/misc/gpio_matrix.c | ||
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/gpio.h> | ||
18 | #include <linux/gpio_event.h> | ||
19 | #include <linux/hrtimer.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/wakelock.h> | ||
23 | |||
24 | struct gpio_kp { | ||
25 | struct gpio_event_input_devs *input_devs; | ||
26 | struct gpio_event_matrix_info *keypad_info; | ||
27 | struct hrtimer timer; | ||
28 | struct wake_lock wake_lock; | ||
29 | int current_output; | ||
30 | unsigned int use_irq:1; | ||
31 | unsigned int key_state_changed:1; | ||
32 | unsigned int last_key_state_changed:1; | ||
33 | unsigned int some_keys_pressed:2; | ||
34 | unsigned int disabled_irq:1; | ||
35 | unsigned long keys_pressed[0]; | ||
36 | }; | ||
37 | |||
38 | static void clear_phantom_key(struct gpio_kp *kp, int out, int in) | ||
39 | { | ||
40 | struct gpio_event_matrix_info *mi = kp->keypad_info; | ||
41 | int key_index = out * mi->ninputs + in; | ||
42 | unsigned short keyentry = mi->keymap[key_index]; | ||
43 | unsigned short keycode = keyentry & MATRIX_KEY_MASK; | ||
44 | unsigned short dev = keyentry >> MATRIX_CODE_BITS; | ||
45 | |||
46 | if (!test_bit(keycode, kp->input_devs->dev[dev]->key)) { | ||
47 | if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS) | ||
48 | pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) " | ||
49 | "cleared\n", keycode, out, in, | ||
50 | mi->output_gpios[out], mi->input_gpios[in]); | ||
51 | __clear_bit(key_index, kp->keys_pressed); | ||
52 | } else { | ||
53 | if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS) | ||
54 | pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) " | ||
55 | "not cleared\n", keycode, out, in, | ||
56 | mi->output_gpios[out], mi->input_gpios[in]); | ||
57 | } | ||
58 | } | ||
59 | |||
60 | static int restore_keys_for_input(struct gpio_kp *kp, int out, int in) | ||
61 | { | ||
62 | int rv = 0; | ||
63 | int key_index; | ||
64 | |||
65 | key_index = out * kp->keypad_info->ninputs + in; | ||
66 | while (out < kp->keypad_info->noutputs) { | ||
67 | if (test_bit(key_index, kp->keys_pressed)) { | ||
68 | rv = 1; | ||
69 | clear_phantom_key(kp, out, in); | ||
70 | } | ||
71 | key_index += kp->keypad_info->ninputs; | ||
72 | out++; | ||
73 | } | ||
74 | return rv; | ||
75 | } | ||
76 | |||
77 | static void remove_phantom_keys(struct gpio_kp *kp) | ||
78 | { | ||
79 | int out, in, inp; | ||
80 | int key_index; | ||
81 | |||
82 | if (kp->some_keys_pressed < 3) | ||
83 | return; | ||
84 | |||
85 | for (out = 0; out < kp->keypad_info->noutputs; out++) { | ||
86 | inp = -1; | ||
87 | key_index = out * kp->keypad_info->ninputs; | ||
88 | for (in = 0; in < kp->keypad_info->ninputs; in++, key_index++) { | ||
89 | if (test_bit(key_index, kp->keys_pressed)) { | ||
90 | if (inp == -1) { | ||
91 | inp = in; | ||
92 | continue; | ||
93 | } | ||
94 | if (inp >= 0) { | ||
95 | if (!restore_keys_for_input(kp, out + 1, | ||
96 | inp)) | ||
97 | break; | ||
98 | clear_phantom_key(kp, out, inp); | ||
99 | inp = -2; | ||
100 | } | ||
101 | restore_keys_for_input(kp, out, in); | ||
102 | } | ||
103 | } | ||
104 | } | ||
105 | } | ||
106 | |||
107 | static void report_key(struct gpio_kp *kp, int key_index, int out, int in) | ||
108 | { | ||
109 | struct gpio_event_matrix_info *mi = kp->keypad_info; | ||
110 | int pressed = test_bit(key_index, kp->keys_pressed); | ||
111 | unsigned short keyentry = mi->keymap[key_index]; | ||
112 | unsigned short keycode = keyentry & MATRIX_KEY_MASK; | ||
113 | unsigned short dev = keyentry >> MATRIX_CODE_BITS; | ||
114 | |||
115 | if (pressed != test_bit(keycode, kp->input_devs->dev[dev]->key)) { | ||
116 | if (keycode == KEY_RESERVED) { | ||
117 | if (mi->flags & GPIOKPF_PRINT_UNMAPPED_KEYS) | ||
118 | pr_info("gpiomatrix: unmapped key, %d-%d " | ||
119 | "(%d-%d) changed to %d\n", | ||
120 | out, in, mi->output_gpios[out], | ||
121 | mi->input_gpios[in], pressed); | ||
122 | } else { | ||
123 | if (mi->flags & GPIOKPF_PRINT_MAPPED_KEYS) | ||
124 | pr_info("gpiomatrix: key %x, %d-%d (%d-%d) " | ||
125 | "changed to %d\n", keycode, | ||
126 | out, in, mi->output_gpios[out], | ||
127 | mi->input_gpios[in], pressed); | ||
128 | input_report_key(kp->input_devs->dev[dev], keycode, pressed); | ||
129 | } | ||
130 | } | ||
131 | } | ||
132 | |||
133 | static void report_sync(struct gpio_kp *kp) | ||
134 | { | ||
135 | int i; | ||
136 | |||
137 | for (i = 0; i < kp->input_devs->count; i++) | ||
138 | input_sync(kp->input_devs->dev[i]); | ||
139 | } | ||
140 | |||
141 | static enum hrtimer_restart gpio_keypad_timer_func(struct hrtimer *timer) | ||
142 | { | ||
143 | int out, in; | ||
144 | int key_index; | ||
145 | int gpio; | ||
146 | struct gpio_kp *kp = container_of(timer, struct gpio_kp, timer); | ||
147 | struct gpio_event_matrix_info *mi = kp->keypad_info; | ||
148 | unsigned gpio_keypad_flags = mi->flags; | ||
149 | unsigned polarity = !!(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH); | ||
150 | |||
151 | out = kp->current_output; | ||
152 | if (out == mi->noutputs) { | ||
153 | out = 0; | ||
154 | kp->last_key_state_changed = kp->key_state_changed; | ||
155 | kp->key_state_changed = 0; | ||
156 | kp->some_keys_pressed = 0; | ||
157 | } else { | ||
158 | key_index = out * mi->ninputs; | ||
159 | for (in = 0; in < mi->ninputs; in++, key_index++) { | ||
160 | gpio = mi->input_gpios[in]; | ||
161 | if (gpio_get_value(gpio) ^ !polarity) { | ||
162 | if (kp->some_keys_pressed < 3) | ||
163 | kp->some_keys_pressed++; | ||
164 | kp->key_state_changed |= !__test_and_set_bit( | ||
165 | key_index, kp->keys_pressed); | ||
166 | } else | ||
167 | kp->key_state_changed |= __test_and_clear_bit( | ||
168 | key_index, kp->keys_pressed); | ||
169 | } | ||
170 | gpio = mi->output_gpios[out]; | ||
171 | if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE) | ||
172 | gpio_set_value(gpio, !polarity); | ||
173 | else | ||
174 | gpio_direction_input(gpio); | ||
175 | out++; | ||
176 | } | ||
177 | kp->current_output = out; | ||
178 | if (out < mi->noutputs) { | ||
179 | gpio = mi->output_gpios[out]; | ||
180 | if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE) | ||
181 | gpio_set_value(gpio, polarity); | ||
182 | else | ||
183 | gpio_direction_output(gpio, polarity); | ||
184 | hrtimer_start(timer, mi->settle_time, HRTIMER_MODE_REL); | ||
185 | return HRTIMER_NORESTART; | ||
186 | } | ||
187 | if (gpio_keypad_flags & GPIOKPF_DEBOUNCE) { | ||
188 | if (kp->key_state_changed) { | ||
189 | hrtimer_start(&kp->timer, mi->debounce_delay, | ||
190 | HRTIMER_MODE_REL); | ||
191 | return HRTIMER_NORESTART; | ||
192 | } | ||
193 | kp->key_state_changed = kp->last_key_state_changed; | ||
194 | } | ||
195 | if (kp->key_state_changed) { | ||
196 | if (gpio_keypad_flags & GPIOKPF_REMOVE_SOME_PHANTOM_KEYS) | ||
197 | remove_phantom_keys(kp); | ||
198 | key_index = 0; | ||
199 | for (out = 0; out < mi->noutputs; out++) | ||
200 | for (in = 0; in < mi->ninputs; in++, key_index++) | ||
201 | report_key(kp, key_index, out, in); | ||
202 | report_sync(kp); | ||
203 | } | ||
204 | if (!kp->use_irq || kp->some_keys_pressed) { | ||
205 | hrtimer_start(timer, mi->poll_time, HRTIMER_MODE_REL); | ||
206 | return HRTIMER_NORESTART; | ||
207 | } | ||
208 | |||
209 | /* No keys are pressed, reenable interrupt */ | ||
210 | for (out = 0; out < mi->noutputs; out++) { | ||
211 | if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE) | ||
212 | gpio_set_value(mi->output_gpios[out], polarity); | ||
213 | else | ||
214 | gpio_direction_output(mi->output_gpios[out], polarity); | ||
215 | } | ||
216 | for (in = 0; in < mi->ninputs; in++) | ||
217 | enable_irq(gpio_to_irq(mi->input_gpios[in])); | ||
218 | wake_unlock(&kp->wake_lock); | ||
219 | return HRTIMER_NORESTART; | ||
220 | } | ||
221 | |||
222 | static irqreturn_t gpio_keypad_irq_handler(int irq_in, void *dev_id) | ||
223 | { | ||
224 | int i; | ||
225 | struct gpio_kp *kp = dev_id; | ||
226 | struct gpio_event_matrix_info *mi = kp->keypad_info; | ||
227 | unsigned gpio_keypad_flags = mi->flags; | ||
228 | |||
229 | if (!kp->use_irq) { | ||
230 | /* ignore interrupt while registering the handler */ | ||
231 | kp->disabled_irq = 1; | ||
232 | disable_irq_nosync(irq_in); | ||
233 | return IRQ_HANDLED; | ||
234 | } | ||
235 | |||
236 | for (i = 0; i < mi->ninputs; i++) | ||
237 | disable_irq_nosync(gpio_to_irq(mi->input_gpios[i])); | ||
238 | for (i = 0; i < mi->noutputs; i++) { | ||
239 | if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE) | ||
240 | gpio_set_value(mi->output_gpios[i], | ||
241 | !(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH)); | ||
242 | else | ||
243 | gpio_direction_input(mi->output_gpios[i]); | ||
244 | } | ||
245 | wake_lock(&kp->wake_lock); | ||
246 | hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL); | ||
247 | return IRQ_HANDLED; | ||
248 | } | ||
249 | |||
250 | static int gpio_keypad_request_irqs(struct gpio_kp *kp) | ||
251 | { | ||
252 | int i; | ||
253 | int err; | ||
254 | unsigned int irq; | ||
255 | unsigned long request_flags; | ||
256 | struct gpio_event_matrix_info *mi = kp->keypad_info; | ||
257 | |||
258 | switch (mi->flags & (GPIOKPF_ACTIVE_HIGH|GPIOKPF_LEVEL_TRIGGERED_IRQ)) { | ||
259 | default: | ||
260 | request_flags = IRQF_TRIGGER_FALLING; | ||
261 | break; | ||
262 | case GPIOKPF_ACTIVE_HIGH: | ||
263 | request_flags = IRQF_TRIGGER_RISING; | ||
264 | break; | ||
265 | case GPIOKPF_LEVEL_TRIGGERED_IRQ: | ||
266 | request_flags = IRQF_TRIGGER_LOW; | ||
267 | break; | ||
268 | case GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_ACTIVE_HIGH: | ||
269 | request_flags = IRQF_TRIGGER_HIGH; | ||
270 | break; | ||
271 | } | ||
272 | |||
273 | for (i = 0; i < mi->ninputs; i++) { | ||
274 | err = irq = gpio_to_irq(mi->input_gpios[i]); | ||
275 | if (err < 0) | ||
276 | goto err_gpio_get_irq_num_failed; | ||
277 | err = request_irq(irq, gpio_keypad_irq_handler, request_flags, | ||
278 | "gpio_kp", kp); | ||
279 | if (err) { | ||
280 | pr_err("gpiomatrix: request_irq failed for input %d, " | ||
281 | "irq %d\n", mi->input_gpios[i], irq); | ||
282 | goto err_request_irq_failed; | ||
283 | } | ||
284 | err = enable_irq_wake(irq); | ||
285 | if (err) { | ||
286 | pr_err("gpiomatrix: set_irq_wake failed for input %d, " | ||
287 | "irq %d\n", mi->input_gpios[i], irq); | ||
288 | } | ||
289 | disable_irq(irq); | ||
290 | if (kp->disabled_irq) { | ||
291 | kp->disabled_irq = 0; | ||
292 | enable_irq(irq); | ||
293 | } | ||
294 | } | ||
295 | return 0; | ||
296 | |||
297 | for (i = mi->noutputs - 1; i >= 0; i--) { | ||
298 | free_irq(gpio_to_irq(mi->input_gpios[i]), kp); | ||
299 | err_request_irq_failed: | ||
300 | err_gpio_get_irq_num_failed: | ||
301 | ; | ||
302 | } | ||
303 | return err; | ||
304 | } | ||
305 | |||
306 | int gpio_event_matrix_func(struct gpio_event_input_devs *input_devs, | ||
307 | struct gpio_event_info *info, void **data, int func) | ||
308 | { | ||
309 | int i; | ||
310 | int err; | ||
311 | int key_count; | ||
312 | struct gpio_kp *kp; | ||
313 | struct gpio_event_matrix_info *mi; | ||
314 | |||
315 | mi = container_of(info, struct gpio_event_matrix_info, info); | ||
316 | if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) { | ||
317 | /* TODO: disable scanning */ | ||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | if (func == GPIO_EVENT_FUNC_INIT) { | ||
322 | if (mi->keymap == NULL || | ||
323 | mi->input_gpios == NULL || | ||
324 | mi->output_gpios == NULL) { | ||
325 | err = -ENODEV; | ||
326 | pr_err("gpiomatrix: Incomplete pdata\n"); | ||
327 | goto err_invalid_platform_data; | ||
328 | } | ||
329 | key_count = mi->ninputs * mi->noutputs; | ||
330 | |||
331 | *data = kp = kzalloc(sizeof(*kp) + sizeof(kp->keys_pressed[0]) * | ||
332 | BITS_TO_LONGS(key_count), GFP_KERNEL); | ||
333 | if (kp == NULL) { | ||
334 | err = -ENOMEM; | ||
335 | pr_err("gpiomatrix: Failed to allocate private data\n"); | ||
336 | goto err_kp_alloc_failed; | ||
337 | } | ||
338 | kp->input_devs = input_devs; | ||
339 | kp->keypad_info = mi; | ||
340 | for (i = 0; i < key_count; i++) { | ||
341 | unsigned short keyentry = mi->keymap[i]; | ||
342 | unsigned short keycode = keyentry & MATRIX_KEY_MASK; | ||
343 | unsigned short dev = keyentry >> MATRIX_CODE_BITS; | ||
344 | if (dev >= input_devs->count) { | ||
345 | pr_err("gpiomatrix: bad device index %d >= " | ||
346 | "%d for key code %d\n", | ||
347 | dev, input_devs->count, keycode); | ||
348 | err = -EINVAL; | ||
349 | goto err_bad_keymap; | ||
350 | } | ||
351 | if (keycode && keycode <= KEY_MAX) | ||
352 | input_set_capability(input_devs->dev[dev], | ||
353 | EV_KEY, keycode); | ||
354 | } | ||
355 | |||
356 | for (i = 0; i < mi->noutputs; i++) { | ||
357 | err = gpio_request(mi->output_gpios[i], "gpio_kp_out"); | ||
358 | if (err) { | ||
359 | pr_err("gpiomatrix: gpio_request failed for " | ||
360 | "output %d\n", mi->output_gpios[i]); | ||
361 | goto err_request_output_gpio_failed; | ||
362 | } | ||
363 | if (gpio_cansleep(mi->output_gpios[i])) { | ||
364 | pr_err("gpiomatrix: unsupported output gpio %d," | ||
365 | " can sleep\n", mi->output_gpios[i]); | ||
366 | err = -EINVAL; | ||
367 | goto err_output_gpio_configure_failed; | ||
368 | } | ||
369 | if (mi->flags & GPIOKPF_DRIVE_INACTIVE) | ||
370 | err = gpio_direction_output(mi->output_gpios[i], | ||
371 | !(mi->flags & GPIOKPF_ACTIVE_HIGH)); | ||
372 | else | ||
373 | err = gpio_direction_input(mi->output_gpios[i]); | ||
374 | if (err) { | ||
375 | pr_err("gpiomatrix: gpio_configure failed for " | ||
376 | "output %d\n", mi->output_gpios[i]); | ||
377 | goto err_output_gpio_configure_failed; | ||
378 | } | ||
379 | } | ||
380 | for (i = 0; i < mi->ninputs; i++) { | ||
381 | err = gpio_request(mi->input_gpios[i], "gpio_kp_in"); | ||
382 | if (err) { | ||
383 | pr_err("gpiomatrix: gpio_request failed for " | ||
384 | "input %d\n", mi->input_gpios[i]); | ||
385 | goto err_request_input_gpio_failed; | ||
386 | } | ||
387 | err = gpio_direction_input(mi->input_gpios[i]); | ||
388 | if (err) { | ||
389 | pr_err("gpiomatrix: gpio_direction_input failed" | ||
390 | " for input %d\n", mi->input_gpios[i]); | ||
391 | goto err_gpio_direction_input_failed; | ||
392 | } | ||
393 | } | ||
394 | kp->current_output = mi->noutputs; | ||
395 | kp->key_state_changed = 1; | ||
396 | |||
397 | hrtimer_init(&kp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
398 | kp->timer.function = gpio_keypad_timer_func; | ||
399 | wake_lock_init(&kp->wake_lock, WAKE_LOCK_SUSPEND, "gpio_kp"); | ||
400 | err = gpio_keypad_request_irqs(kp); | ||
401 | kp->use_irq = err == 0; | ||
402 | |||
403 | pr_info("GPIO Matrix Keypad Driver: Start keypad matrix for " | ||
404 | "%s%s in %s mode\n", input_devs->dev[0]->name, | ||
405 | (input_devs->count > 1) ? "..." : "", | ||
406 | kp->use_irq ? "interrupt" : "polling"); | ||
407 | |||
408 | if (kp->use_irq) | ||
409 | wake_lock(&kp->wake_lock); | ||
410 | hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL); | ||
411 | |||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | err = 0; | ||
416 | kp = *data; | ||
417 | |||
418 | if (kp->use_irq) | ||
419 | for (i = mi->noutputs - 1; i >= 0; i--) | ||
420 | free_irq(gpio_to_irq(mi->input_gpios[i]), kp); | ||
421 | |||
422 | hrtimer_cancel(&kp->timer); | ||
423 | wake_lock_destroy(&kp->wake_lock); | ||
424 | for (i = mi->noutputs - 1; i >= 0; i--) { | ||
425 | err_gpio_direction_input_failed: | ||
426 | gpio_free(mi->input_gpios[i]); | ||
427 | err_request_input_gpio_failed: | ||
428 | ; | ||
429 | } | ||
430 | for (i = mi->noutputs - 1; i >= 0; i--) { | ||
431 | err_output_gpio_configure_failed: | ||
432 | gpio_free(mi->output_gpios[i]); | ||
433 | err_request_output_gpio_failed: | ||
434 | ; | ||
435 | } | ||
436 | err_bad_keymap: | ||
437 | kfree(kp); | ||
438 | err_kp_alloc_failed: | ||
439 | err_invalid_platform_data: | ||
440 | return err; | ||
441 | } | ||
diff --git a/drivers/input/misc/gpio_output.c b/drivers/input/misc/gpio_output.c new file mode 100644 index 00000000000..2aac2fad0a1 --- /dev/null +++ b/drivers/input/misc/gpio_output.c | |||
@@ -0,0 +1,97 @@ | |||
1 | /* drivers/input/misc/gpio_output.c | ||
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/gpio.h> | ||
18 | #include <linux/gpio_event.h> | ||
19 | |||
20 | int gpio_event_output_event( | ||
21 | struct gpio_event_input_devs *input_devs, struct gpio_event_info *info, | ||
22 | void **data, unsigned int dev, unsigned int type, | ||
23 | unsigned int code, int value) | ||
24 | { | ||
25 | int i; | ||
26 | struct gpio_event_output_info *oi; | ||
27 | oi = container_of(info, struct gpio_event_output_info, info); | ||
28 | if (type != oi->type) | ||
29 | return 0; | ||
30 | if (!(oi->flags & GPIOEDF_ACTIVE_HIGH)) | ||
31 | value = !value; | ||
32 | for (i = 0; i < oi->keymap_size; i++) | ||
33 | if (dev == oi->keymap[i].dev && code == oi->keymap[i].code) | ||
34 | gpio_set_value(oi->keymap[i].gpio, value); | ||
35 | return 0; | ||
36 | } | ||
37 | |||
38 | int gpio_event_output_func( | ||
39 | struct gpio_event_input_devs *input_devs, struct gpio_event_info *info, | ||
40 | void **data, int func) | ||
41 | { | ||
42 | int ret; | ||
43 | int i; | ||
44 | struct gpio_event_output_info *oi; | ||
45 | oi = container_of(info, struct gpio_event_output_info, info); | ||
46 | |||
47 | if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) | ||
48 | return 0; | ||
49 | |||
50 | if (func == GPIO_EVENT_FUNC_INIT) { | ||
51 | int output_level = !(oi->flags & GPIOEDF_ACTIVE_HIGH); | ||
52 | |||
53 | for (i = 0; i < oi->keymap_size; i++) { | ||
54 | int dev = oi->keymap[i].dev; | ||
55 | if (dev >= input_devs->count) { | ||
56 | pr_err("gpio_event_output_func: bad device " | ||
57 | "index %d >= %d for key code %d\n", | ||
58 | dev, input_devs->count, | ||
59 | oi->keymap[i].code); | ||
60 | ret = -EINVAL; | ||
61 | goto err_bad_keymap; | ||
62 | } | ||
63 | input_set_capability(input_devs->dev[dev], oi->type, | ||
64 | oi->keymap[i].code); | ||
65 | } | ||
66 | |||
67 | for (i = 0; i < oi->keymap_size; i++) { | ||
68 | ret = gpio_request(oi->keymap[i].gpio, | ||
69 | "gpio_event_output"); | ||
70 | if (ret) { | ||
71 | pr_err("gpio_event_output_func: gpio_request " | ||
72 | "failed for %d\n", oi->keymap[i].gpio); | ||
73 | goto err_gpio_request_failed; | ||
74 | } | ||
75 | ret = gpio_direction_output(oi->keymap[i].gpio, | ||
76 | output_level); | ||
77 | if (ret) { | ||
78 | pr_err("gpio_event_output_func: " | ||
79 | "gpio_direction_output failed for %d\n", | ||
80 | oi->keymap[i].gpio); | ||
81 | goto err_gpio_direction_output_failed; | ||
82 | } | ||
83 | } | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | ret = 0; | ||
88 | for (i = oi->keymap_size - 1; i >= 0; i--) { | ||
89 | err_gpio_direction_output_failed: | ||
90 | gpio_free(oi->keymap[i].gpio); | ||
91 | err_gpio_request_failed: | ||
92 | ; | ||
93 | } | ||
94 | err_bad_keymap: | ||
95 | return ret; | ||
96 | } | ||
97 | |||
diff --git a/drivers/input/misc/keychord.c b/drivers/input/misc/keychord.c new file mode 100644 index 00000000000..3ffab6da411 --- /dev/null +++ b/drivers/input/misc/keychord.c | |||
@@ -0,0 +1,387 @@ | |||
1 | /* | ||
2 | * drivers/input/misc/keychord.c | ||
3 | * | ||
4 | * Copyright (C) 2008 Google, Inc. | ||
5 | * Author: Mike Lockwood <lockwood@android.com> | ||
6 | * | ||
7 | * This software is licensed under the terms of the GNU General Public | ||
8 | * License version 2, as published by the Free Software Foundation, and | ||
9 | * may be copied, distributed, and modified under those terms. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #include <linux/poll.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/spinlock.h> | ||
23 | #include <linux/fs.h> | ||
24 | #include <linux/miscdevice.h> | ||
25 | #include <linux/keychord.h> | ||
26 | #include <linux/sched.h> | ||
27 | |||
28 | #define KEYCHORD_NAME "keychord" | ||
29 | #define BUFFER_SIZE 16 | ||
30 | |||
31 | MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>"); | ||
32 | MODULE_DESCRIPTION("Key chord input driver"); | ||
33 | MODULE_SUPPORTED_DEVICE("keychord"); | ||
34 | MODULE_LICENSE("GPL"); | ||
35 | |||
36 | #define NEXT_KEYCHORD(kc) ((struct input_keychord *) \ | ||
37 | ((char *)kc + sizeof(struct input_keychord) + \ | ||
38 | kc->count * sizeof(kc->keycodes[0]))) | ||
39 | |||
40 | struct keychord_device { | ||
41 | struct input_handler input_handler; | ||
42 | int registered; | ||
43 | |||
44 | /* list of keychords to monitor */ | ||
45 | struct input_keychord *keychords; | ||
46 | int keychord_count; | ||
47 | |||
48 | /* bitmask of keys contained in our keychords */ | ||
49 | unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; | ||
50 | /* current state of the keys */ | ||
51 | unsigned long keystate[BITS_TO_LONGS(KEY_CNT)]; | ||
52 | /* number of keys that are currently pressed */ | ||
53 | int key_down; | ||
54 | |||
55 | /* second input_device_id is needed for null termination */ | ||
56 | struct input_device_id device_ids[2]; | ||
57 | |||
58 | spinlock_t lock; | ||
59 | wait_queue_head_t waitq; | ||
60 | unsigned char head; | ||
61 | unsigned char tail; | ||
62 | __u16 buff[BUFFER_SIZE]; | ||
63 | }; | ||
64 | |||
65 | static int check_keychord(struct keychord_device *kdev, | ||
66 | struct input_keychord *keychord) | ||
67 | { | ||
68 | int i; | ||
69 | |||
70 | if (keychord->count != kdev->key_down) | ||
71 | return 0; | ||
72 | |||
73 | for (i = 0; i < keychord->count; i++) { | ||
74 | if (!test_bit(keychord->keycodes[i], kdev->keystate)) | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | /* we have a match */ | ||
79 | return 1; | ||
80 | } | ||
81 | |||
82 | static void keychord_event(struct input_handle *handle, unsigned int type, | ||
83 | unsigned int code, int value) | ||
84 | { | ||
85 | struct keychord_device *kdev = handle->private; | ||
86 | struct input_keychord *keychord; | ||
87 | unsigned long flags; | ||
88 | int i, got_chord = 0; | ||
89 | |||
90 | if (type != EV_KEY || code >= KEY_MAX) | ||
91 | return; | ||
92 | |||
93 | spin_lock_irqsave(&kdev->lock, flags); | ||
94 | /* do nothing if key state did not change */ | ||
95 | if (!test_bit(code, kdev->keystate) == !value) | ||
96 | goto done; | ||
97 | __change_bit(code, kdev->keystate); | ||
98 | if (value) | ||
99 | kdev->key_down++; | ||
100 | else | ||
101 | kdev->key_down--; | ||
102 | |||
103 | /* don't notify on key up */ | ||
104 | if (!value) | ||
105 | goto done; | ||
106 | /* ignore this event if it is not one of the keys we are monitoring */ | ||
107 | if (!test_bit(code, kdev->keybit)) | ||
108 | goto done; | ||
109 | |||
110 | keychord = kdev->keychords; | ||
111 | if (!keychord) | ||
112 | goto done; | ||
113 | |||
114 | /* check to see if the keyboard state matches any keychords */ | ||
115 | for (i = 0; i < kdev->keychord_count; i++) { | ||
116 | if (check_keychord(kdev, keychord)) { | ||
117 | kdev->buff[kdev->head] = keychord->id; | ||
118 | kdev->head = (kdev->head + 1) % BUFFER_SIZE; | ||
119 | got_chord = 1; | ||
120 | break; | ||
121 | } | ||
122 | /* skip to next keychord */ | ||
123 | keychord = NEXT_KEYCHORD(keychord); | ||
124 | } | ||
125 | |||
126 | done: | ||
127 | spin_unlock_irqrestore(&kdev->lock, flags); | ||
128 | |||
129 | if (got_chord) | ||
130 | wake_up_interruptible(&kdev->waitq); | ||
131 | } | ||
132 | |||
133 | static int keychord_connect(struct input_handler *handler, | ||
134 | struct input_dev *dev, | ||
135 | const struct input_device_id *id) | ||
136 | { | ||
137 | int i, ret; | ||
138 | struct input_handle *handle; | ||
139 | struct keychord_device *kdev = | ||
140 | container_of(handler, struct keychord_device, input_handler); | ||
141 | |||
142 | /* | ||
143 | * ignore this input device if it does not contain any keycodes | ||
144 | * that we are monitoring | ||
145 | */ | ||
146 | for (i = 0; i < KEY_MAX; i++) { | ||
147 | if (test_bit(i, kdev->keybit) && test_bit(i, dev->keybit)) | ||
148 | break; | ||
149 | } | ||
150 | if (i == KEY_MAX) | ||
151 | return -ENODEV; | ||
152 | |||
153 | handle = kzalloc(sizeof(*handle), GFP_KERNEL); | ||
154 | if (!handle) | ||
155 | return -ENOMEM; | ||
156 | |||
157 | handle->dev = dev; | ||
158 | handle->handler = handler; | ||
159 | handle->name = KEYCHORD_NAME; | ||
160 | handle->private = kdev; | ||
161 | |||
162 | ret = input_register_handle(handle); | ||
163 | if (ret) | ||
164 | goto err_input_register_handle; | ||
165 | |||
166 | ret = input_open_device(handle); | ||
167 | if (ret) | ||
168 | goto err_input_open_device; | ||
169 | |||
170 | pr_info("keychord: using input dev %s for fevent\n", dev->name); | ||
171 | |||
172 | return 0; | ||
173 | |||
174 | err_input_open_device: | ||
175 | input_unregister_handle(handle); | ||
176 | err_input_register_handle: | ||
177 | kfree(handle); | ||
178 | return ret; | ||
179 | } | ||
180 | |||
181 | static void keychord_disconnect(struct input_handle *handle) | ||
182 | { | ||
183 | input_close_device(handle); | ||
184 | input_unregister_handle(handle); | ||
185 | kfree(handle); | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | * keychord_read is used to read keychord events from the driver | ||
190 | */ | ||
191 | static ssize_t keychord_read(struct file *file, char __user *buffer, | ||
192 | size_t count, loff_t *ppos) | ||
193 | { | ||
194 | struct keychord_device *kdev = file->private_data; | ||
195 | __u16 id; | ||
196 | int retval; | ||
197 | unsigned long flags; | ||
198 | |||
199 | if (count < sizeof(id)) | ||
200 | return -EINVAL; | ||
201 | count = sizeof(id); | ||
202 | |||
203 | if (kdev->head == kdev->tail && (file->f_flags & O_NONBLOCK)) | ||
204 | return -EAGAIN; | ||
205 | |||
206 | retval = wait_event_interruptible(kdev->waitq, | ||
207 | kdev->head != kdev->tail); | ||
208 | if (retval) | ||
209 | return retval; | ||
210 | |||
211 | spin_lock_irqsave(&kdev->lock, flags); | ||
212 | /* pop a keychord ID off the queue */ | ||
213 | id = kdev->buff[kdev->tail]; | ||
214 | kdev->tail = (kdev->tail + 1) % BUFFER_SIZE; | ||
215 | spin_unlock_irqrestore(&kdev->lock, flags); | ||
216 | |||
217 | if (copy_to_user(buffer, &id, count)) | ||
218 | return -EFAULT; | ||
219 | |||
220 | return count; | ||
221 | } | ||
222 | |||
223 | /* | ||
224 | * keychord_write is used to configure the driver | ||
225 | */ | ||
226 | static ssize_t keychord_write(struct file *file, const char __user *buffer, | ||
227 | size_t count, loff_t *ppos) | ||
228 | { | ||
229 | struct keychord_device *kdev = file->private_data; | ||
230 | struct input_keychord *keychords = 0; | ||
231 | struct input_keychord *keychord, *next, *end; | ||
232 | int ret, i, key; | ||
233 | unsigned long flags; | ||
234 | |||
235 | if (count < sizeof(struct input_keychord)) | ||
236 | return -EINVAL; | ||
237 | keychords = kzalloc(count, GFP_KERNEL); | ||
238 | if (!keychords) | ||
239 | return -ENOMEM; | ||
240 | |||
241 | /* read list of keychords from userspace */ | ||
242 | if (copy_from_user(keychords, buffer, count)) { | ||
243 | kfree(keychords); | ||
244 | return -EFAULT; | ||
245 | } | ||
246 | |||
247 | /* unregister handler before changing configuration */ | ||
248 | if (kdev->registered) { | ||
249 | input_unregister_handler(&kdev->input_handler); | ||
250 | kdev->registered = 0; | ||
251 | } | ||
252 | |||
253 | spin_lock_irqsave(&kdev->lock, flags); | ||
254 | /* clear any existing configuration */ | ||
255 | kfree(kdev->keychords); | ||
256 | kdev->keychords = 0; | ||
257 | kdev->keychord_count = 0; | ||
258 | kdev->key_down = 0; | ||
259 | memset(kdev->keybit, 0, sizeof(kdev->keybit)); | ||
260 | memset(kdev->keystate, 0, sizeof(kdev->keystate)); | ||
261 | kdev->head = kdev->tail = 0; | ||
262 | |||
263 | keychord = keychords; | ||
264 | end = (struct input_keychord *)((char *)keychord + count); | ||
265 | |||
266 | while (keychord < end) { | ||
267 | next = NEXT_KEYCHORD(keychord); | ||
268 | if (keychord->count <= 0 || next > end) { | ||
269 | pr_err("keychord: invalid keycode count %d\n", | ||
270 | keychord->count); | ||
271 | goto err_unlock_return; | ||
272 | } | ||
273 | if (keychord->version != KEYCHORD_VERSION) { | ||
274 | pr_err("keychord: unsupported version %d\n", | ||
275 | keychord->version); | ||
276 | goto err_unlock_return; | ||
277 | } | ||
278 | |||
279 | /* keep track of the keys we are monitoring in keybit */ | ||
280 | for (i = 0; i < keychord->count; i++) { | ||
281 | key = keychord->keycodes[i]; | ||
282 | if (key < 0 || key >= KEY_CNT) { | ||
283 | pr_err("keychord: keycode %d out of range\n", | ||
284 | key); | ||
285 | goto err_unlock_return; | ||
286 | } | ||
287 | __set_bit(key, kdev->keybit); | ||
288 | } | ||
289 | |||
290 | kdev->keychord_count++; | ||
291 | keychord = next; | ||
292 | } | ||
293 | |||
294 | kdev->keychords = keychords; | ||
295 | spin_unlock_irqrestore(&kdev->lock, flags); | ||
296 | |||
297 | ret = input_register_handler(&kdev->input_handler); | ||
298 | if (ret) { | ||
299 | kfree(keychords); | ||
300 | kdev->keychords = 0; | ||
301 | return ret; | ||
302 | } | ||
303 | kdev->registered = 1; | ||
304 | |||
305 | return count; | ||
306 | |||
307 | err_unlock_return: | ||
308 | spin_unlock_irqrestore(&kdev->lock, flags); | ||
309 | kfree(keychords); | ||
310 | return -EINVAL; | ||
311 | } | ||
312 | |||
313 | static unsigned int keychord_poll(struct file *file, poll_table *wait) | ||
314 | { | ||
315 | struct keychord_device *kdev = file->private_data; | ||
316 | |||
317 | poll_wait(file, &kdev->waitq, wait); | ||
318 | |||
319 | if (kdev->head != kdev->tail) | ||
320 | return POLLIN | POLLRDNORM; | ||
321 | |||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | static int keychord_open(struct inode *inode, struct file *file) | ||
326 | { | ||
327 | struct keychord_device *kdev; | ||
328 | |||
329 | kdev = kzalloc(sizeof(struct keychord_device), GFP_KERNEL); | ||
330 | if (!kdev) | ||
331 | return -ENOMEM; | ||
332 | |||
333 | spin_lock_init(&kdev->lock); | ||
334 | init_waitqueue_head(&kdev->waitq); | ||
335 | |||
336 | kdev->input_handler.event = keychord_event; | ||
337 | kdev->input_handler.connect = keychord_connect; | ||
338 | kdev->input_handler.disconnect = keychord_disconnect; | ||
339 | kdev->input_handler.name = KEYCHORD_NAME; | ||
340 | kdev->input_handler.id_table = kdev->device_ids; | ||
341 | |||
342 | kdev->device_ids[0].flags = INPUT_DEVICE_ID_MATCH_EVBIT; | ||
343 | __set_bit(EV_KEY, kdev->device_ids[0].evbit); | ||
344 | |||
345 | file->private_data = kdev; | ||
346 | |||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | static int keychord_release(struct inode *inode, struct file *file) | ||
351 | { | ||
352 | struct keychord_device *kdev = file->private_data; | ||
353 | |||
354 | if (kdev->registered) | ||
355 | input_unregister_handler(&kdev->input_handler); | ||
356 | kfree(kdev); | ||
357 | |||
358 | return 0; | ||
359 | } | ||
360 | |||
361 | static const struct file_operations keychord_fops = { | ||
362 | .owner = THIS_MODULE, | ||
363 | .open = keychord_open, | ||
364 | .release = keychord_release, | ||
365 | .read = keychord_read, | ||
366 | .write = keychord_write, | ||
367 | .poll = keychord_poll, | ||
368 | }; | ||
369 | |||
370 | static struct miscdevice keychord_misc = { | ||
371 | .fops = &keychord_fops, | ||
372 | .name = KEYCHORD_NAME, | ||
373 | .minor = MISC_DYNAMIC_MINOR, | ||
374 | }; | ||
375 | |||
376 | static int __init keychord_init(void) | ||
377 | { | ||
378 | return misc_register(&keychord_misc); | ||
379 | } | ||
380 | |||
381 | static void __exit keychord_exit(void) | ||
382 | { | ||
383 | misc_deregister(&keychord_misc); | ||
384 | } | ||
385 | |||
386 | module_init(keychord_init); | ||
387 | module_exit(keychord_exit); | ||
diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c new file mode 100644 index 00000000000..211811ae552 --- /dev/null +++ b/drivers/input/touchscreen/h3600_ts_input.c | |||
@@ -0,0 +1,494 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2001 "Crazy" James Simmons jsimmons@transvirtual.com | ||
3 | * | ||
4 | * Sponsored by Transvirtual Technology. | ||
5 | * | ||
6 | * Derived from the code in h3600_ts.[ch] by Charles Flynn | ||
7 | */ | ||
8 | |||
9 | /* | ||
10 | * Driver for the h3600 Touch Screen and other Atmel controlled devices. | ||
11 | */ | ||
12 | |||
13 | /* | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation; either version 2 of the License, or | ||
17 | * (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
27 | * | ||
28 | * Should you need to contact me, the author, you can do so by | ||
29 | * e-mail - mail your message to <jsimmons@transvirtual.com>. | ||
30 | */ | ||
31 | |||
32 | #include <linux/errno.h> | ||
33 | #include <linux/kernel.h> | ||
34 | #include <linux/module.h> | ||
35 | #include <linux/slab.h> | ||
36 | #include <linux/input.h> | ||
37 | #include <linux/serio.h> | ||
38 | #include <linux/init.h> | ||
39 | #include <linux/delay.h> | ||
40 | |||
41 | /* SA1100 serial defines */ | ||
42 | #include <mach/hardware.h> | ||
43 | #include <mach/irqs.h> | ||
44 | |||
45 | #define DRIVER_DESC "H3600 touchscreen driver" | ||
46 | |||
47 | MODULE_AUTHOR("James Simmons <jsimmons@transvirtual.com>"); | ||
48 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
49 | MODULE_LICENSE("GPL"); | ||
50 | |||
51 | /* | ||
52 | * Definitions & global arrays. | ||
53 | */ | ||
54 | |||
55 | /* The start and end of frame characters SOF and EOF */ | ||
56 | #define CHAR_SOF 0x02 | ||
57 | #define CHAR_EOF 0x03 | ||
58 | #define FRAME_OVERHEAD 3 /* CHAR_SOF,CHAR_EOF,LENGTH = 3 */ | ||
59 | |||
60 | /* | ||
61 | Atmel events and response IDs contained in frame. | ||
62 | Programmer has no control over these numbers. | ||
63 | TODO there are holes - specifically 1,7,0x0a | ||
64 | */ | ||
65 | #define VERSION_ID 0 /* Get Version (request/response) */ | ||
66 | #define KEYBD_ID 2 /* Keyboard (event) */ | ||
67 | #define TOUCHS_ID 3 /* Touch Screen (event)*/ | ||
68 | #define EEPROM_READ_ID 4 /* (request/response) */ | ||
69 | #define EEPROM_WRITE_ID 5 /* (request/response) */ | ||
70 | #define THERMAL_ID 6 /* (request/response) */ | ||
71 | #define NOTIFY_LED_ID 8 /* (request/response) */ | ||
72 | #define BATTERY_ID 9 /* (request/response) */ | ||
73 | #define SPI_READ_ID 0x0b /* ( request/response) */ | ||
74 | #define SPI_WRITE_ID 0x0c /* ( request/response) */ | ||
75 | #define FLITE_ID 0x0d /* backlight ( request/response) */ | ||
76 | #define STX_ID 0xa1 /* extension pack status (req/resp) */ | ||
77 | |||
78 | #define MAX_ID 14 | ||
79 | |||
80 | #define H3600_MAX_LENGTH 16 | ||
81 | #define H3600_KEY 0xf | ||
82 | |||
83 | #define H3600_SCANCODE_RECORD 1 /* 1 -> record button */ | ||
84 | #define H3600_SCANCODE_CALENDAR 2 /* 2 -> calendar */ | ||
85 | #define H3600_SCANCODE_CONTACTS 3 /* 3 -> contact */ | ||
86 | #define H3600_SCANCODE_Q 4 /* 4 -> Q button */ | ||
87 | #define H3600_SCANCODE_START 5 /* 5 -> start menu */ | ||
88 | #define H3600_SCANCODE_UP 6 /* 6 -> up */ | ||
89 | #define H3600_SCANCODE_RIGHT 7 /* 7 -> right */ | ||
90 | #define H3600_SCANCODE_LEFT 8 /* 8 -> left */ | ||
91 | #define H3600_SCANCODE_DOWN 9 /* 9 -> down */ | ||
92 | |||
93 | /* | ||
94 | * Per-touchscreen data. | ||
95 | */ | ||
96 | struct h3600_dev { | ||
97 | struct input_dev *dev; | ||
98 | struct serio *serio; | ||
99 | unsigned char event; /* event ID from packet */ | ||
100 | unsigned char chksum; | ||
101 | unsigned char len; | ||
102 | unsigned char idx; | ||
103 | unsigned char buf[H3600_MAX_LENGTH]; | ||
104 | char phys[32]; | ||
105 | }; | ||
106 | |||
107 | static irqreturn_t action_button_handler(int irq, void *dev_id) | ||
108 | { | ||
109 | int down = (GPLR & GPIO_BITSY_ACTION_BUTTON) ? 0 : 1; | ||
110 | struct input_dev *dev = dev_id; | ||
111 | |||
112 | input_report_key(dev, KEY_ENTER, down); | ||
113 | input_sync(dev); | ||
114 | |||
115 | return IRQ_HANDLED; | ||
116 | } | ||
117 | |||
118 | static irqreturn_t npower_button_handler(int irq, void *dev_id) | ||
119 | { | ||
120 | int down = (GPLR & GPIO_BITSY_NPOWER_BUTTON) ? 0 : 1; | ||
121 | struct input_dev *dev = dev_id; | ||
122 | |||
123 | /* | ||
124 | * This interrupt is only called when we release the key. So we have | ||
125 | * to fake a key press. | ||
126 | */ | ||
127 | input_report_key(dev, KEY_SUSPEND, 1); | ||
128 | input_report_key(dev, KEY_SUSPEND, down); | ||
129 | input_sync(dev); | ||
130 | |||
131 | return IRQ_HANDLED; | ||
132 | } | ||
133 | |||
134 | #ifdef CONFIG_PM | ||
135 | |||
136 | static int flite_brightness = 25; | ||
137 | |||
138 | enum flite_pwr { | ||
139 | FLITE_PWR_OFF = 0, | ||
140 | FLITE_PWR_ON = 1 | ||
141 | }; | ||
142 | |||
143 | /* | ||
144 | * h3600_flite_power: enables or disables power to frontlight, using last bright */ | ||
145 | unsigned int h3600_flite_power(struct input_dev *dev, enum flite_pwr pwr) | ||
146 | { | ||
147 | unsigned char brightness = (pwr == FLITE_PWR_OFF) ? 0 : flite_brightness; | ||
148 | struct h3600_dev *ts = input_get_drvdata(dev); | ||
149 | |||
150 | /* Must be in this order */ | ||
151 | serio_write(ts->serio, 1); | ||
152 | serio_write(ts->serio, pwr); | ||
153 | serio_write(ts->serio, brightness); | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | #endif | ||
159 | |||
160 | /* | ||
161 | * This function translates the native event packets to linux input event | ||
162 | * packets. Some packets coming from serial are not touchscreen related. In | ||
163 | * this case we send them off to be processed elsewhere. | ||
164 | */ | ||
165 | static void h3600ts_process_packet(struct h3600_dev *ts) | ||
166 | { | ||
167 | struct input_dev *dev = ts->dev; | ||
168 | static int touched = 0; | ||
169 | int key, down = 0; | ||
170 | |||
171 | switch (ts->event) { | ||
172 | /* | ||
173 | Buttons - returned as a single byte | ||
174 | 7 6 5 4 3 2 1 0 | ||
175 | S x x x N N N N | ||
176 | |||
177 | S switch state ( 0=pressed 1=released) | ||
178 | x Unused. | ||
179 | NNNN switch number 0-15 | ||
180 | |||
181 | Note: This is true for non interrupt generated key events. | ||
182 | */ | ||
183 | case KEYBD_ID: | ||
184 | down = (ts->buf[0] & 0x80) ? 0 : 1; | ||
185 | |||
186 | switch (ts->buf[0] & 0x7f) { | ||
187 | case H3600_SCANCODE_RECORD: | ||
188 | key = KEY_RECORD; | ||
189 | break; | ||
190 | case H3600_SCANCODE_CALENDAR: | ||
191 | key = KEY_PROG1; | ||
192 | break; | ||
193 | case H3600_SCANCODE_CONTACTS: | ||
194 | key = KEY_PROG2; | ||
195 | break; | ||
196 | case H3600_SCANCODE_Q: | ||
197 | key = KEY_Q; | ||
198 | break; | ||
199 | case H3600_SCANCODE_START: | ||
200 | key = KEY_PROG3; | ||
201 | break; | ||
202 | case H3600_SCANCODE_UP: | ||
203 | key = KEY_UP; | ||
204 | break; | ||
205 | case H3600_SCANCODE_RIGHT: | ||
206 | key = KEY_RIGHT; | ||
207 | break; | ||
208 | case H3600_SCANCODE_LEFT: | ||
209 | key = KEY_LEFT; | ||
210 | break; | ||
211 | case H3600_SCANCODE_DOWN: | ||
212 | key = KEY_DOWN; | ||
213 | break; | ||
214 | default: | ||
215 | key = 0; | ||
216 | } | ||
217 | if (key) | ||
218 | input_report_key(dev, key, down); | ||
219 | break; | ||
220 | /* | ||
221 | * Native touchscreen event data is formatted as shown below:- | ||
222 | * | ||
223 | * +-------+-------+-------+-------+ | ||
224 | * | Xmsb | Xlsb | Ymsb | Ylsb | | ||
225 | * +-------+-------+-------+-------+ | ||
226 | * byte 0 1 2 3 | ||
227 | */ | ||
228 | case TOUCHS_ID: | ||
229 | if (!touched) { | ||
230 | input_report_key(dev, BTN_TOUCH, 1); | ||
231 | touched = 1; | ||
232 | } | ||
233 | |||
234 | if (ts->len) { | ||
235 | unsigned short x, y; | ||
236 | |||
237 | x = ts->buf[0]; x <<= 8; x += ts->buf[1]; | ||
238 | y = ts->buf[2]; y <<= 8; y += ts->buf[3]; | ||
239 | |||
240 | input_report_abs(dev, ABS_X, x); | ||
241 | input_report_abs(dev, ABS_Y, y); | ||
242 | } else { | ||
243 | input_report_key(dev, BTN_TOUCH, 0); | ||
244 | touched = 0; | ||
245 | } | ||
246 | break; | ||
247 | default: | ||
248 | /* Send a non input event elsewhere */ | ||
249 | break; | ||
250 | } | ||
251 | |||
252 | input_sync(dev); | ||
253 | } | ||
254 | |||
255 | /* | ||
256 | * h3600ts_event() handles events from the input module. | ||
257 | */ | ||
258 | static int h3600ts_event(struct input_dev *dev, unsigned int type, | ||
259 | unsigned int code, int value) | ||
260 | { | ||
261 | #if 0 | ||
262 | struct h3600_dev *ts = input_get_drvdata(dev); | ||
263 | |||
264 | switch (type) { | ||
265 | case EV_LED: { | ||
266 | // serio_write(ts->serio, SOME_CMD); | ||
267 | return 0; | ||
268 | } | ||
269 | } | ||
270 | return -1; | ||
271 | #endif | ||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | /* | ||
276 | Frame format | ||
277 | byte 1 2 3 len + 4 | ||
278 | +-------+---------------+---------------+--=------------+ | ||
279 | |SOF |id |len | len bytes | Chksum | | ||
280 | +-------+---------------+---------------+--=------------+ | ||
281 | bit 0 7 8 11 12 15 16 | ||
282 | |||
283 | +-------+---------------+-------+ | ||
284 | |SOF |id |0 |Chksum | - Note Chksum does not include SOF | ||
285 | +-------+---------------+-------+ | ||
286 | bit 0 7 8 11 12 15 16 | ||
287 | |||
288 | */ | ||
289 | |||
290 | static int state; | ||
291 | |||
292 | /* decode States */ | ||
293 | #define STATE_SOF 0 /* start of FRAME */ | ||
294 | #define STATE_ID 1 /* state where we decode the ID & len */ | ||
295 | #define STATE_DATA 2 /* state where we decode data */ | ||
296 | #define STATE_EOF 3 /* state where we decode checksum or EOF */ | ||
297 | |||
298 | static irqreturn_t h3600ts_interrupt(struct serio *serio, unsigned char data, | ||
299 | unsigned int flags) | ||
300 | { | ||
301 | struct h3600_dev *ts = serio_get_drvdata(serio); | ||
302 | |||
303 | /* | ||
304 | * We have a new frame coming in. | ||
305 | */ | ||
306 | switch (state) { | ||
307 | case STATE_SOF: | ||
308 | if (data == CHAR_SOF) | ||
309 | state = STATE_ID; | ||
310 | break; | ||
311 | case STATE_ID: | ||
312 | ts->event = (data & 0xf0) >> 4; | ||
313 | ts->len = (data & 0xf); | ||
314 | ts->idx = 0; | ||
315 | if (ts->event >= MAX_ID) { | ||
316 | state = STATE_SOF; | ||
317 | break; | ||
318 | } | ||
319 | ts->chksum = data; | ||
320 | state = (ts->len > 0) ? STATE_DATA : STATE_EOF; | ||
321 | break; | ||
322 | case STATE_DATA: | ||
323 | ts->chksum += data; | ||
324 | ts->buf[ts->idx]= data; | ||
325 | if (++ts->idx == ts->len) | ||
326 | state = STATE_EOF; | ||
327 | break; | ||
328 | case STATE_EOF: | ||
329 | state = STATE_SOF; | ||
330 | if (data == CHAR_EOF || data == ts->chksum) | ||
331 | h3600ts_process_packet(ts); | ||
332 | break; | ||
333 | default: | ||
334 | printk("Error3\n"); | ||
335 | break; | ||
336 | } | ||
337 | |||
338 | return IRQ_HANDLED; | ||
339 | } | ||
340 | |||
341 | /* | ||
342 | * h3600ts_connect() is the routine that is called when someone adds a | ||
343 | * new serio device that supports H3600 protocol and registers it as | ||
344 | * an input device. | ||
345 | */ | ||
346 | static int h3600ts_connect(struct serio *serio, struct serio_driver *drv) | ||
347 | { | ||
348 | struct h3600_dev *ts; | ||
349 | struct input_dev *input_dev; | ||
350 | int err; | ||
351 | |||
352 | ts = kzalloc(sizeof(struct h3600_dev), GFP_KERNEL); | ||
353 | input_dev = input_allocate_device(); | ||
354 | if (!ts || !input_dev) { | ||
355 | err = -ENOMEM; | ||
356 | goto fail1; | ||
357 | } | ||
358 | |||
359 | ts->serio = serio; | ||
360 | ts->dev = input_dev; | ||
361 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", serio->phys); | ||
362 | |||
363 | input_dev->name = "H3600 TouchScreen"; | ||
364 | input_dev->phys = ts->phys; | ||
365 | input_dev->id.bustype = BUS_RS232; | ||
366 | input_dev->id.vendor = SERIO_H3600; | ||
367 | input_dev->id.product = 0x0666; /* FIXME !!! We can ask the hardware */ | ||
368 | input_dev->id.version = 0x0100; | ||
369 | input_dev->dev.parent = &serio->dev; | ||
370 | |||
371 | input_set_drvdata(input_dev, ts); | ||
372 | |||
373 | input_dev->event = h3600ts_event; | ||
374 | |||
375 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) | | ||
376 | BIT_MASK(EV_LED) | BIT_MASK(EV_PWR); | ||
377 | input_dev->ledbit[0] = BIT_MASK(LED_SLEEP); | ||
378 | input_set_abs_params(input_dev, ABS_X, 60, 985, 0, 0); | ||
379 | input_set_abs_params(input_dev, ABS_Y, 35, 1024, 0, 0); | ||
380 | |||
381 | set_bit(KEY_RECORD, input_dev->keybit); | ||
382 | set_bit(KEY_Q, input_dev->keybit); | ||
383 | set_bit(KEY_PROG1, input_dev->keybit); | ||
384 | set_bit(KEY_PROG2, input_dev->keybit); | ||
385 | set_bit(KEY_PROG3, input_dev->keybit); | ||
386 | set_bit(KEY_UP, input_dev->keybit); | ||
387 | set_bit(KEY_RIGHT, input_dev->keybit); | ||
388 | set_bit(KEY_LEFT, input_dev->keybit); | ||
389 | set_bit(KEY_DOWN, input_dev->keybit); | ||
390 | set_bit(KEY_ENTER, input_dev->keybit); | ||
391 | set_bit(KEY_SUSPEND, input_dev->keybit); | ||
392 | set_bit(BTN_TOUCH, input_dev->keybit); | ||
393 | |||
394 | /* Device specific stuff */ | ||
395 | set_GPIO_IRQ_edge(GPIO_BITSY_ACTION_BUTTON, GPIO_BOTH_EDGES); | ||
396 | set_GPIO_IRQ_edge(GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE); | ||
397 | |||
398 | if (request_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, action_button_handler, | ||
399 | IRQF_SHARED | IRQF_DISABLED, "h3600_action", ts->dev)) { | ||
400 | printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n"); | ||
401 | err = -EBUSY; | ||
402 | goto fail1; | ||
403 | } | ||
404 | |||
405 | if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler, | ||
406 | IRQF_SHARED | IRQF_DISABLED, "h3600_suspend", ts->dev)) { | ||
407 | printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n"); | ||
408 | err = -EBUSY; | ||
409 | goto fail2; | ||
410 | } | ||
411 | |||
412 | serio_set_drvdata(serio, ts); | ||
413 | |||
414 | err = serio_open(serio, drv); | ||
415 | if (err) | ||
416 | goto fail3; | ||
417 | |||
418 | //h3600_flite_control(1, 25); /* default brightness */ | ||
419 | err = input_register_device(ts->dev); | ||
420 | if (err) | ||
421 | goto fail4; | ||
422 | |||
423 | return 0; | ||
424 | |||
425 | fail4: serio_close(serio); | ||
426 | fail3: serio_set_drvdata(serio, NULL); | ||
427 | free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev); | ||
428 | fail2: free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev); | ||
429 | fail1: input_free_device(input_dev); | ||
430 | kfree(ts); | ||
431 | return err; | ||
432 | } | ||
433 | |||
434 | /* | ||
435 | * h3600ts_disconnect() is the opposite of h3600ts_connect() | ||
436 | */ | ||
437 | |||
438 | static void h3600ts_disconnect(struct serio *serio) | ||
439 | { | ||
440 | struct h3600_dev *ts = serio_get_drvdata(serio); | ||
441 | |||
442 | free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev); | ||
443 | free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev); | ||
444 | input_get_device(ts->dev); | ||
445 | input_unregister_device(ts->dev); | ||
446 | serio_close(serio); | ||
447 | serio_set_drvdata(serio, NULL); | ||
448 | input_put_device(ts->dev); | ||
449 | kfree(ts); | ||
450 | } | ||
451 | |||
452 | /* | ||
453 | * The serio driver structure. | ||
454 | */ | ||
455 | |||
456 | static struct serio_device_id h3600ts_serio_ids[] = { | ||
457 | { | ||
458 | .type = SERIO_RS232, | ||
459 | .proto = SERIO_H3600, | ||
460 | .id = SERIO_ANY, | ||
461 | .extra = SERIO_ANY, | ||
462 | }, | ||
463 | { 0 } | ||
464 | }; | ||
465 | |||
466 | MODULE_DEVICE_TABLE(serio, h3600ts_serio_ids); | ||
467 | |||
468 | static struct serio_driver h3600ts_drv = { | ||
469 | .driver = { | ||
470 | .name = "h3600ts", | ||
471 | }, | ||
472 | .description = DRIVER_DESC, | ||
473 | .id_table = h3600ts_serio_ids, | ||
474 | .interrupt = h3600ts_interrupt, | ||
475 | .connect = h3600ts_connect, | ||
476 | .disconnect = h3600ts_disconnect, | ||
477 | }; | ||
478 | |||
479 | /* | ||
480 | * The functions for inserting/removing us as a module. | ||
481 | */ | ||
482 | |||
483 | static int __init h3600ts_init(void) | ||
484 | { | ||
485 | return serio_register_driver(&h3600ts_drv); | ||
486 | } | ||
487 | |||
488 | static void __exit h3600ts_exit(void) | ||
489 | { | ||
490 | serio_unregister_driver(&h3600ts_drv); | ||
491 | } | ||
492 | |||
493 | module_init(h3600ts_init); | ||
494 | module_exit(h3600ts_exit); | ||
diff --git a/drivers/input/touchscreen/panjit_i2c.c b/drivers/input/touchscreen/panjit_i2c.c new file mode 100644 index 00000000000..4fccebc52ea --- /dev/null +++ b/drivers/input/touchscreen/panjit_i2c.c | |||
@@ -0,0 +1,361 @@ | |||
1 | /* | ||
2 | * drivers/input/touchscreen/panjit_i2c.c | ||
3 | * | ||
4 | * Touchscreen class input driver for Panjit touch panel using I2C bus | ||
5 | * | ||
6 | * Copyright (c) 2010, NVIDIA Corporation. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along | ||
19 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
20 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/device.h> | ||
25 | #include <linux/input.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/earlysuspend.h> | ||
28 | #include <linux/i2c.h> | ||
29 | #include <linux/i2c/panjit_ts.h> | ||
30 | #include <linux/interrupt.h> | ||
31 | #include <linux/gpio.h> | ||
32 | #include <linux/slab.h> | ||
33 | |||
34 | #define CSR 0x00 | ||
35 | #define CSR_SCAN_EN (1 << 3) | ||
36 | #define CSR_SLEEP_EN (1 << 7) | ||
37 | #define C_FLAG 0x01 | ||
38 | #define X1_H 0x03 | ||
39 | |||
40 | #define DRIVER_NAME "panjit_touch" | ||
41 | |||
42 | #ifdef CONFIG_HAS_EARLYSUSPEND | ||
43 | static void pj_early_suspend(struct early_suspend *h); | ||
44 | static void pj_late_resume(struct early_suspend *h); | ||
45 | #endif | ||
46 | |||
47 | struct pj_data { | ||
48 | struct input_dev *input_dev; | ||
49 | struct i2c_client *client; | ||
50 | int gpio_reset; | ||
51 | struct early_suspend early_suspend; | ||
52 | }; | ||
53 | |||
54 | struct pj_event { | ||
55 | __be16 coord[2][2]; | ||
56 | __u8 fingers; | ||
57 | __u8 gesture; | ||
58 | }; | ||
59 | |||
60 | union pj_buff { | ||
61 | struct pj_event data; | ||
62 | unsigned char buff[sizeof(struct pj_data)]; | ||
63 | }; | ||
64 | |||
65 | static void pj_reset(struct pj_data *touch) | ||
66 | { | ||
67 | if (touch->gpio_reset < 0) | ||
68 | return; | ||
69 | |||
70 | gpio_set_value(touch->gpio_reset, 1); | ||
71 | msleep(50); | ||
72 | gpio_set_value(touch->gpio_reset, 0); | ||
73 | msleep(50); | ||
74 | } | ||
75 | |||
76 | static irqreturn_t pj_irq(int irq, void *dev_id) | ||
77 | { | ||
78 | struct pj_data *touch = dev_id; | ||
79 | struct i2c_client *client = touch->client; | ||
80 | union pj_buff event; | ||
81 | int ret, i; | ||
82 | |||
83 | ret = i2c_smbus_read_i2c_block_data(client, X1_H, | ||
84 | sizeof(event.buff), event.buff); | ||
85 | if (WARN_ON(ret < 0)) { | ||
86 | dev_err(&client->dev, "error %d reading event data\n", ret); | ||
87 | return IRQ_NONE; | ||
88 | } | ||
89 | ret = i2c_smbus_write_byte_data(client, C_FLAG, 0); | ||
90 | if (WARN_ON(ret < 0)) { | ||
91 | dev_err(&client->dev, "error %d clearing interrupt\n", ret); | ||
92 | return IRQ_NONE; | ||
93 | } | ||
94 | |||
95 | input_report_key(touch->input_dev, BTN_TOUCH, | ||
96 | (event.data.fingers == 1 || event.data.fingers == 2)); | ||
97 | input_report_key(touch->input_dev, BTN_2, (event.data.fingers == 2)); | ||
98 | |||
99 | if (!event.data.fingers || (event.data.fingers > 2)) | ||
100 | goto out; | ||
101 | |||
102 | for (i = 0; i < event.data.fingers; i++) { | ||
103 | input_report_abs(touch->input_dev, ABS_MT_POSITION_X, | ||
104 | __be16_to_cpu(event.data.coord[i][0])); | ||
105 | input_report_abs(touch->input_dev, ABS_MT_POSITION_Y, | ||
106 | __be16_to_cpu(event.data.coord[i][1])); | ||
107 | input_report_abs(touch->input_dev, ABS_MT_TRACKING_ID, i + 1); | ||
108 | input_mt_sync(touch->input_dev); | ||
109 | } | ||
110 | |||
111 | out: | ||
112 | input_sync(touch->input_dev); | ||
113 | return IRQ_HANDLED; | ||
114 | } | ||
115 | |||
116 | static int pj_probe(struct i2c_client *client, | ||
117 | const struct i2c_device_id *id) | ||
118 | { | ||
119 | struct panjit_i2c_ts_platform_data *pdata = client->dev.platform_data; | ||
120 | struct pj_data *touch = NULL; | ||
121 | struct input_dev *input_dev = NULL; | ||
122 | int ret = 0; | ||
123 | |||
124 | touch = kzalloc(sizeof(struct pj_data), GFP_KERNEL); | ||
125 | if (!touch) { | ||
126 | dev_err(&client->dev, "%s: no memory\n", __func__); | ||
127 | return -ENOMEM; | ||
128 | } | ||
129 | |||
130 | touch->gpio_reset = -EINVAL; | ||
131 | |||
132 | if (pdata) { | ||
133 | ret = gpio_request(pdata->gpio_reset, "panjit_reset"); | ||
134 | if (!ret) { | ||
135 | ret = gpio_direction_output(pdata->gpio_reset, 1); | ||
136 | if (ret < 0) | ||
137 | gpio_free(pdata->gpio_reset); | ||
138 | } | ||
139 | |||
140 | if (!ret) | ||
141 | touch->gpio_reset = pdata->gpio_reset; | ||
142 | else | ||
143 | dev_warn(&client->dev, "unable to configure GPIO\n"); | ||
144 | } | ||
145 | |||
146 | input_dev = input_allocate_device(); | ||
147 | if (!input_dev) { | ||
148 | dev_err(&client->dev, "%s: no memory\n", __func__); | ||
149 | kfree(touch); | ||
150 | return -ENOMEM; | ||
151 | } | ||
152 | |||
153 | touch->client = client; | ||
154 | i2c_set_clientdata(client, touch); | ||
155 | |||
156 | pj_reset(touch); | ||
157 | |||
158 | /* clear interrupt */ | ||
159 | ret = i2c_smbus_write_byte_data(touch->client, C_FLAG, 0); | ||
160 | if (ret < 0) { | ||
161 | dev_err(&client->dev, "%s: clear interrupt failed\n", | ||
162 | __func__); | ||
163 | goto fail_i2c_or_register; | ||
164 | } | ||
165 | |||
166 | /* enable scanning */ | ||
167 | ret = i2c_smbus_write_byte_data(touch->client, CSR, CSR_SCAN_EN); | ||
168 | if (ret < 0) { | ||
169 | dev_err(&client->dev, "%s: enable interrupt failed\n", | ||
170 | __func__); | ||
171 | goto fail_i2c_or_register; | ||
172 | } | ||
173 | |||
174 | touch->input_dev = input_dev; | ||
175 | touch->input_dev->name = DRIVER_NAME; | ||
176 | |||
177 | set_bit(EV_SYN, touch->input_dev->evbit); | ||
178 | set_bit(EV_KEY, touch->input_dev->evbit); | ||
179 | set_bit(EV_ABS, touch->input_dev->evbit); | ||
180 | set_bit(BTN_TOUCH, touch->input_dev->keybit); | ||
181 | set_bit(BTN_2, touch->input_dev->keybit); | ||
182 | |||
183 | /* expose multi-touch capabilities */ | ||
184 | set_bit(ABS_MT_POSITION_X, touch->input_dev->keybit); | ||
185 | set_bit(ABS_MT_POSITION_Y, touch->input_dev->keybit); | ||
186 | set_bit(ABS_X, touch->input_dev->keybit); | ||
187 | set_bit(ABS_Y, touch->input_dev->keybit); | ||
188 | |||
189 | /* all coordinates are reported in 0..4095 */ | ||
190 | input_set_abs_params(touch->input_dev, ABS_X, 0, 4095, 0, 0); | ||
191 | input_set_abs_params(touch->input_dev, ABS_Y, 0, 4095, 0, 0); | ||
192 | input_set_abs_params(touch->input_dev, ABS_HAT0X, 0, 4095, 0, 0); | ||
193 | input_set_abs_params(touch->input_dev, ABS_HAT0Y, 0, 4095, 0, 0); | ||
194 | input_set_abs_params(touch->input_dev, ABS_HAT1X, 0, 4095, 0, 0); | ||
195 | input_set_abs_params(touch->input_dev, ABS_HAT1Y, 0, 4095, 0, 0); | ||
196 | |||
197 | input_set_abs_params(touch->input_dev, ABS_MT_POSITION_X, 0, 4095, 0, 0); | ||
198 | input_set_abs_params(touch->input_dev, ABS_MT_POSITION_Y, 0, 4095, 0, 0); | ||
199 | input_set_abs_params(touch->input_dev, ABS_MT_TRACKING_ID, 0, 2, 1, 0); | ||
200 | |||
201 | ret = input_register_device(touch->input_dev); | ||
202 | if (ret) { | ||
203 | dev_err(&client->dev, "%s: input_register_device failed\n", | ||
204 | __func__); | ||
205 | goto fail_i2c_or_register; | ||
206 | } | ||
207 | |||
208 | /* get the irq */ | ||
209 | ret = request_threaded_irq(touch->client->irq, NULL, pj_irq, | ||
210 | IRQF_ONESHOT | IRQF_TRIGGER_LOW, | ||
211 | DRIVER_NAME, touch); | ||
212 | if (ret) { | ||
213 | dev_err(&client->dev, "%s: request_irq(%d) failed\n", | ||
214 | __func__, touch->client->irq); | ||
215 | goto fail_irq; | ||
216 | } | ||
217 | |||
218 | #ifdef CONFIG_HAS_EARLYSUSPEND | ||
219 | touch->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; | ||
220 | touch->early_suspend.suspend = pj_early_suspend; | ||
221 | touch->early_suspend.resume = pj_late_resume; | ||
222 | register_early_suspend(&touch->early_suspend); | ||
223 | #endif | ||
224 | dev_info(&client->dev, "%s: initialized\n", __func__); | ||
225 | return 0; | ||
226 | |||
227 | fail_irq: | ||
228 | input_unregister_device(touch->input_dev); | ||
229 | |||
230 | fail_i2c_or_register: | ||
231 | if (touch->gpio_reset >= 0) | ||
232 | gpio_free(touch->gpio_reset); | ||
233 | |||
234 | input_free_device(input_dev); | ||
235 | kfree(touch); | ||
236 | return ret; | ||
237 | } | ||
238 | |||
239 | static int pj_suspend(struct i2c_client *client, pm_message_t state) | ||
240 | { | ||
241 | struct pj_data *touch = i2c_get_clientdata(client); | ||
242 | int ret; | ||
243 | |||
244 | if (WARN_ON(!touch)) | ||
245 | return -EINVAL; | ||
246 | |||
247 | disable_irq(client->irq); | ||
248 | |||
249 | /* disable scanning and enable deep sleep */ | ||
250 | ret = i2c_smbus_write_byte_data(client, CSR, CSR_SLEEP_EN); | ||
251 | if (ret < 0) { | ||
252 | dev_err(&client->dev, "%s: sleep enable fail\n", __func__); | ||
253 | return ret; | ||
254 | } | ||
255 | |||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | static int pj_resume(struct i2c_client *client) | ||
260 | { | ||
261 | struct pj_data *touch = i2c_get_clientdata(client); | ||
262 | int ret = 0; | ||
263 | |||
264 | if (WARN_ON(!touch)) | ||
265 | return -EINVAL; | ||
266 | |||
267 | pj_reset(touch); | ||
268 | |||
269 | /* enable scanning and disable deep sleep */ | ||
270 | ret = i2c_smbus_write_byte_data(client, C_FLAG, 0); | ||
271 | if (ret >= 0) | ||
272 | ret = i2c_smbus_write_byte_data(client, CSR, CSR_SCAN_EN); | ||
273 | if (ret < 0) { | ||
274 | dev_err(&client->dev, "%s: scan enable fail\n", __func__); | ||
275 | return ret; | ||
276 | } | ||
277 | |||
278 | enable_irq(client->irq); | ||
279 | |||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | #ifdef CONFIG_HAS_EARLYSUSPEND | ||
284 | static void pj_early_suspend(struct early_suspend *es) | ||
285 | { | ||
286 | struct pj_data *touch; | ||
287 | touch = container_of(es, struct pj_data, early_suspend); | ||
288 | |||
289 | if (pj_suspend(touch->client, PMSG_SUSPEND) != 0) | ||
290 | dev_err(&touch->client->dev, "%s: failed\n", __func__); | ||
291 | } | ||
292 | |||
293 | static void pj_late_resume(struct early_suspend *es) | ||
294 | { | ||
295 | struct pj_data *touch; | ||
296 | touch = container_of(es, struct pj_data, early_suspend); | ||
297 | |||
298 | if (pj_resume(touch->client) != 0) | ||
299 | dev_err(&touch->client->dev, "%s: failed\n", __func__); | ||
300 | } | ||
301 | #endif | ||
302 | |||
303 | static int pj_remove(struct i2c_client *client) | ||
304 | { | ||
305 | struct pj_data *touch = i2c_get_clientdata(client); | ||
306 | |||
307 | if (!touch) | ||
308 | return -EINVAL; | ||
309 | |||
310 | #ifdef CONFIG_HAS_EARLYSUSPEND | ||
311 | unregister_early_suspend(&touch->early_suspend); | ||
312 | #endif | ||
313 | free_irq(touch->client->irq, touch); | ||
314 | if (touch->gpio_reset >= 0) | ||
315 | gpio_free(touch->gpio_reset); | ||
316 | input_unregister_device(touch->input_dev); | ||
317 | input_free_device(touch->input_dev); | ||
318 | kfree(touch); | ||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | static const struct i2c_device_id panjit_ts_id[] = { | ||
323 | { DRIVER_NAME, 0 }, | ||
324 | { } | ||
325 | }; | ||
326 | |||
327 | static struct i2c_driver panjit_driver = { | ||
328 | .probe = pj_probe, | ||
329 | .remove = pj_remove, | ||
330 | #ifndef CONFIG_HAS_EARLYSUSPEND | ||
331 | .suspend = pj_suspend, | ||
332 | .resume = pj_resume, | ||
333 | #endif | ||
334 | .id_table = panjit_ts_id, | ||
335 | .driver = { | ||
336 | .name = DRIVER_NAME, | ||
337 | }, | ||
338 | }; | ||
339 | |||
340 | static int __devinit panjit_init(void) | ||
341 | { | ||
342 | int e; | ||
343 | |||
344 | e = i2c_add_driver(&panjit_driver); | ||
345 | if (e != 0) { | ||
346 | pr_err("%s: failed to register with I2C bus with " | ||
347 | "error: 0x%x\n", __func__, e); | ||
348 | } | ||
349 | return e; | ||
350 | } | ||
351 | |||
352 | static void __exit panjit_exit(void) | ||
353 | { | ||
354 | i2c_del_driver(&panjit_driver); | ||
355 | } | ||
356 | |||
357 | module_init(panjit_init); | ||
358 | module_exit(panjit_exit); | ||
359 | |||
360 | MODULE_LICENSE("GPL"); | ||
361 | MODULE_DESCRIPTION("Panjit I2C touch driver"); | ||
diff --git a/drivers/input/touchscreen/rm31080a_ts.c b/drivers/input/touchscreen/rm31080a_ts.c new file mode 100644 index 00000000000..35e85a25486 --- /dev/null +++ b/drivers/input/touchscreen/rm31080a_ts.c | |||
@@ -0,0 +1,1370 @@ | |||
1 | /* | ||
2 | |||
3 | * Raydium RM31080(T007) touchscreen (SPI bus) - Android version | ||
4 | * | ||
5 | * Copyright (C) 2011-2012 Raydium Inc. | ||
6 | * | ||
7 | * Licensed under the GPL-2 or later. | ||
8 | * | ||
9 | * Version : 0.04 | ||
10 | */ | ||
11 | |||
12 | //============================================================================= | ||
13 | //INCLUDED FILES | ||
14 | //============================================================================= | ||
15 | #include <linux/input.h> // BUS_SPI | ||
16 | #include <linux/spi/spi.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/irq.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/gpio.h> | ||
24 | #include <linux/sched.h> // wake_up_process() | ||
25 | #include <linux/kthread.h> // kthread_create()、kthread_run() | ||
26 | #include <asm/uaccess.h> // copy_to_user(), | ||
27 | #include <linux/miscdevice.h> | ||
28 | #include <asm/siginfo.h> // siginfo | ||
29 | #include <linux/rcupdate.h> // rcu_read_lock | ||
30 | #include <linux/sched.h> // find_task_by_pid_type | ||
31 | #include <linux/syscalls.h> // sys_clock_gettime() | ||
32 | #if defined(CONFIG_HAS_EARLYSUSPEND) | ||
33 | #include <linux/earlysuspend.h> | ||
34 | #endif | ||
35 | |||
36 | #include <linux/spi/rm31080a_ts.h> | ||
37 | //============================================================================= | ||
38 | //DEFINITIONS | ||
39 | //============================================================================= | ||
40 | #define ENABLE_WORK_QUEUE | ||
41 | #define ENABLE_REPORT_TO_UART | ||
42 | #define ENABLE_RM31080_DEEP_SLEEP | ||
43 | #define ENABLE_AUTO_SCAN | ||
44 | //#define ENABLE_AUTO_FREQ | ||
45 | //#define ENABLE_SPEED_TEST_FUNCTION | ||
46 | //#define ENABLE_TEST_AVERAGE | ||
47 | //#define ENABLE_CALC_QUEUE_COUNT | ||
48 | |||
49 | #define MAX_SPI_FREQ_HZ 50000000 | ||
50 | #define TS_PEN_UP_TIMEOUT msecs_to_jiffies(50) | ||
51 | |||
52 | #ifdef ENABLE_RAW_DATA_QUEUE | ||
53 | #define QUEUE_COUNT 128 | ||
54 | #define RAW_DATA_LENGTH 2048 | ||
55 | |||
56 | #define RM_SCAN_MODE_MANUAL 0x00 | ||
57 | #define RM_SCAN_MODE_PREPARE_AUTO 0x01 | ||
58 | #define RM_SCAN_MODE_AUTO_SCAN 0x02 | ||
59 | |||
60 | #define RM_NEED_NONE 0x00 | ||
61 | #define RM_NEED_TO_SEND_SCAN 0x01 | ||
62 | #define RM_NEED_TO_READ_RAW_DATA 0x02 | ||
63 | #define RM_NEED_TO_SEND_SIGNAL 0x03 | ||
64 | #endif | ||
65 | |||
66 | #ifdef ENABLE_WORK_QUEUE | ||
67 | #include <linux/workqueue.h> | ||
68 | #endif | ||
69 | |||
70 | //============================================================================= | ||
71 | //STRUCTURE DECLARATION | ||
72 | //============================================================================= | ||
73 | struct rm31080a_ts_para { | ||
74 | unsigned long ulHalPID; | ||
75 | bool bInitFinish; | ||
76 | bool bCalcFinish; | ||
77 | bool bEnableScriber; | ||
78 | bool bEnableAutoScan; | ||
79 | bool bIsSuspended; | ||
80 | struct mutex mutex; | ||
81 | #ifdef ENABLE_WORK_QUEUE | ||
82 | struct workqueue_struct *rm_workqueue; | ||
83 | struct work_struct rm_work; | ||
84 | bool bIsWorkQueueExecuting; | ||
85 | #endif | ||
86 | #ifdef ENABLE_RAW_DATA_QUEUE | ||
87 | u8 u8ScanModeState; | ||
88 | #endif | ||
89 | }; | ||
90 | |||
91 | struct rm31080_ts { | ||
92 | const struct rm31080_bus_ops *bops; | ||
93 | struct device *dev; | ||
94 | struct input_dev *input; | ||
95 | unsigned int irq; | ||
96 | bool disabled; | ||
97 | bool suspended; | ||
98 | char phys[32]; | ||
99 | struct mutex access_mutex; | ||
100 | #if defined(CONFIG_HAS_EARLYSUSPEND) | ||
101 | struct early_suspend early_suspend; | ||
102 | #endif | ||
103 | }; | ||
104 | |||
105 | struct rm31080_bus_ops { | ||
106 | u16 bustype; | ||
107 | int (*read) (struct device * dev, u8 reg); | ||
108 | int (*multi_read) (struct device * dev, u8 first_reg, u8 count, | ||
109 | u16 * buf); | ||
110 | int (*write) (struct device * dev, u8 reg, u16 val); | ||
111 | }; | ||
112 | |||
113 | #ifdef ENABLE_RAW_DATA_QUEUE | ||
114 | struct rm31080_queue_info { | ||
115 | u8(*pQueue)[RAW_DATA_LENGTH]; | ||
116 | u16 u16Front; | ||
117 | u16 u16Rear; | ||
118 | }; | ||
119 | #endif | ||
120 | |||
121 | //============================================================================= | ||
122 | //GLOBAL VARIABLES DECLARATION | ||
123 | //============================================================================= | ||
124 | struct input_dev *g_input_dev; | ||
125 | struct spi_device *g_spi; | ||
126 | struct rm31080a_ts_para g_stTs; | ||
127 | |||
128 | #ifdef ENABLE_RAW_DATA_QUEUE | ||
129 | struct rm31080_queue_info g_stQ; | ||
130 | #endif | ||
131 | |||
132 | //============================================================================= | ||
133 | //FUNCTION DECLARATION | ||
134 | //============================================================================= | ||
135 | #if defined(CONFIG_HAS_EARLYSUSPEND) | ||
136 | static void rm31080_early_suspend(struct early_suspend *es); | ||
137 | static void rm31080_early_resume(struct early_suspend *es); | ||
138 | #endif | ||
139 | //============================================================================= | ||
140 | // Description: | ||
141 | // Debug function: test speed. | ||
142 | // Input: | ||
143 | // N/A | ||
144 | // Output: | ||
145 | // 1:succeed | ||
146 | // 0:failed | ||
147 | //============================================================================= | ||
148 | #ifdef ENABLE_SPEED_TEST_FUNCTION | ||
149 | void my_calc_time(int iStart) | ||
150 | { | ||
151 | static volatile unsigned int u32Max = UINT_MAX; | ||
152 | |||
153 | static long iTimebuffer[1000]; | ||
154 | static unsigned long long t1, t2; | ||
155 | unsigned long nanosec_rem; | ||
156 | static int iIndex = 0; | ||
157 | |||
158 | if (iStart) { | ||
159 | t1 = cpu_clock(u32Max); | ||
160 | return; | ||
161 | } else | ||
162 | t2 = cpu_clock(u32Max); | ||
163 | |||
164 | t2 = t2 - t1; | ||
165 | |||
166 | nanosec_rem = do_div(t2, 1000000000); | ||
167 | |||
168 | if (t2) { //more than 1 Second | ||
169 | iTimebuffer[iIndex] = 999999; | ||
170 | } else { | ||
171 | iTimebuffer[iIndex] = nanosec_rem / 1000; //micro second | ||
172 | } | ||
173 | |||
174 | iIndex++; | ||
175 | if (iIndex == 1000) { | ||
176 | for (iIndex = 0; iIndex < 1000; iIndex++) { | ||
177 | printk(" %04d,%06d\n", iIndex, | ||
178 | (u32) iTimebuffer[iIndex]); | ||
179 | } | ||
180 | iIndex = 0; | ||
181 | } | ||
182 | |||
183 | } | ||
184 | #endif //ENABLE_SPEED_TEST_FUNCTION | ||
185 | //============================================================================= | ||
186 | // Description: | ||
187 | // RM31080 spi interface. | ||
188 | // Input: | ||
189 | // N/A | ||
190 | // Output: | ||
191 | // 1:succeed | ||
192 | // 0:failed | ||
193 | //============================================================================= | ||
194 | int rm31080_spi_read(u8 u8addr, u8 * rxbuf, size_t len) | ||
195 | { | ||
196 | static DEFINE_MUTEX(lock); | ||
197 | |||
198 | int status; | ||
199 | struct spi_message message; | ||
200 | struct spi_transfer x[2]; | ||
201 | |||
202 | if (!mutex_trylock(&lock)) { | ||
203 | //printk("Raydium TS: rm31080_spi_read trylock fail\n"); | ||
204 | return -EINVAL; | ||
205 | } | ||
206 | |||
207 | spi_message_init(&message); | ||
208 | memset(x, 0, sizeof x); | ||
209 | |||
210 | u8addr |= 0x80; | ||
211 | x[0].len = 1; | ||
212 | x[0].tx_buf = &u8addr; | ||
213 | spi_message_add_tail(&x[0], &message); | ||
214 | |||
215 | x[1].len = len; | ||
216 | x[1].rx_buf = rxbuf; | ||
217 | spi_message_add_tail(&x[1], &message); | ||
218 | |||
219 | status = spi_sync(g_spi, &message); | ||
220 | |||
221 | mutex_unlock(&lock); | ||
222 | return status; // 0 = succeed | ||
223 | } | ||
224 | |||
225 | int rm31080_spi_write(u8 * txbuf, size_t len) | ||
226 | { | ||
227 | return spi_write(g_spi, txbuf, len); | ||
228 | } | ||
229 | |||
230 | static int rm31080_spi_byte_read(u8 u8Addr, u8 * pu8Value) | ||
231 | { | ||
232 | int iErrorCode; | ||
233 | iErrorCode = rm31080_spi_read(u8Addr, pu8Value, 1); | ||
234 | if (iErrorCode != 0) { | ||
235 | return 0; //fail | ||
236 | } | ||
237 | return 1; | ||
238 | } | ||
239 | |||
240 | static int rm31080_spi_byte_write(u8 u8Addr, u8 u8Value) | ||
241 | { | ||
242 | int iErrorCode; | ||
243 | u8 buf[2]; | ||
244 | buf[0] = u8Addr; | ||
245 | buf[1] = u8Value; | ||
246 | |||
247 | iErrorCode = rm31080_spi_write(buf, 2); | ||
248 | |||
249 | if (iErrorCode != 0) { | ||
250 | //printk("rm31080_spi_write_byte failed:Reg=%x", u8Addr); | ||
251 | return 0; //fail | ||
252 | } | ||
253 | return 1; | ||
254 | } | ||
255 | |||
256 | //============================================================================= | ||
257 | // Description: | ||
258 | // RM31080 control functions. | ||
259 | // Input: | ||
260 | // N/A | ||
261 | // Output: | ||
262 | // 1:succeed | ||
263 | // 0:failed | ||
264 | //============================================================================= | ||
265 | #ifdef ENABLE_RAW_DATA_QUEUE | ||
266 | |||
267 | #define RM31080_REG_01 0x01 | ||
268 | #define RM31080_REG_02 0x02 | ||
269 | #define RM31080_REG_09 0x09 | ||
270 | #define RM31080_REG_0E 0x0E | ||
271 | #define RM31080_REG_10 0x10 | ||
272 | #define RM31080_REG_11 0x11 | ||
273 | #define RM31080_REG_1F 0x1F | ||
274 | #define RM31080_REG_40 0x40 | ||
275 | #define RM31080_REG_41 0x41 | ||
276 | #define RM31080_REG_80 0x80 | ||
277 | #define RM31080_REG_F2 0xF2 | ||
278 | |||
279 | #define RM31080_RAW_DATA_LENGTH 1530 | ||
280 | static int rm31080_ctrl_clear_int(void) | ||
281 | { | ||
282 | u8 u8Flag; | ||
283 | return rm31080_spi_byte_read(RM31080_REG_F2, &u8Flag); | ||
284 | } | ||
285 | |||
286 | #ifdef ENABLE_AUTO_SCAN | ||
287 | void rm31080_ctrl_enter_auto_mode(void) | ||
288 | { | ||
289 | //Enable auto scan | ||
290 | rm31080_spi_byte_write(RM31080_REG_09, 0x10 | 0x40); | ||
291 | } | ||
292 | |||
293 | void rm31080_ctrl_leave_auto_mode(void) | ||
294 | { | ||
295 | //Disable auto scan | ||
296 | rm31080_spi_byte_write(RM31080_REG_09, 0x00); | ||
297 | } | ||
298 | #endif //ENABLE_AUTO_SCAN | ||
299 | |||
300 | #ifdef ENABLE_RM31080_DEEP_SLEEP | ||
301 | static int rm31080_ctrl_suspend(void) | ||
302 | { | ||
303 | //Flow designed by Roger 20110930 | ||
304 | //rm31080_ts_send_signal(g_stTs.ulHalPID,RM_SIGNAL_SUSPEND); | ||
305 | g_stTs.bInitFinish = 0; | ||
306 | msleep(8); | ||
307 | rm31080_ctrl_clear_int(); | ||
308 | //disable auto scan | ||
309 | rm31080_spi_byte_write(RM31080_REG_09, 0x00); | ||
310 | rm31080_spi_byte_write(RM31080_REG_10, 0x14); | ||
311 | rm31080_spi_byte_write(RM31080_REG_11, 0x17); | ||
312 | msleep(15); | ||
313 | rm31080_spi_byte_write(RM31080_REG_11, 0x06); | ||
314 | return 1; | ||
315 | } | ||
316 | #endif | ||
317 | |||
318 | static int rm31080_ctrl_scan_start(void) | ||
319 | { | ||
320 | return rm31080_spi_byte_write(RM31080_REG_11, 0x17); | ||
321 | } | ||
322 | |||
323 | static u32 rm31080_ctrl_configure(void) | ||
324 | { | ||
325 | u32 u32Flag; | ||
326 | |||
327 | switch (g_stTs.u8ScanModeState) { | ||
328 | case RM_SCAN_MODE_MANUAL: | ||
329 | u32Flag = | ||
330 | RM_NEED_TO_SEND_SCAN | RM_NEED_TO_READ_RAW_DATA | | ||
331 | RM_NEED_TO_SEND_SIGNAL; | ||
332 | break; | ||
333 | #ifdef ENABLE_AUTO_SCAN | ||
334 | case RM_SCAN_MODE_PREPARE_AUTO: | ||
335 | rm31080_ctrl_enter_auto_mode(); | ||
336 | g_stTs.u8ScanModeState = RM_SCAN_MODE_AUTO_SCAN; | ||
337 | u32Flag = RM_NEED_NONE; | ||
338 | break; | ||
339 | case RM_SCAN_MODE_AUTO_SCAN: | ||
340 | rm31080_ctrl_leave_auto_mode(); | ||
341 | rm31080_ctrl_scan_start(); | ||
342 | g_stTs.u8ScanModeState = RM_SCAN_MODE_MANUAL; | ||
343 | u32Flag = | ||
344 | RM_NEED_TO_SEND_SCAN | RM_NEED_TO_READ_RAW_DATA | | ||
345 | RM_NEED_TO_SEND_SIGNAL; | ||
346 | break; | ||
347 | #endif //ENABLE_AUTO_SCAN | ||
348 | default: | ||
349 | u32Flag = RM_NEED_NONE; | ||
350 | break; | ||
351 | } | ||
352 | |||
353 | return u32Flag; | ||
354 | } | ||
355 | |||
356 | static void rm31080_enter_manual_mode(void) | ||
357 | { | ||
358 | flush_workqueue(g_stTs.rm_workqueue); | ||
359 | |||
360 | if (g_stTs.u8ScanModeState == RM_SCAN_MODE_MANUAL) | ||
361 | return; | ||
362 | |||
363 | if (g_stTs.u8ScanModeState == RM_SCAN_MODE_PREPARE_AUTO) { | ||
364 | g_stTs.u8ScanModeState = RM_SCAN_MODE_MANUAL; | ||
365 | return; | ||
366 | } | ||
367 | |||
368 | if (g_stTs.u8ScanModeState == RM_SCAN_MODE_AUTO_SCAN) { | ||
369 | rm31080_ctrl_leave_auto_mode(); | ||
370 | g_stTs.u8ScanModeState = RM_SCAN_MODE_MANUAL; | ||
371 | msleep(10); | ||
372 | } | ||
373 | } | ||
374 | |||
375 | static int rm31080_ctrl_read_raw_data(u8 * p) | ||
376 | { | ||
377 | int iRet; | ||
378 | iRet = rm31080_spi_byte_write(RM31080_REG_01, 0x10); | ||
379 | if (iRet) | ||
380 | iRet = rm31080_spi_byte_write(RM31080_REG_02, 0x00); | ||
381 | |||
382 | if (iRet) { | ||
383 | iRet = rm31080_spi_read(RM31080_REG_80, p, RM31080_RAW_DATA_LENGTH); //return 0 =succeed | ||
384 | iRet = !iRet; | ||
385 | } | ||
386 | |||
387 | if (!iRet) { | ||
388 | //printk("rm31080 read raw data failed\n"); | ||
389 | } | ||
390 | |||
391 | return iRet; | ||
392 | } | ||
393 | #endif //ENABLE_RAW_DATA_QUEUE | ||
394 | //============================================================================= | ||
395 | // Description: | ||
396 | // Queuing functions. | ||
397 | // Input: | ||
398 | // N/A | ||
399 | // Output: | ||
400 | // 0:succeed | ||
401 | // others:error code | ||
402 | //============================================================================= | ||
403 | #ifdef ENABLE_RAW_DATA_QUEUE | ||
404 | |||
405 | static void rm31080_queue_reset(void) | ||
406 | { | ||
407 | g_stQ.u16Rear = 0; | ||
408 | g_stQ.u16Front = 0; | ||
409 | } | ||
410 | |||
411 | static int rm31080_queue_init(void) | ||
412 | { | ||
413 | rm31080_queue_reset(); | ||
414 | g_stQ.pQueue = kmalloc(QUEUE_COUNT * RAW_DATA_LENGTH, GFP_KERNEL); | ||
415 | if (g_stQ.pQueue == NULL) { | ||
416 | //printk("rm31080_queue_init failed\n"); | ||
417 | return -ENOMEM; | ||
418 | } | ||
419 | return 0; | ||
420 | } | ||
421 | |||
422 | static void rm31080_queue_free(void) | ||
423 | { | ||
424 | if (!g_stQ.pQueue) | ||
425 | return; | ||
426 | kfree(g_stQ.pQueue); | ||
427 | g_stQ.pQueue = NULL; | ||
428 | } | ||
429 | |||
430 | //============================================================================= | ||
431 | // Description: | ||
432 | // About full/empty buffer distinction, | ||
433 | // There are a number of solutions like: | ||
434 | // 1.Always keep one slot open. | ||
435 | // 2.Use a fill count to distinguish the two cases. | ||
436 | // 3.Use read and write counts to get the fill count from. | ||
437 | // 4.Use absolute indices. | ||
438 | // we chose "keep one slot open" to make it simple and robust | ||
439 | // and also avoid race condition. | ||
440 | // Input: | ||
441 | // N/A | ||
442 | // Output: | ||
443 | // 1:empty | ||
444 | // 0:not empty | ||
445 | //============================================================================= | ||
446 | static int rm31080_queue_is_empty(void) | ||
447 | { | ||
448 | if (g_stQ.u16Rear == g_stQ.u16Front) | ||
449 | return 1; | ||
450 | return 0; | ||
451 | } | ||
452 | |||
453 | //============================================================================= | ||
454 | // Description: | ||
455 | // check queue full. | ||
456 | // Input: | ||
457 | // N/A | ||
458 | // Output: | ||
459 | // 1:full | ||
460 | // 0:not full | ||
461 | //============================================================================= | ||
462 | static int rm31080_queue_is_full(void) | ||
463 | { | ||
464 | if (g_stQ.u16Rear + 1 == g_stQ.u16Front) | ||
465 | return 1; | ||
466 | |||
467 | if ((g_stQ.u16Rear == (QUEUE_COUNT - 1)) && (g_stQ.u16Front == 0)) | ||
468 | return 1; | ||
469 | |||
470 | return 0; | ||
471 | } | ||
472 | |||
473 | #ifdef ENABLE_CALC_QUEUE_COUNT | ||
474 | static int rm31080_queue_get_current_count(void) | ||
475 | { | ||
476 | if (g_stQ.u16Rear >= g_stQ.u16Front) | ||
477 | return g_stQ.u16Rear - g_stQ.u16Front; | ||
478 | |||
479 | return (QUEUE_COUNT - g_stQ.u16Front) + g_stQ.u16Rear; | ||
480 | } | ||
481 | #endif | ||
482 | static void *rm31080_enqueue_start(void) | ||
483 | { | ||
484 | if (!g_stQ.pQueue) //error handling for no memory | ||
485 | return NULL; | ||
486 | |||
487 | if (!rm31080_queue_is_full()) | ||
488 | return &g_stQ.pQueue[g_stQ.u16Rear]; | ||
489 | |||
490 | //printk("rm31080 Queue full with Queue Count:%d\n", QUEUE_COUNT); | ||
491 | return NULL; | ||
492 | } | ||
493 | |||
494 | static void rm31080_enqueue_finish(void) | ||
495 | { | ||
496 | if (g_stQ.u16Rear == (QUEUE_COUNT - 1)) | ||
497 | g_stQ.u16Rear = 0; | ||
498 | else | ||
499 | g_stQ.u16Rear++; | ||
500 | } | ||
501 | |||
502 | static void *rm31080_dequeue_start(void) | ||
503 | { | ||
504 | if (!rm31080_queue_is_empty()) | ||
505 | return &g_stQ.pQueue[g_stQ.u16Front]; | ||
506 | |||
507 | return NULL; | ||
508 | } | ||
509 | |||
510 | static void rm31080_dequeue_finish(void) | ||
511 | { | ||
512 | if (g_stQ.u16Front == (QUEUE_COUNT - 1)) | ||
513 | g_stQ.u16Front = 0; | ||
514 | else | ||
515 | g_stQ.u16Front++; | ||
516 | } | ||
517 | |||
518 | static long rm31080_queue_read_raw_data(u8 * p, u32 u32Len) | ||
519 | { | ||
520 | u8 *pQueue; | ||
521 | u32 u32Ret; | ||
522 | pQueue = rm31080_dequeue_start(); | ||
523 | if (!pQueue) | ||
524 | return 0; | ||
525 | |||
526 | u32Ret = copy_to_user(p, pQueue, u32Len); | ||
527 | if (u32Ret != 0) | ||
528 | return 0; | ||
529 | |||
530 | rm31080_dequeue_finish(); | ||
531 | return 1; | ||
532 | |||
533 | } | ||
534 | #endif //ENABLE_RAW_DATA_QUEUE | ||
535 | |||
536 | //============================================================================= | ||
537 | // Description: | ||
538 | // Copy Config(Parameters) to HAL's Buffer | ||
539 | // Input: | ||
540 | // p: HAL's buffer | ||
541 | // u32Len : buffer size | ||
542 | // Output: | ||
543 | // 1: succeed | ||
544 | // 0: failed | ||
545 | //============================================================================= | ||
546 | static long rm31080_get_config(u8 * p, u32 u32Len) | ||
547 | { | ||
548 | u32 u32Ret; | ||
549 | struct rm_spi_ts_platform_data *pdata; | ||
550 | pdata = g_input_dev->dev.parent->platform_data; | ||
551 | u32Ret = copy_to_user(p, pdata->config, u32Len); | ||
552 | if (u32Ret != 0) | ||
553 | return 0; | ||
554 | return 1; | ||
555 | } | ||
556 | |||
557 | #ifdef ENABLE_AUTO_FREQ | ||
558 | void raydium_auto_freq() | ||
559 | { | ||
560 | g_stTs.bInitFinish = 0; | ||
561 | msleep(10); | ||
562 | rm31080_ctrl_clear_int(); | ||
563 | |||
564 | //roger_auto_freq_detection(); | ||
565 | |||
566 | g_stTs.bInitFinish = 1; | ||
567 | rm31080_ctrl_scan_start(); | ||
568 | |||
569 | } | ||
570 | #endif //ENABLE_TEST_AUTO_FREQ | ||
571 | //============================================================================= | ||
572 | #ifdef ENABLE_AUTO_SCAN | ||
573 | void raydium_change_scan_mode(u8 u8TouchCount) | ||
574 | { | ||
575 | static u32 u32NoTouchCount = 0; | ||
576 | if (u8TouchCount) { | ||
577 | u32NoTouchCount = 0; | ||
578 | return; | ||
579 | } | ||
580 | if (u32NoTouchCount < 100) { | ||
581 | u32NoTouchCount++; | ||
582 | } else if (g_stTs.u8ScanModeState == RM_SCAN_MODE_MANUAL) { | ||
583 | #ifdef ENABLE_AUTO_FREQ | ||
584 | raydium_auto_freq(); | ||
585 | #else | ||
586 | if (g_stTs.bEnableAutoScan) | ||
587 | g_stTs.u8ScanModeState = RM_SCAN_MODE_PREPARE_AUTO; | ||
588 | #endif | ||
589 | u32NoTouchCount = 0; | ||
590 | } | ||
591 | } | ||
592 | #endif //ENABLE_AUTO_SCAN | ||
593 | //============================================================================= | ||
594 | //report touch data for scriber | ||
595 | // | ||
596 | //============================================================================= | ||
597 | #ifdef ENABLE_REPORT_TO_UART | ||
598 | void raydium_report_to_uart_printf(unsigned char *ucData, unsigned char ucCount) | ||
599 | { | ||
600 | unsigned char i; | ||
601 | for (i = 0; i < ucCount; i++) { | ||
602 | printk("%02X", ucData[i]); | ||
603 | } | ||
604 | printk("\n"); | ||
605 | } | ||
606 | |||
607 | void raydium_report_to_uart(void *p) | ||
608 | { | ||
609 | unsigned char ucData[1 + 1 + (4 * 12) + 1]; //1=Tag,1=Touch count,4=(xH xL ,yH yL) ,12=max point,1=Check sum | ||
610 | rm_touch_event *spTP; | ||
611 | unsigned short usX, usY; | ||
612 | int i, j; | ||
613 | |||
614 | if (g_stTs.bEnableScriber == 0) | ||
615 | return; | ||
616 | |||
617 | spTP = (rm_touch_event *) p; | ||
618 | |||
619 | ucData[0] = 0x8E; | ||
620 | ucData[1] = spTP->ucTouchCount; | ||
621 | j = 2; | ||
622 | for (i = 0; i < spTP->ucTouchCount; i++) { | ||
623 | usX = spTP->usX[i] + 1; //1~1536 | ||
624 | usY = spTP->usY[i] + 1; //1~960 | ||
625 | ucData[j++] = ((usX >> 8) & 0xFF) | (spTP->ucID[i] << 4); //add id | ||
626 | ucData[j++] = ((usX) & 0xFF); | ||
627 | ucData[j++] = ((usY >> 8) & 0xFF); | ||
628 | ucData[j++] = ((usY) & 0xFF); | ||
629 | } | ||
630 | |||
631 | //check sum | ||
632 | ucData[j] = 0; | ||
633 | for (i = 0; i < j; i++) { | ||
634 | ucData[j] += ucData[i]; | ||
635 | } | ||
636 | ucData[j] = 0x100 - ucData[j]; | ||
637 | j++; | ||
638 | |||
639 | |||
640 | raydium_report_to_uart_printf(ucData, j); | ||
641 | if (spTP->ucTouchCount == 0) //send more , to avoid losing | ||
642 | { | ||
643 | raydium_report_to_uart_printf(ucData, j); | ||
644 | raydium_report_to_uart_printf(ucData, j); | ||
645 | } | ||
646 | } | ||
647 | #endif | ||
648 | //============================================================================= | ||
649 | void raydium_report_pointer(void *p) | ||
650 | { | ||
651 | static unsigned char ucLastTouchCount = 0; | ||
652 | int i; | ||
653 | int iCount; | ||
654 | rm_touch_event *spTP; | ||
655 | spTP = (rm_touch_event *) p; | ||
656 | |||
657 | iCount = max(ucLastTouchCount, spTP->ucTouchCount); | ||
658 | if (iCount) { | ||
659 | for (i = 0; i < iCount; i++) { | ||
660 | if (i == 10) | ||
661 | break; //due to the "touch test" can't support great than 10 points | ||
662 | |||
663 | if (i < spTP->ucTouchCount) { | ||
664 | input_report_abs(g_input_dev, | ||
665 | ABS_MT_TRACKING_ID, | ||
666 | spTP->ucID[i]); | ||
667 | |||
668 | input_report_abs(g_input_dev, | ||
669 | ABS_MT_TOUCH_MAJOR, 100); | ||
670 | if (spTP->usX[i] >= (RM_INPUT_RESOLUTION_X - 1)) | ||
671 | input_report_abs(g_input_dev, ABS_MT_POSITION_X, (RM_INPUT_RESOLUTION_X - 1) - 1); //fixed bug: OS scale fail | ||
672 | else | ||
673 | input_report_abs(g_input_dev, | ||
674 | ABS_MT_POSITION_X, | ||
675 | spTP->usX[i]); | ||
676 | |||
677 | if (spTP->usY[i] >= (RM_INPUT_RESOLUTION_Y - 1)) | ||
678 | input_report_abs(g_input_dev, ABS_MT_POSITION_Y, (RM_INPUT_RESOLUTION_Y - 1) - 1); //fixed bug: OS scale fail | ||
679 | else | ||
680 | input_report_abs(g_input_dev, | ||
681 | ABS_MT_POSITION_Y, | ||
682 | spTP->usY[i]); | ||
683 | } | ||
684 | input_mt_sync(g_input_dev); | ||
685 | } | ||
686 | ucLastTouchCount = spTP->ucTouchCount; | ||
687 | input_report_key(g_input_dev, BTN_TOUCH, | ||
688 | spTP->ucTouchCount > 0); | ||
689 | input_sync(g_input_dev); | ||
690 | #ifdef ENABLE_REPORT_TO_UART | ||
691 | raydium_report_to_uart(p); | ||
692 | #endif | ||
693 | |||
694 | } | ||
695 | |||
696 | #ifdef ENABLE_AUTO_SCAN | ||
697 | raydium_change_scan_mode(spTP->ucTouchCount); | ||
698 | #endif | ||
699 | } | ||
700 | |||
701 | //============================================================================= | ||
702 | |||
703 | //============================================================================= | ||
704 | int rm31080_ts_send_signal(int pid, int iInfo) | ||
705 | { | ||
706 | struct siginfo info; | ||
707 | struct task_struct *t; | ||
708 | int ret; | ||
709 | |||
710 | /* send the signal */ | ||
711 | memset(&info, 0, sizeof(struct siginfo)); | ||
712 | info.si_signo = RM_TS_SIGNAL; | ||
713 | info.si_code = SI_QUEUE; // this is bit of a trickery: SI_QUEUE is normally used by sigqueue from user space, | ||
714 | // and kernel space should use SI_KERNEL. But if SI_KERNEL is used the real_time data | ||
715 | // is not delivered to the user space signal handler function. | ||
716 | info.si_int = iInfo; //real time signals may have 32 bits of data. | ||
717 | |||
718 | rcu_read_lock(); | ||
719 | t = find_task_by_vpid(pid); | ||
720 | if (t == NULL) { | ||
721 | //printk("no such pid\n"); | ||
722 | rcu_read_unlock(); | ||
723 | return -ENODEV; | ||
724 | } | ||
725 | rcu_read_unlock(); | ||
726 | ret = send_sig_info(RM_TS_SIGNAL, &info, t); //send the signal | ||
727 | if (ret < 0) { | ||
728 | //printk("error sending signal\n"); | ||
729 | return ret; | ||
730 | } | ||
731 | |||
732 | return ret; | ||
733 | } | ||
734 | |||
735 | //============================================================================= | ||
736 | static void __rm31080_enable(struct rm31080_ts *ts) | ||
737 | { | ||
738 | enable_irq(ts->irq); | ||
739 | } | ||
740 | |||
741 | static void __rm31080_disable(struct rm31080_ts *ts) | ||
742 | { | ||
743 | disable_irq(ts->irq); | ||
744 | } | ||
745 | |||
746 | static void vtest_toggle(struct rm31080_ts *ts, bool disable) | ||
747 | { | ||
748 | mutex_lock(&ts->input->mutex); | ||
749 | |||
750 | if (!ts->suspended && ts->input->users != 0) { | ||
751 | |||
752 | if (disable) { | ||
753 | if (ts->disabled) | ||
754 | __rm31080_enable(ts); | ||
755 | } else { | ||
756 | if (!ts->disabled) | ||
757 | __rm31080_disable(ts); | ||
758 | } | ||
759 | } | ||
760 | |||
761 | ts->disabled = disable; | ||
762 | |||
763 | mutex_unlock(&ts->input->mutex); | ||
764 | } | ||
765 | |||
766 | static ssize_t vtest_disable_show(struct device *dev, | ||
767 | struct device_attribute *attr, char *buf) | ||
768 | { | ||
769 | struct rm31080_ts *ts = dev_get_drvdata(dev); | ||
770 | |||
771 | return sprintf(buf, "%u\n", ts->disabled); | ||
772 | } | ||
773 | |||
774 | static ssize_t vtest_disable_store(struct device *dev, | ||
775 | struct device_attribute *attr, | ||
776 | const char *buf, size_t count) | ||
777 | { | ||
778 | struct rm31080_ts *ts = dev_get_drvdata(dev); | ||
779 | unsigned long val; | ||
780 | int error; | ||
781 | |||
782 | error = strict_strtoul(buf, 10, &val); | ||
783 | if (error) | ||
784 | return error; | ||
785 | |||
786 | vtest_toggle(ts, val); | ||
787 | |||
788 | return count; | ||
789 | } | ||
790 | |||
791 | static DEVICE_ATTR(disable, 0664, vtest_disable_show, vtest_disable_store); | ||
792 | static struct attribute *vtest_attributes[] = { | ||
793 | &dev_attr_disable.attr, | ||
794 | NULL | ||
795 | }; | ||
796 | |||
797 | static const struct attribute_group vtest_attr_group = { | ||
798 | .attrs = vtest_attributes, | ||
799 | }; | ||
800 | |||
801 | static int rm31080_input_open(struct input_dev *input) | ||
802 | { | ||
803 | struct rm31080_ts *ts = input_get_drvdata(input); | ||
804 | |||
805 | /* protected by input->mutex */ | ||
806 | if (!ts->disabled && !ts->suspended) | ||
807 | __rm31080_enable(ts); | ||
808 | |||
809 | return 0; | ||
810 | } | ||
811 | |||
812 | static void rm31080_input_close(struct input_dev *input) | ||
813 | { | ||
814 | struct rm31080_ts *ts = input_get_drvdata(input); | ||
815 | |||
816 | /* protected by input->mutex */ | ||
817 | if (!ts->disabled && !ts->suspended) | ||
818 | __rm31080_disable(ts); | ||
819 | } | ||
820 | |||
821 | //============================================================================= | ||
822 | |||
823 | #ifdef ENABLE_TEST_AVERAGE //only for test | ||
824 | #define _AVERAGE_COUNT 2 | ||
825 | s8 g_bAverageBuf[_AVERAGE_COUNT][2048]; | ||
826 | int test_soft_average(s8 * pSource) | ||
827 | { | ||
828 | static u8 u8AverageIndex = 0; | ||
829 | static u8 u8StartAverage = 0; | ||
830 | u16 i, j; | ||
831 | s16 s16Sum; | ||
832 | |||
833 | for (i = 0; i < RM31080_RAW_DATA_LENGTH; i++) //RM31080_RAW_DATA_LENGTH =1530 | ||
834 | g_bAverageBuf[u8AverageIndex][i] = pSource[i] - 0x80; | ||
835 | u8AverageIndex++; | ||
836 | |||
837 | if (u8AverageIndex == _AVERAGE_COUNT) { | ||
838 | u8StartAverage = 1; | ||
839 | u8AverageIndex = 0; | ||
840 | } | ||
841 | else | ||
842 | { | ||
843 | u8StartAverage = 0; | ||
844 | } | ||
845 | |||
846 | if (u8StartAverage) { | ||
847 | for (i = 0; i < RM31080_RAW_DATA_LENGTH; i++) { | ||
848 | s16Sum = 0; | ||
849 | for (j = 0; j < _AVERAGE_COUNT; j++) | ||
850 | s16Sum += g_bAverageBuf[j][i]; | ||
851 | pSource[i] = (s16Sum / _AVERAGE_COUNT) + 0x80; | ||
852 | } | ||
853 | return 1; | ||
854 | } | ||
855 | return 0; | ||
856 | } | ||
857 | #endif | ||
858 | |||
859 | #ifdef ENABLE_WORK_QUEUE | ||
860 | //1.2 | ||
861 | static void rm_work_handler(struct work_struct *work) | ||
862 | { | ||
863 | void *pKernelBuffer; | ||
864 | u32 u32Flag; | ||
865 | int iRet; | ||
866 | |||
867 | |||
868 | if (g_stTs.bIsSuspended) { | ||
869 | //printk("rm_work_handler stops after suspend\n"); | ||
870 | return; | ||
871 | } | ||
872 | |||
873 | g_stTs.bIsWorkQueueExecuting = 1; | ||
874 | |||
875 | iRet = rm31080_ctrl_clear_int(); | ||
876 | |||
877 | u32Flag = rm31080_ctrl_configure(); | ||
878 | |||
879 | if (u32Flag | RM_NEED_TO_SEND_SCAN) { | ||
880 | rm31080_ctrl_scan_start(); | ||
881 | } | ||
882 | |||
883 | if (u32Flag | RM_NEED_TO_READ_RAW_DATA) { | ||
884 | pKernelBuffer = rm31080_enqueue_start(); | ||
885 | if (pKernelBuffer) { | ||
886 | iRet = rm31080_ctrl_read_raw_data((u8 *) pKernelBuffer); | ||
887 | #ifdef ENABLE_TEST_AVERAGE | ||
888 | if (iRet) { | ||
889 | iRet = test_soft_average((s8 *) pKernelBuffer); | ||
890 | } | ||
891 | #endif | ||
892 | if (iRet) { | ||
893 | rm31080_enqueue_finish(); | ||
894 | } | ||
895 | } | ||
896 | } | ||
897 | |||
898 | if (u32Flag | RM_NEED_TO_SEND_SIGNAL) { | ||
899 | if (g_stTs.bCalcFinish) { | ||
900 | g_stTs.bCalcFinish = 0; | ||
901 | rm31080_ts_send_signal(g_stTs.ulHalPID, RM_SIGNAL_INTR); | ||
902 | } | ||
903 | } | ||
904 | g_stTs.bIsWorkQueueExecuting = 0; | ||
905 | } | ||
906 | #endif | ||
907 | |||
908 | static irqreturn_t rm31080_irq(int irq, void *handle) | ||
909 | { | ||
910 | |||
911 | //struct rm31080_ts *ts = handle; | ||
912 | if (!g_stTs.bInitFinish) { | ||
913 | return IRQ_HANDLED; | ||
914 | } | ||
915 | |||
916 | #ifdef ENABLE_WORK_QUEUE | ||
917 | queue_work(g_stTs.rm_workqueue, &g_stTs.rm_work); | ||
918 | #endif | ||
919 | |||
920 | return IRQ_HANDLED; | ||
921 | } | ||
922 | |||
923 | //============================================================================= | ||
924 | static void rm31080_init_ts_structure_part(void) | ||
925 | { | ||
926 | g_stTs.bInitFinish = 0; | ||
927 | g_stTs.bCalcFinish = 0; | ||
928 | g_stTs.bEnableScriber = 0; | ||
929 | g_stTs.bIsSuspended = 0; | ||
930 | g_stTs.bEnableAutoScan = 1; | ||
931 | |||
932 | #ifdef ENABLE_RAW_DATA_QUEUE | ||
933 | g_stTs.u8ScanModeState = RM_SCAN_MODE_MANUAL; | ||
934 | #endif | ||
935 | } | ||
936 | |||
937 | static void rm31080_init_ts_structure(void) | ||
938 | { | ||
939 | g_stTs.ulHalPID = 0; | ||
940 | |||
941 | memset(&g_stTs, 0, sizeof(struct rm31080a_ts_para)); | ||
942 | |||
943 | #ifdef ENABLE_WORK_QUEUE | ||
944 | g_stTs.rm_workqueue = create_singlethread_workqueue("rm_work"); | ||
945 | INIT_WORK(&g_stTs.rm_work, rm_work_handler); | ||
946 | g_stTs.bIsWorkQueueExecuting = 0; | ||
947 | #endif | ||
948 | } | ||
949 | |||
950 | //============================================================================= | ||
951 | static void rm31080_start(struct rm31080_ts *ts) | ||
952 | { | ||
953 | #ifdef ENABLE_RM31080_DEEP_SLEEP | ||
954 | struct rm_spi_ts_platform_data *pdata; | ||
955 | #endif | ||
956 | |||
957 | if (!g_stTs.bIsSuspended) | ||
958 | return; | ||
959 | g_stTs.bIsSuspended = 0; | ||
960 | |||
961 | #ifdef ENABLE_RM31080_DEEP_SLEEP | ||
962 | //flow designed by Roger //20110930 | ||
963 | pdata = g_input_dev->dev.parent->platform_data; | ||
964 | gpio_set_value(pdata->gpio_reset, 0); | ||
965 | msleep(120); | ||
966 | gpio_set_value(pdata->gpio_reset, 1); | ||
967 | msleep(10); | ||
968 | rm31080_init_ts_structure_part(); | ||
969 | rm31080_ts_send_signal(g_stTs.ulHalPID, RM_SIGNAL_RESUME); | ||
970 | #elif defined(ENABLE_AUTO_SCAN) | ||
971 | rm31080_ctrl_clear_int(); | ||
972 | rm31080_ctrl_scan_start(); | ||
973 | #endif | ||
974 | |||
975 | } | ||
976 | |||
977 | static void rm31080_stop(struct rm31080_ts *ts) | ||
978 | { | ||
979 | int iCount; | ||
980 | if (g_stTs.bIsSuspended) | ||
981 | return; | ||
982 | |||
983 | iCount = 0; | ||
984 | while (g_stTs.bIsWorkQueueExecuting) { | ||
985 | //printk("Raydium TS: Work_Queue is Executing.\n"); | ||
986 | msleep(1); | ||
987 | iCount++; | ||
988 | if (iCount > 1000) | ||
989 | break; | ||
990 | } | ||
991 | g_stTs.bIsSuspended = 1; | ||
992 | |||
993 | #ifdef ENABLE_RM31080_DEEP_SLEEP | ||
994 | rm31080_ctrl_suspend(); | ||
995 | #endif | ||
996 | } | ||
997 | |||
998 | #ifdef CONFIG_PM | ||
999 | static int rm31080_suspend(struct device *dev) | ||
1000 | { | ||
1001 | struct rm31080_ts *ts = dev_get_drvdata(dev); | ||
1002 | rm31080_stop(ts); | ||
1003 | return 0; | ||
1004 | } | ||
1005 | |||
1006 | static int rm31080_resume(struct device *dev) | ||
1007 | { | ||
1008 | struct rm31080_ts *ts = dev_get_drvdata(dev); | ||
1009 | rm31080_start(ts); | ||
1010 | return 0; | ||
1011 | } | ||
1012 | |||
1013 | #if defined(CONFIG_HAS_EARLYSUSPEND) | ||
1014 | static void rm31080_early_suspend(struct early_suspend *es) | ||
1015 | { | ||
1016 | struct rm31080_ts *ts; | ||
1017 | struct device *dev; | ||
1018 | |||
1019 | ts = container_of(es, struct rm31080_ts, early_suspend); | ||
1020 | dev = ts->dev; | ||
1021 | |||
1022 | if (rm31080_suspend(dev) != 0) { | ||
1023 | dev_err(dev, "%s: failed\n", __func__); | ||
1024 | } | ||
1025 | } | ||
1026 | |||
1027 | static void rm31080_early_resume(struct early_suspend *es) | ||
1028 | { | ||
1029 | struct rm31080_ts *ts; | ||
1030 | struct device *dev; | ||
1031 | |||
1032 | ts = container_of(es, struct rm31080_ts, early_suspend); | ||
1033 | dev = ts->dev; | ||
1034 | |||
1035 | if (rm31080_resume(dev) != 0) { | ||
1036 | dev_err(dev, "%s: failed\n", __func__); | ||
1037 | } | ||
1038 | } | ||
1039 | #else | ||
1040 | static const struct dev_pm_ops rm31080_pm_ops = { | ||
1041 | .suspend = rm31080_suspend, | ||
1042 | .resume = rm31080_resume, | ||
1043 | }; | ||
1044 | #endif | ||
1045 | #endif | ||
1046 | |||
1047 | struct rm31080_ts *rm31080_input_init(struct device *dev, unsigned int irq, | ||
1048 | const struct rm31080_bus_ops *bops) | ||
1049 | { | ||
1050 | |||
1051 | struct rm31080_ts *ts; | ||
1052 | struct input_dev *input_dev; | ||
1053 | int err; | ||
1054 | |||
1055 | if (!irq) { | ||
1056 | dev_err(dev, "no IRQ?\n"); | ||
1057 | err = -EINVAL; | ||
1058 | goto err_out; | ||
1059 | } | ||
1060 | |||
1061 | ts = kzalloc(sizeof(*ts), GFP_KERNEL); | ||
1062 | |||
1063 | input_dev = input_allocate_device(); | ||
1064 | |||
1065 | if (!ts || !input_dev) { | ||
1066 | dev_err(dev, "Failed to allocate memory\n"); | ||
1067 | err = -ENOMEM; | ||
1068 | goto err_free_mem; | ||
1069 | } | ||
1070 | |||
1071 | g_input_dev = input_dev; | ||
1072 | |||
1073 | ts->bops = bops; | ||
1074 | ts->dev = dev; | ||
1075 | ts->input = input_dev; | ||
1076 | ts->irq = irq; | ||
1077 | |||
1078 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(dev)); | ||
1079 | |||
1080 | input_dev->name = "raydium_ts"; | ||
1081 | input_dev->phys = ts->phys; | ||
1082 | input_dev->dev.parent = dev; | ||
1083 | input_dev->id.bustype = bops->bustype; | ||
1084 | |||
1085 | input_dev->open = rm31080_input_open; | ||
1086 | input_dev->close = rm31080_input_close; | ||
1087 | |||
1088 | input_set_drvdata(input_dev, ts); | ||
1089 | |||
1090 | __set_bit(EV_ABS, input_dev->evbit); | ||
1091 | __set_bit(ABS_X, input_dev->absbit); | ||
1092 | __set_bit(ABS_Y, input_dev->absbit); | ||
1093 | __set_bit(ABS_PRESSURE, input_dev->absbit); | ||
1094 | |||
1095 | __set_bit(EV_KEY, input_dev->evbit); | ||
1096 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
1097 | |||
1098 | |||
1099 | input_set_abs_params(input_dev, ABS_X, | ||
1100 | 0, RM_INPUT_RESOLUTION_X - 1, 0, 0); | ||
1101 | input_set_abs_params(input_dev, ABS_Y, | ||
1102 | 0, RM_INPUT_RESOLUTION_Y - 1, 0, 0); | ||
1103 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 1, 0, 0); | ||
1104 | |||
1105 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 0xFF, 0, 0); | ||
1106 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | ||
1107 | 0, RM_INPUT_RESOLUTION_X - 1, 0, 0); | ||
1108 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
1109 | 0, RM_INPUT_RESOLUTION_Y - 1, 0, 0); | ||
1110 | input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, 32, 0, 0); | ||
1111 | |||
1112 | err = request_threaded_irq(ts->irq, NULL, rm31080_irq, | ||
1113 | IRQF_TRIGGER_RISING, dev_name(dev), ts); | ||
1114 | if (err) { | ||
1115 | dev_err(dev, "irq %d busy?\n", ts->irq); | ||
1116 | goto err_free_mem; | ||
1117 | } | ||
1118 | |||
1119 | mutex_init(&ts->access_mutex); | ||
1120 | #if defined(CONFIG_HAS_EARLYSUSPEND) | ||
1121 | ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; | ||
1122 | ts->early_suspend.suspend = rm31080_early_suspend; | ||
1123 | ts->early_suspend.resume = rm31080_early_resume; | ||
1124 | register_early_suspend(&ts->early_suspend); | ||
1125 | #endif | ||
1126 | |||
1127 | __rm31080_disable(ts); | ||
1128 | |||
1129 | err = sysfs_create_group(&dev->kobj, &vtest_attr_group); | ||
1130 | if (err) | ||
1131 | goto err_free_irq; | ||
1132 | |||
1133 | err = input_register_device(input_dev); | ||
1134 | if (err) | ||
1135 | goto err_remove_attr; | ||
1136 | |||
1137 | return ts; | ||
1138 | |||
1139 | err_remove_attr: | ||
1140 | sysfs_remove_group(&dev->kobj, &vtest_attr_group); | ||
1141 | err_free_irq: | ||
1142 | free_irq(ts->irq, ts); | ||
1143 | err_free_mem: | ||
1144 | input_free_device(input_dev); | ||
1145 | kfree(ts); | ||
1146 | err_out: | ||
1147 | return ERR_PTR(err); | ||
1148 | } | ||
1149 | |||
1150 | static int dev_open(struct inode *inode, struct file *filp) | ||
1151 | { | ||
1152 | return 0; | ||
1153 | } | ||
1154 | |||
1155 | static int dev_release(struct inode *inode, struct file *filp) | ||
1156 | { | ||
1157 | g_stTs.bInitFinish = 0; | ||
1158 | rm31080_enter_manual_mode(); | ||
1159 | return 0; | ||
1160 | } | ||
1161 | |||
1162 | static ssize_t | ||
1163 | dev_read(struct file *filp, char __user * buf, size_t count, loff_t * pos) | ||
1164 | { | ||
1165 | unsigned long missing; | ||
1166 | ssize_t status = 0; | ||
1167 | u8 *pMyBuf; | ||
1168 | |||
1169 | pMyBuf = kmalloc(count, GFP_KERNEL); | ||
1170 | if (pMyBuf == NULL) | ||
1171 | return -ENOMEM; | ||
1172 | |||
1173 | pMyBuf[0] = buf[0]; | ||
1174 | status = rm31080_spi_read(pMyBuf[0], pMyBuf, count); | ||
1175 | |||
1176 | if (status != 0) { | ||
1177 | //printk("rm31080_spi_read() fail\n"); | ||
1178 | } | ||
1179 | status = count; | ||
1180 | missing = copy_to_user(buf, pMyBuf, count); | ||
1181 | |||
1182 | if (missing == status) | ||
1183 | status = -EFAULT; | ||
1184 | else | ||
1185 | status = status - missing; | ||
1186 | |||
1187 | kfree(pMyBuf); | ||
1188 | return status; | ||
1189 | } | ||
1190 | |||
1191 | static ssize_t | ||
1192 | dev_write(struct file *filp, const char __user * buf, | ||
1193 | size_t count, loff_t * pos) | ||
1194 | { | ||
1195 | u8 *pMyBuf; | ||
1196 | unsigned long missing; | ||
1197 | ssize_t status = 0; | ||
1198 | |||
1199 | pMyBuf = kmalloc(count, GFP_KERNEL); | ||
1200 | if (pMyBuf == NULL) | ||
1201 | return -ENOMEM; | ||
1202 | |||
1203 | missing = copy_from_user(pMyBuf, buf, count); | ||
1204 | if (missing == 0) { | ||
1205 | status = rm31080_spi_write(pMyBuf, count); | ||
1206 | } else | ||
1207 | status = -EFAULT; | ||
1208 | |||
1209 | kfree(pMyBuf); | ||
1210 | return count; | ||
1211 | } | ||
1212 | |||
1213 | //============================================================================= | ||
1214 | // Description: | ||
1215 | // I/O Control routin. | ||
1216 | // Input: | ||
1217 | // file: | ||
1218 | // cmd : | ||
1219 | // arg : | ||
1220 | // Output: | ||
1221 | // 1: succeed | ||
1222 | // 0: failed | ||
1223 | //============================================================================= | ||
1224 | static long dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
1225 | { | ||
1226 | long ret = 1; | ||
1227 | switch (cmd & 0xFFFF) { | ||
1228 | case RM_IOCTL_REPORT_POINT: | ||
1229 | raydium_report_pointer((void *)arg); | ||
1230 | break; | ||
1231 | case RM_IOCTL_SET_HAL_PID: | ||
1232 | g_stTs.ulHalPID = arg; | ||
1233 | break; | ||
1234 | case RM_IOCTL_INIT_START: | ||
1235 | g_stTs.bInitFinish = 0; | ||
1236 | rm31080_enter_manual_mode(); | ||
1237 | break; | ||
1238 | case RM_IOCTL_INIT_END: | ||
1239 | g_stTs.bInitFinish = 1; | ||
1240 | g_stTs.bCalcFinish = 1; | ||
1241 | #ifdef ENABLE_RAW_DATA_QUEUE | ||
1242 | ret = rm31080_ctrl_scan_start(); | ||
1243 | #endif | ||
1244 | break; | ||
1245 | case RM_IOCTL_FINISH_CALC: | ||
1246 | g_stTs.bCalcFinish = 1; | ||
1247 | break; | ||
1248 | case RM_IOCTL_SCRIBER_CTRL: | ||
1249 | g_stTs.bEnableScriber = (bool) arg; | ||
1250 | break; | ||
1251 | case RM_IOCTL_AUTOSCAN_CTRL: | ||
1252 | g_stTs.bEnableAutoScan = (bool) arg; | ||
1253 | break; | ||
1254 | #ifdef ENABLE_RAW_DATA_QUEUE | ||
1255 | case RM_IOCTL_READ_RAW_DATA: | ||
1256 | ret = | ||
1257 | rm31080_queue_read_raw_data((u8 *) arg, | ||
1258 | (cmd >> 16) & 0xFFFF); | ||
1259 | break; | ||
1260 | #endif | ||
1261 | case RM_IOCTL_SET_PARAMETER: | ||
1262 | ret = rm31080_get_config((u8 *) arg, (cmd >> 16) & 0xFFFF); | ||
1263 | break; | ||
1264 | default: | ||
1265 | break; | ||
1266 | } | ||
1267 | return ret; | ||
1268 | } | ||
1269 | |||
1270 | static struct file_operations dev_fops = { | ||
1271 | .owner = THIS_MODULE, | ||
1272 | .open = dev_open, | ||
1273 | .release = dev_release, | ||
1274 | .read = dev_read, | ||
1275 | .write = dev_write, | ||
1276 | .unlocked_ioctl = dev_ioctl, | ||
1277 | }; | ||
1278 | |||
1279 | static struct miscdevice raydium_ts_miscdev = { | ||
1280 | .minor = MISC_DYNAMIC_MINOR, | ||
1281 | .name = "raydium_ts", | ||
1282 | .fops = &dev_fops, | ||
1283 | }; | ||
1284 | |||
1285 | static const struct rm31080_bus_ops rm31080_spi_bus_ops = { | ||
1286 | .bustype = BUS_SPI, | ||
1287 | }; | ||
1288 | |||
1289 | static int __devexit rm31080_spi_remove(struct spi_device *spi) | ||
1290 | { | ||
1291 | struct rm31080_ts *ts = spi_get_drvdata(spi); | ||
1292 | |||
1293 | #ifdef ENABLE_RAW_DATA_QUEUE | ||
1294 | rm31080_queue_free(); | ||
1295 | #endif | ||
1296 | |||
1297 | #ifdef ENABLE_WORK_QUEUE | ||
1298 | if (g_stTs.rm_workqueue) | ||
1299 | destroy_workqueue(g_stTs.rm_workqueue); | ||
1300 | #endif | ||
1301 | |||
1302 | misc_deregister(&raydium_ts_miscdev); | ||
1303 | |||
1304 | sysfs_remove_group(&ts->dev->kobj, &vtest_attr_group); | ||
1305 | free_irq(ts->irq, ts); | ||
1306 | input_unregister_device(ts->input); | ||
1307 | kfree(ts); | ||
1308 | spi_set_drvdata(spi, NULL); | ||
1309 | return 0; | ||
1310 | } | ||
1311 | |||
1312 | static int __devinit rm31080_spi_probe(struct spi_device *spi) | ||
1313 | { | ||
1314 | struct rm31080_ts *ts; | ||
1315 | |||
1316 | rm31080_init_ts_structure(); | ||
1317 | rm31080_init_ts_structure_part(); | ||
1318 | |||
1319 | if (spi->max_speed_hz > MAX_SPI_FREQ_HZ) { | ||
1320 | dev_err(&spi->dev, "SPI CLK %d Hz?\n", spi->max_speed_hz); | ||
1321 | return -EINVAL; | ||
1322 | } | ||
1323 | |||
1324 | ts = rm31080_input_init(&spi->dev, spi->irq, &rm31080_spi_bus_ops); | ||
1325 | if (IS_ERR(ts)) | ||
1326 | return PTR_ERR(ts); | ||
1327 | spi_set_drvdata(spi, ts); | ||
1328 | |||
1329 | g_spi = spi; | ||
1330 | |||
1331 | if (misc_register(&raydium_ts_miscdev) != 0) { | ||
1332 | dev_err(&spi->dev, "Raydium TS: cannot register miscdev\n"); | ||
1333 | return 0; | ||
1334 | } | ||
1335 | #ifdef ENABLE_RAW_DATA_QUEUE | ||
1336 | rm31080_queue_init(); | ||
1337 | #endif | ||
1338 | |||
1339 | return 0; | ||
1340 | } | ||
1341 | |||
1342 | static struct spi_driver rm31080_spi_driver = { | ||
1343 | .driver = { | ||
1344 | .name = "rm_ts_spidev", | ||
1345 | .bus = &spi_bus_type, | ||
1346 | .owner = THIS_MODULE, | ||
1347 | #if !defined(CONFIG_HAS_EARLYSUSPEND) | ||
1348 | .pm = &rm31080_pm_ops, | ||
1349 | #endif | ||
1350 | }, | ||
1351 | .probe = rm31080_spi_probe, | ||
1352 | .remove = __devexit_p(rm31080_spi_remove), | ||
1353 | }; | ||
1354 | |||
1355 | static int __init rm31080_spi_init(void) | ||
1356 | { | ||
1357 | return spi_register_driver(&rm31080_spi_driver); | ||
1358 | } | ||
1359 | module_init(rm31080_spi_init); | ||
1360 | |||
1361 | static void __exit rm31080_spi_exit(void) | ||
1362 | { | ||
1363 | spi_unregister_driver(&rm31080_spi_driver); | ||
1364 | } | ||
1365 | module_exit(rm31080_spi_exit); | ||
1366 | |||
1367 | MODULE_AUTHOR("Valentine Hsu <valentine.hsu@rad-ic.com>"); | ||
1368 | MODULE_DESCRIPTION("Raydium touchscreen SPI bus driver"); | ||
1369 | MODULE_LICENSE("GPL"); | ||
1370 | MODULE_ALIAS("spi:raydium-t007"); | ||
diff --git a/drivers/input/touchscreen/rmi4/Makefile b/drivers/input/touchscreen/rmi4/Makefile new file mode 100644 index 00000000000..a7375ed07a3 --- /dev/null +++ b/drivers/input/touchscreen/rmi4/Makefile | |||
@@ -0,0 +1,18 @@ | |||
1 | # | ||
2 | # Makefile for Synaptics Touchscreen (RMI4/SPI) | ||
3 | # | ||
4 | GCOV_PROFILE := y | ||
5 | |||
6 | ccflags-$(CONFIG_SPI_DEBUG) := -DDEBUG | ||
7 | |||
8 | #Synaptics SPI Sensor (2002) | ||
9 | obj-$(CONFIG_TOUCHSCREEN_SYN_RMI4_SPI) += rmi_bus.o | ||
10 | obj-$(CONFIG_TOUCHSCREEN_SYN_RMI4_SPI) += rmi_i2c.o | ||
11 | obj-$(CONFIG_TOUCHSCREEN_SYN_RMI4_SPI) += rmi_spi.o | ||
12 | obj-$(CONFIG_TOUCHSCREEN_SYN_RMI4_SPI) += rmi_driver.o rmi_f01.o | ||
13 | obj-$(CONFIG_TOUCHSCREEN_SYN_RMI4_SPI) += rmi_f09.o | ||
14 | obj-$(CONFIG_TOUCHSCREEN_SYN_RMI4_SPI) += rmi_f11.o | ||
15 | obj-$(CONFIG_TOUCHSCREEN_SYN_RMI4_SPI) += rmi_f19.o | ||
16 | obj-$(CONFIG_TOUCHSCREEN_SYN_RMI4_SPI) += rmi_f34.o | ||
17 | obj-$(CONFIG_TOUCHSCREEN_SYN_RMI4_SPI) += rmi_f54.o | ||
18 | obj-$(CONFIG_TOUCHSCREEN_SYN_RMI4_SPI) += rmi_dev.o | ||
diff --git a/drivers/input/touchscreen/rmi4/rmi_bus.c b/drivers/input/touchscreen/rmi4/rmi_bus.c new file mode 100644 index 00000000000..6a269df4ff3 --- /dev/null +++ b/drivers/input/touchscreen/rmi4/rmi_bus.c | |||
@@ -0,0 +1,315 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Synaptics Incorporated | ||
3 | * Copyright (c) 2011 Unixphere | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/device.h> | ||
21 | #include <linux/pm.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/list.h> | ||
24 | #include <linux/rmi.h> | ||
25 | |||
26 | static struct rmi_function_list { | ||
27 | struct list_head list; | ||
28 | struct rmi_function_handler *fh; | ||
29 | } rmi_supported_functions; | ||
30 | |||
31 | static int rmi_bus_match(struct device *dev, struct device_driver *driver) | ||
32 | { | ||
33 | struct rmi_driver *rmi_driver; | ||
34 | struct rmi_device *rmi_dev; | ||
35 | struct rmi_device_platform_data *pdata; | ||
36 | |||
37 | pr_info("in function ____%s____ \n", __func__); | ||
38 | rmi_driver = to_rmi_driver(driver); | ||
39 | rmi_dev = to_rmi_device(dev); | ||
40 | pdata = to_rmi_platform_data(rmi_dev); | ||
41 | |||
42 | pr_info(" rmi_driver->driver.name = %s\n", rmi_driver->driver.name); | ||
43 | pr_info(" device:rmi_device = 0x%x \n", rmi_dev); | ||
44 | pr_info(" device:rmi_device:rmi_device_platform_data:driver_name = %s \n", pdata->driver_name); | ||
45 | pr_info(" rmi_device:driver = 0x%x \n", rmi_dev->driver); | ||
46 | |||
47 | if (!strcmp(pdata->driver_name, rmi_driver->driver.name)) { | ||
48 | rmi_dev->driver = rmi_driver; | ||
49 | pr_info(" names match, so now rmi_device:driver = 0x%x \n",rmi_dev->driver); | ||
50 | return 1; | ||
51 | } | ||
52 | pr_info(" names DO NOT match, so return nothing \n"); | ||
53 | |||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | #ifdef CONFIG_PM | ||
58 | static int rmi_bus_suspend(struct device *dev) | ||
59 | { | ||
60 | #ifdef GENERIC_SUBSYS_PM_OPS | ||
61 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | ||
62 | |||
63 | if (pm && pm->suspend) | ||
64 | return pm->suspend(dev); | ||
65 | #endif | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static int rmi_bus_resume(struct device *dev) | ||
71 | { | ||
72 | #ifdef GENERIC_SUBSYS_PM_OPS | ||
73 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | ||
74 | pr_info("in function ____%s____ \n", __func__); | ||
75 | |||
76 | if (pm && pm->resume) | ||
77 | return pm->resume(dev); | ||
78 | #endif | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | #endif | ||
83 | |||
84 | static int rmi_bus_probe(struct device *dev) | ||
85 | { | ||
86 | struct rmi_driver *driver; | ||
87 | struct rmi_device *rmi_dev = to_rmi_device(dev); | ||
88 | |||
89 | pr_info("in function ____%s____ \n", __func__); | ||
90 | driver = rmi_dev->driver; | ||
91 | if (driver && driver->probe) | ||
92 | return driver->probe(rmi_dev); | ||
93 | |||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | static int rmi_bus_remove(struct device *dev) | ||
98 | { | ||
99 | struct rmi_driver *driver; | ||
100 | struct rmi_device *rmi_dev = to_rmi_device(dev); | ||
101 | |||
102 | pr_info("in function ____%s____ \n", __func__); | ||
103 | driver = rmi_dev->driver; | ||
104 | if (driver && driver->remove) | ||
105 | return driver->remove(rmi_dev); | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static void rmi_bus_shutdown(struct device *dev) | ||
111 | { | ||
112 | struct rmi_driver *driver; | ||
113 | struct rmi_device *rmi_dev = to_rmi_device(dev); | ||
114 | |||
115 | driver = rmi_dev->driver; | ||
116 | if (driver && driver->shutdown) | ||
117 | driver->shutdown(rmi_dev); | ||
118 | } | ||
119 | |||
120 | static SIMPLE_DEV_PM_OPS(rmi_bus_pm_ops, | ||
121 | rmi_bus_suspend, rmi_bus_resume); | ||
122 | |||
123 | struct bus_type rmi_bus_type = { | ||
124 | .name = "rmi", | ||
125 | .match = rmi_bus_match, | ||
126 | .probe = rmi_bus_probe, | ||
127 | .remove = rmi_bus_remove, | ||
128 | .shutdown = rmi_bus_shutdown, | ||
129 | .pm = &rmi_bus_pm_ops | ||
130 | }; | ||
131 | |||
132 | int rmi_register_phys_device(struct rmi_phys_device *phys) | ||
133 | { | ||
134 | static int phys_device_num; | ||
135 | struct rmi_device_platform_data *pdata = phys->dev->platform_data; | ||
136 | struct rmi_device *rmi_dev; | ||
137 | |||
138 | pr_info("in function ____%s____ \n", __func__); | ||
139 | |||
140 | if (!pdata) { | ||
141 | dev_err(phys->dev, "no platform data!\n"); | ||
142 | return -EINVAL; | ||
143 | } | ||
144 | |||
145 | rmi_dev = kzalloc(sizeof(struct rmi_device), GFP_KERNEL); | ||
146 | if (!rmi_dev) | ||
147 | return -ENOMEM; | ||
148 | |||
149 | rmi_dev->phys = phys; | ||
150 | rmi_dev->dev.bus = &rmi_bus_type; | ||
151 | dev_set_name(&rmi_dev->dev, "sensor%02d", phys_device_num++); | ||
152 | |||
153 | phys->rmi_dev = rmi_dev; | ||
154 | pr_info(" registering physical device:\n"); | ||
155 | pr_info(" dev.init_name = \n", rmi_dev->dev.init_name); | ||
156 | pr_info(" dev.bus->name = \n", rmi_dev->dev.bus->name); | ||
157 | return device_register(&rmi_dev->dev); | ||
158 | } | ||
159 | EXPORT_SYMBOL(rmi_register_phys_device); | ||
160 | |||
161 | void rmi_unregister_phys_device(struct rmi_phys_device *phys) | ||
162 | { | ||
163 | struct rmi_device *rmi_dev = phys->rmi_dev; | ||
164 | pr_info("in function ____%s____ \n", __func__); | ||
165 | |||
166 | device_unregister(&rmi_dev->dev); | ||
167 | kfree(rmi_dev); | ||
168 | } | ||
169 | EXPORT_SYMBOL(rmi_unregister_phys_device); | ||
170 | |||
171 | int rmi_register_driver(struct rmi_driver *driver) | ||
172 | { | ||
173 | pr_info("in function ____%s____ \n", __func__); | ||
174 | driver->driver.bus = &rmi_bus_type; | ||
175 | return driver_register(&driver->driver); | ||
176 | } | ||
177 | EXPORT_SYMBOL(rmi_register_driver); | ||
178 | |||
179 | static int __rmi_driver_remove(struct device *dev, void *data) | ||
180 | { | ||
181 | struct rmi_driver *driver = data; | ||
182 | struct rmi_device *rmi_dev = to_rmi_device(dev); | ||
183 | |||
184 | if (rmi_dev->driver == driver) | ||
185 | rmi_dev->driver = NULL; | ||
186 | |||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | void rmi_unregister_driver(struct rmi_driver *driver) | ||
191 | { | ||
192 | bus_for_each_dev(&rmi_bus_type, NULL, driver, __rmi_driver_remove); | ||
193 | driver_unregister(&driver->driver); | ||
194 | } | ||
195 | EXPORT_SYMBOL(rmi_unregister_driver); | ||
196 | |||
197 | static int __rmi_bus_fh_add(struct device *dev, void *data) | ||
198 | { | ||
199 | struct rmi_driver *driver; | ||
200 | struct rmi_device *rmi_dev = to_rmi_device(dev); | ||
201 | pr_info("in function ____%s____ \n", __func__); | ||
202 | |||
203 | driver = rmi_dev->driver; | ||
204 | if (driver && driver->fh_add) | ||
205 | driver->fh_add(rmi_dev, data); | ||
206 | |||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | int rmi_register_function_driver(struct rmi_function_handler *fh) | ||
211 | { | ||
212 | struct rmi_function_list *entry; | ||
213 | struct rmi_function_handler *fh_dup; | ||
214 | |||
215 | fh_dup = rmi_get_function_handler(fh->func); | ||
216 | if (fh_dup) { | ||
217 | pr_err("%s: function f%.2x already registered!\n", __func__, | ||
218 | fh->func); | ||
219 | return -EINVAL; | ||
220 | } | ||
221 | |||
222 | entry = kzalloc(sizeof(struct rmi_function_list), GFP_KERNEL); | ||
223 | if (!entry) | ||
224 | return -ENOMEM; | ||
225 | |||
226 | entry->fh = fh; | ||
227 | list_add_tail(&entry->list, &rmi_supported_functions.list); | ||
228 | |||
229 | /* notify devices of the new function handler */ | ||
230 | bus_for_each_dev(&rmi_bus_type, NULL, fh, __rmi_bus_fh_add); | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | EXPORT_SYMBOL(rmi_register_function_driver); | ||
235 | |||
236 | static int __rmi_bus_fh_remove(struct device *dev, void *data) | ||
237 | { | ||
238 | struct rmi_driver *driver; | ||
239 | struct rmi_device *rmi_dev = to_rmi_device(dev); | ||
240 | |||
241 | pr_info("in function ____%s____ \n", __func__); | ||
242 | driver = rmi_dev->driver; | ||
243 | if (driver && driver->fh_remove) | ||
244 | driver->fh_remove(rmi_dev, data); | ||
245 | |||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | void rmi_unregister_function_driver(struct rmi_function_handler *fh) | ||
250 | { | ||
251 | struct rmi_function_list *entry, *n; | ||
252 | pr_info("in function ____%s____ \n", __func__); | ||
253 | |||
254 | /* notify devices of the removal of the function handler */ | ||
255 | bus_for_each_dev(&rmi_bus_type, NULL, fh, __rmi_bus_fh_remove); | ||
256 | |||
257 | list_for_each_entry_safe(entry, n, &rmi_supported_functions.list, list) | ||
258 | if (entry->fh->func == fh->func) { | ||
259 | list_del(&entry->list); | ||
260 | kfree(entry); | ||
261 | } | ||
262 | } | ||
263 | EXPORT_SYMBOL(rmi_unregister_function_driver); | ||
264 | |||
265 | struct rmi_function_handler *rmi_get_function_handler(int id) | ||
266 | { | ||
267 | struct rmi_function_list *entry; | ||
268 | pr_info("in function ____%s____ \n", __func__); | ||
269 | |||
270 | list_for_each_entry(entry, &rmi_supported_functions.list, list) | ||
271 | if (entry->fh->func == id) | ||
272 | return entry->fh; | ||
273 | |||
274 | return NULL; | ||
275 | } | ||
276 | EXPORT_SYMBOL(rmi_get_function_handler); | ||
277 | |||
278 | static int __init rmi_bus_init(void) | ||
279 | { | ||
280 | int error; | ||
281 | |||
282 | pr_info("in function ____%s____ \n", __func__); | ||
283 | INIT_LIST_HEAD(&rmi_supported_functions.list); | ||
284 | |||
285 | error = bus_register(&rmi_bus_type); | ||
286 | if (error < 0) { | ||
287 | pr_err("%s: error registering the RMI bus: %d\n", __func__, | ||
288 | error); | ||
289 | return error; | ||
290 | } | ||
291 | pr_info("%s: successfully registered RMI bus.\n", __func__); | ||
292 | |||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | static void __exit rmi_bus_exit(void) | ||
297 | { | ||
298 | struct rmi_function_list *entry, *n; | ||
299 | pr_info("in function ____%s____ \n", __func__); | ||
300 | |||
301 | list_for_each_entry_safe(entry, n, &rmi_supported_functions.list, | ||
302 | list) { | ||
303 | list_del(&entry->list); | ||
304 | kfree(entry); | ||
305 | } | ||
306 | |||
307 | bus_unregister(&rmi_bus_type); | ||
308 | } | ||
309 | |||
310 | module_init(rmi_bus_init); | ||
311 | module_exit(rmi_bus_exit); | ||
312 | |||
313 | MODULE_AUTHOR("Eric Andersson <eric.andersson@unixphere.com>"); | ||
314 | MODULE_DESCRIPTION("RMI bus"); | ||
315 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/rmi4/rmi_dev.c b/drivers/input/touchscreen/rmi4/rmi_dev.c new file mode 100644 index 00000000000..fa21ef9b20f --- /dev/null +++ b/drivers/input/touchscreen/rmi4/rmi_dev.c | |||
@@ -0,0 +1,428 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Synaptics Incorporated | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
17 | */ | ||
18 | |||
19 | #include <linux/fs.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/uaccess.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/input.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/syscalls.h> | ||
26 | |||
27 | #include <linux/rmi.h> | ||
28 | #include "rmi_driver.h" | ||
29 | |||
30 | #define CHAR_DEVICE_NAME "rmi" | ||
31 | |||
32 | #define REG_ADDR_LIMIT 0xFFFF | ||
33 | |||
34 | /*store dynamically allocated major number of char device*/ | ||
35 | static int rmi_char_dev_major_num; | ||
36 | |||
37 | |||
38 | /* file operations for RMI char device */ | ||
39 | |||
40 | /* | ||
41 | * rmi_char_dev_llseek: - use to setup register address | ||
42 | * | ||
43 | * @filp: file structure for seek | ||
44 | * @off: offset | ||
45 | * if whence == SEEK_SET, | ||
46 | * high 16 bits: page address | ||
47 | * low 16 bits: register address | ||
48 | * | ||
49 | * if whence == SEEK_CUR, | ||
50 | * offset from current position | ||
51 | * | ||
52 | * if whence == SEEK_END, | ||
53 | * offset from END(0xFFFF) | ||
54 | * | ||
55 | * @whence: SEEK_SET , SEEK_CUR or SEEK_END | ||
56 | */ | ||
57 | static loff_t rmi_char_dev_llseek(struct file *filp, loff_t off, int whence) | ||
58 | { | ||
59 | loff_t newpos; | ||
60 | struct rmi_char_dev *my_char_dev = filp->private_data; | ||
61 | |||
62 | if (IS_ERR(my_char_dev)) { | ||
63 | pr_err("%s: pointer of char device is invalid", __func__); | ||
64 | return -EBADF; | ||
65 | } | ||
66 | |||
67 | mutex_lock(&(my_char_dev->mutex_file_op)); | ||
68 | |||
69 | switch (whence) { | ||
70 | case SEEK_SET: | ||
71 | newpos = off; | ||
72 | break; | ||
73 | |||
74 | case SEEK_CUR: | ||
75 | newpos = filp->f_pos + off; | ||
76 | break; | ||
77 | |||
78 | case SEEK_END: | ||
79 | newpos = REG_ADDR_LIMIT + off; | ||
80 | break; | ||
81 | |||
82 | default: /* can't happen */ | ||
83 | newpos = -EINVAL; | ||
84 | goto clean_up; | ||
85 | } | ||
86 | |||
87 | if (newpos < 0 || newpos > REG_ADDR_LIMIT) { | ||
88 | dev_err(my_char_dev->phys->dev, "newpos 0x%04x is invalid.\n", | ||
89 | (unsigned int)newpos); | ||
90 | newpos = -EINVAL; | ||
91 | goto clean_up; | ||
92 | } | ||
93 | |||
94 | filp->f_pos = newpos; | ||
95 | |||
96 | clean_up: | ||
97 | mutex_unlock(&(my_char_dev->mutex_file_op)); | ||
98 | return newpos; | ||
99 | } | ||
100 | |||
101 | /* | ||
102 | * rmi_char_dev_read: - use to read data from RMI stream | ||
103 | * | ||
104 | * @filp: file structure for read | ||
105 | * @buf: user-level buffer pointer | ||
106 | * | ||
107 | * @count: number of byte read | ||
108 | * @f_pos: offset (starting register address) | ||
109 | * | ||
110 | * @return number of bytes read into user buffer (buf) if succeeds | ||
111 | * negative number if error occurs. | ||
112 | */ | ||
113 | static ssize_t rmi_char_dev_read(struct file *filp, char __user *buf, | ||
114 | size_t count, loff_t *f_pos) | ||
115 | { | ||
116 | struct rmi_char_dev *my_char_dev = filp->private_data; | ||
117 | ssize_t ret_value = 0; | ||
118 | unsigned char tmpbuf[count+1]; | ||
119 | struct rmi_phys_device *phys; | ||
120 | |||
121 | /* limit offset to REG_ADDR_LIMIT-1 */ | ||
122 | if (count > (REG_ADDR_LIMIT - *f_pos)) | ||
123 | count = REG_ADDR_LIMIT - *f_pos; | ||
124 | |||
125 | if (count == 0) | ||
126 | return 0; | ||
127 | |||
128 | if (IS_ERR(my_char_dev)) { | ||
129 | pr_err("%s: pointer of char device is invalid", __func__); | ||
130 | ret_value = -EBADF; | ||
131 | return ret_value; | ||
132 | } | ||
133 | |||
134 | mutex_lock(&(my_char_dev->mutex_file_op)); | ||
135 | |||
136 | phys = my_char_dev->phys; | ||
137 | /* | ||
138 | * just let it go through , because we do not know the register is FIFO | ||
139 | * register or not | ||
140 | */ | ||
141 | |||
142 | ret_value = phys->read_block(phys, *f_pos, tmpbuf, count); | ||
143 | |||
144 | if (ret_value < 0) | ||
145 | goto clean_up; | ||
146 | else | ||
147 | *f_pos += ret_value; | ||
148 | |||
149 | if (copy_to_user(buf, tmpbuf, count)) | ||
150 | ret_value = -EFAULT; | ||
151 | |||
152 | clean_up: | ||
153 | |||
154 | mutex_unlock(&(my_char_dev->mutex_file_op)); | ||
155 | |||
156 | return ret_value; | ||
157 | } | ||
158 | |||
159 | /* | ||
160 | * rmi_char_dev_write: - use to write data into RMI stream | ||
161 | * | ||
162 | * @filep : file structure for write | ||
163 | * @buf: user-level buffer pointer contains data to be written | ||
164 | * @count: number of byte be be written | ||
165 | * @f_pos: offset (starting register address) | ||
166 | * | ||
167 | * @return number of bytes written from user buffer (buf) if succeeds | ||
168 | * negative number if error occurs. | ||
169 | */ | ||
170 | static ssize_t rmi_char_dev_write(struct file *filp, const char __user *buf, | ||
171 | size_t count, loff_t *f_pos) | ||
172 | { | ||
173 | struct rmi_char_dev *my_char_dev = filp->private_data; | ||
174 | ssize_t ret_value = 0; | ||
175 | unsigned char tmpbuf[count+1]; | ||
176 | struct rmi_phys_device *phys; | ||
177 | |||
178 | /* limit offset to REG_ADDR_LIMIT-1 */ | ||
179 | if (count > (REG_ADDR_LIMIT - *f_pos)) | ||
180 | count = REG_ADDR_LIMIT - *f_pos; | ||
181 | |||
182 | if (count == 0) | ||
183 | return 0; | ||
184 | |||
185 | if (IS_ERR(my_char_dev)) { | ||
186 | pr_err("%s: pointer of char device is invalid", __func__); | ||
187 | ret_value = -EBADF; | ||
188 | return ret_value; | ||
189 | } | ||
190 | |||
191 | if (copy_from_user(tmpbuf, buf, count)) { | ||
192 | ret_value = -EFAULT; | ||
193 | return ret_value; | ||
194 | } | ||
195 | |||
196 | mutex_lock(&(my_char_dev->mutex_file_op)); | ||
197 | |||
198 | phys = my_char_dev->phys; | ||
199 | /* | ||
200 | * just let it go through , because we do not know the register is FIFO | ||
201 | * register or not | ||
202 | */ | ||
203 | |||
204 | ret_value = phys->write_block(phys, *f_pos, tmpbuf, count); | ||
205 | |||
206 | if (ret_value >= 0) | ||
207 | *f_pos += count; | ||
208 | |||
209 | mutex_unlock(&(my_char_dev->mutex_file_op)); | ||
210 | |||
211 | return ret_value; | ||
212 | } | ||
213 | |||
214 | /* | ||
215 | * rmi_char_dev_open: - get a new handle for from RMI stream | ||
216 | * @inp : inode struture | ||
217 | * @filp: file structure for read/write | ||
218 | * | ||
219 | * @return 0 if succeeds | ||
220 | */ | ||
221 | static int rmi_char_dev_open(struct inode *inp, struct file *filp) | ||
222 | { | ||
223 | /* store the device pointer to file structure */ | ||
224 | struct rmi_char_dev *my_dev = container_of(inp->i_cdev, | ||
225 | struct rmi_char_dev, main_dev); | ||
226 | struct rmi_phys_device *phys = my_dev->phys; | ||
227 | int ret_value = 0; | ||
228 | |||
229 | filp->private_data = my_dev; | ||
230 | |||
231 | if (!phys) | ||
232 | return -EACCES; | ||
233 | |||
234 | mutex_lock(&(my_dev->mutex_file_op)); | ||
235 | if (my_dev->ref_count < 1) | ||
236 | my_dev->ref_count++; | ||
237 | else | ||
238 | ret_value = -EACCES; | ||
239 | |||
240 | mutex_unlock(&(my_dev->mutex_file_op)); | ||
241 | |||
242 | return ret_value; | ||
243 | } | ||
244 | |||
245 | /* | ||
246 | * rmi_char_dev_release: - release an existing handle | ||
247 | * @inp: inode structure | ||
248 | * @filp: file structure for read/write | ||
249 | * | ||
250 | * @return 0 if succeeds | ||
251 | */ | ||
252 | static int rmi_char_dev_release(struct inode *inp, struct file *filp) | ||
253 | { | ||
254 | struct rmi_char_dev *my_dev = container_of(inp->i_cdev, | ||
255 | struct rmi_char_dev, main_dev); | ||
256 | struct rmi_phys_device *phys = my_dev->phys; | ||
257 | |||
258 | if (!phys) | ||
259 | return -EACCES; | ||
260 | |||
261 | mutex_lock(&(my_dev->mutex_file_op)); | ||
262 | |||
263 | my_dev->ref_count--; | ||
264 | if (my_dev->ref_count < 0) | ||
265 | my_dev->ref_count = 0; | ||
266 | |||
267 | mutex_unlock(&(my_dev->mutex_file_op)); | ||
268 | |||
269 | return 0; | ||
270 | } | ||
271 | |||
272 | static const struct file_operations rmi_char_dev_fops = { | ||
273 | .owner = THIS_MODULE, | ||
274 | .llseek = rmi_char_dev_llseek, | ||
275 | .read = rmi_char_dev_read, | ||
276 | .write = rmi_char_dev_write, | ||
277 | .open = rmi_char_dev_open, | ||
278 | .release = rmi_char_dev_release, | ||
279 | }; | ||
280 | |||
281 | /* | ||
282 | * rmi_char_dev_clean_up - release memory or unregister driver | ||
283 | * @rmi_char_dev: rmi_char_dev structure | ||
284 | * | ||
285 | */ | ||
286 | static void rmi_char_dev_clean_up(struct rmi_char_dev *char_dev, | ||
287 | struct class *char_device_class) | ||
288 | { | ||
289 | dev_t devno; | ||
290 | |||
291 | /* Get rid of our char dev entries */ | ||
292 | if (char_dev) { | ||
293 | devno = char_dev->main_dev.dev; | ||
294 | |||
295 | cdev_del(&char_dev->main_dev); | ||
296 | kfree(char_dev); | ||
297 | |||
298 | if (char_device_class) { | ||
299 | device_destroy(char_device_class, devno); | ||
300 | class_unregister(char_device_class); | ||
301 | class_destroy(char_device_class); | ||
302 | } | ||
303 | |||
304 | /* cleanup_module is never called if registering failed */ | ||
305 | unregister_chrdev_region(devno, 1); | ||
306 | pr_debug("%s: rmi_char_dev is removed\n", __func__); | ||
307 | } | ||
308 | } | ||
309 | |||
310 | /* | ||
311 | * rmi_char_devnode - return device permission | ||
312 | * | ||
313 | * @dev: char device structure | ||
314 | * @mode: file permission | ||
315 | * | ||
316 | */ | ||
317 | static char *rmi_char_devnode(struct device *dev, mode_t *mode) | ||
318 | { | ||
319 | if (!mode) | ||
320 | return NULL; | ||
321 | /* rmi** */ | ||
322 | /**mode = 0666*/ | ||
323 | *mode = (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); | ||
324 | |||
325 | return kasprintf(GFP_KERNEL, "rmi/%s", dev_name(dev)); | ||
326 | } | ||
327 | |||
328 | /* | ||
329 | * rmi_char_dev_register - register char device (called from up-level) | ||
330 | * | ||
331 | * @phy: a pointer to an rmi_phys_devices structure | ||
332 | * | ||
333 | * @return: zero if suceeds | ||
334 | */ | ||
335 | int rmi_char_dev_register(struct rmi_phys_device *phys) | ||
336 | { | ||
337 | struct rmi_char_dev *char_dev; | ||
338 | dev_t dev_no; | ||
339 | int err; | ||
340 | int result; | ||
341 | struct device *device_ptr; | ||
342 | |||
343 | if (rmi_char_dev_major_num) { | ||
344 | dev_no = MKDEV(rmi_char_dev_major_num, 0); | ||
345 | result = register_chrdev_region(dev_no, 1, CHAR_DEVICE_NAME); | ||
346 | } else { | ||
347 | result = alloc_chrdev_region(&dev_no, 0, 1, CHAR_DEVICE_NAME); | ||
348 | /* let kernel allocate a major for us */ | ||
349 | rmi_char_dev_major_num = MAJOR(dev_no); | ||
350 | dev_info(phys->dev, "Major number of rmi_char_dev: %d\n", | ||
351 | rmi_char_dev_major_num); | ||
352 | } | ||
353 | if (result < 0) | ||
354 | return result; | ||
355 | |||
356 | char_dev = kzalloc(sizeof(struct rmi_char_dev), GFP_KERNEL); | ||
357 | if (!char_dev) { | ||
358 | dev_err(phys->dev, "Failed to allocate rmi_char_dev.\n"); | ||
359 | /* unregister the char device region */ | ||
360 | __unregister_chrdev(rmi_char_dev_major_num, MINOR(dev_no), 1, | ||
361 | CHAR_DEVICE_NAME); | ||
362 | return -ENOMEM; | ||
363 | } | ||
364 | |||
365 | mutex_init(&char_dev->mutex_file_op); | ||
366 | |||
367 | phys->char_dev = char_dev; | ||
368 | char_dev->phys = phys; | ||
369 | |||
370 | cdev_init(&char_dev->main_dev, &rmi_char_dev_fops); | ||
371 | |||
372 | err = cdev_add(&char_dev->main_dev, dev_no, 1); | ||
373 | if (err) { | ||
374 | dev_err(phys->dev, "Error %d adding rmi_char_dev.\n", err); | ||
375 | rmi_char_dev_clean_up(phys->char_dev, | ||
376 | phys->rmi_char_device_class); | ||
377 | return err; | ||
378 | } | ||
379 | |||
380 | /* create device node */ | ||
381 | phys->rmi_char_device_class = | ||
382 | class_create(THIS_MODULE, CHAR_DEVICE_NAME); | ||
383 | |||
384 | if (IS_ERR(phys->rmi_char_device_class)) { | ||
385 | dev_err(phys->dev, "Failed to create /dev/%s.\n", | ||
386 | CHAR_DEVICE_NAME); | ||
387 | rmi_char_dev_clean_up(phys->char_dev, | ||
388 | phys->rmi_char_device_class); | ||
389 | return -ENODEV; | ||
390 | } | ||
391 | /* setup permission */ | ||
392 | phys->rmi_char_device_class->devnode = rmi_char_devnode; | ||
393 | |||
394 | /* class creation */ | ||
395 | device_ptr = device_create( | ||
396 | phys->rmi_char_device_class, | ||
397 | NULL, dev_no, NULL, | ||
398 | CHAR_DEVICE_NAME"%d", | ||
399 | MINOR(dev_no)); | ||
400 | |||
401 | if (IS_ERR(device_ptr)) { | ||
402 | dev_err(phys->dev, "Failed to create rmi device.\n"); | ||
403 | rmi_char_dev_clean_up(phys->char_dev, | ||
404 | phys->rmi_char_device_class); | ||
405 | return -ENODEV; | ||
406 | } | ||
407 | |||
408 | return 0; | ||
409 | } | ||
410 | EXPORT_SYMBOL(rmi_char_dev_register); | ||
411 | |||
412 | /* rmi_char_dev_unregister - unregister char device (called from up-level) | ||
413 | * | ||
414 | * @phys: pointer to an rmi_phys_device structure | ||
415 | */ | ||
416 | |||
417 | void rmi_char_dev_unregister(struct rmi_phys_device *phys) | ||
418 | { | ||
419 | /* clean up */ | ||
420 | if (phys) | ||
421 | rmi_char_dev_clean_up(phys->char_dev, | ||
422 | phys->rmi_char_device_class); | ||
423 | } | ||
424 | EXPORT_SYMBOL(rmi_char_dev_unregister); | ||
425 | |||
426 | MODULE_AUTHOR("Synaptics, Inc."); | ||
427 | MODULE_DESCRIPTION("RMI4 Char Device"); | ||
428 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/rmi4/rmi_driver.c b/drivers/input/touchscreen/rmi4/rmi_driver.c new file mode 100644 index 00000000000..6aeb3b93b2c --- /dev/null +++ b/drivers/input/touchscreen/rmi4/rmi_driver.c | |||
@@ -0,0 +1,1354 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Synaptics Incorporated | ||
3 | * Copyright (c) 2011 Unixphere | ||
4 | * | ||
5 | * This driver adds support for generic RMI4 devices from Synpatics. It | ||
6 | * implements the mandatory f01 RMI register and depends on the presence of | ||
7 | * other required RMI functions. | ||
8 | * | ||
9 | * The RMI4 specification can be found here (URL split after files/ for | ||
10 | * style reasons): | ||
11 | * http://www.synaptics.com/sites/default/files/ | ||
12 | * 511-000136-01-Rev-E-RMI4%20Intrfacing%20Guide.pdf | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation; either version 2 of the License, or | ||
17 | * (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | */ | ||
28 | |||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/device.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/device.h> | ||
34 | #include <linux/slab.h> | ||
35 | #include <linux/list.h> | ||
36 | #include <linux/pm.h> | ||
37 | #include <linux/gpio.h> | ||
38 | #include <linux/workqueue.h> | ||
39 | #include <linux/rmi.h> | ||
40 | #include "rmi_driver.h" | ||
41 | |||
42 | #define DELAY_DEBUG 0 | ||
43 | #define REGISTER_DEBUG 0 | ||
44 | |||
45 | #define PDT_END_SCAN_LOCATION 0x0005 | ||
46 | #define PDT_PROPERTIES_LOCATION 0x00EF | ||
47 | #define BSR_LOCATION 0x00FE | ||
48 | #define HAS_BSR_MASK 0x20 | ||
49 | #define HAS_NONSTANDARD_PDT_MASK 0x40 | ||
50 | #define RMI4_END_OF_PDT(id) ((id) == 0x00 || (id) == 0xff) | ||
51 | #define RMI4_MAX_PAGE 0xff | ||
52 | #define RMI4_PAGE_SIZE 0x100 | ||
53 | |||
54 | #define RMI_DEVICE_RESET_CMD 0x01 | ||
55 | #define INITIAL_RESET_WAIT_MS 20 | ||
56 | |||
57 | #ifdef CONFIG_HAS_EARLYSUSPEND | ||
58 | static void rmi_driver_early_suspend(struct early_suspend *h); | ||
59 | static void rmi_driver_late_resume(struct early_suspend *h); | ||
60 | #endif | ||
61 | |||
62 | |||
63 | /* sysfs files for attributes for driver values. */ | ||
64 | static ssize_t rmi_driver_hasbsr_show(struct device *dev, | ||
65 | struct device_attribute *attr, char *buf); | ||
66 | |||
67 | static ssize_t rmi_driver_bsr_show(struct device *dev, | ||
68 | struct device_attribute *attr, char *buf); | ||
69 | |||
70 | static ssize_t rmi_driver_bsr_store(struct device *dev, | ||
71 | struct device_attribute *attr, | ||
72 | const char *buf, size_t count); | ||
73 | |||
74 | static ssize_t rmi_driver_enabled_show(struct device *dev, | ||
75 | struct device_attribute *attr, | ||
76 | char *buf); | ||
77 | |||
78 | static ssize_t rmi_driver_enabled_store(struct device *dev, | ||
79 | struct device_attribute *attr, | ||
80 | const char *buf, size_t count); | ||
81 | |||
82 | static ssize_t rmi_driver_phys_show(struct device *dev, | ||
83 | struct device_attribute *attr, | ||
84 | char *buf); | ||
85 | |||
86 | static ssize_t rmi_driver_version_show(struct device *dev, | ||
87 | struct device_attribute *attr, | ||
88 | char *buf); | ||
89 | |||
90 | #if REGISTER_DEBUG | ||
91 | static ssize_t rmi_driver_reg_store(struct device *dev, | ||
92 | struct device_attribute *attr, | ||
93 | const char *buf, size_t count); | ||
94 | #endif | ||
95 | |||
96 | #if DELAY_DEBUG | ||
97 | static ssize_t rmi_delay_show(struct device *dev, | ||
98 | struct device_attribute *attr, | ||
99 | char *buf); | ||
100 | |||
101 | static ssize_t rmi_delay_store(struct device *dev, | ||
102 | struct device_attribute *attr, | ||
103 | const char *buf, size_t count); | ||
104 | #endif | ||
105 | |||
106 | static struct device_attribute attrs[] = { | ||
107 | __ATTR(hasbsr, RMI_RO_ATTR, | ||
108 | rmi_driver_hasbsr_show, rmi_store_error), | ||
109 | __ATTR(bsr, RMI_RW_ATTR, | ||
110 | rmi_driver_bsr_show, rmi_driver_bsr_store), | ||
111 | __ATTR(enabled, RMI_RW_ATTR, | ||
112 | rmi_driver_enabled_show, rmi_driver_enabled_store), | ||
113 | __ATTR(phys, RMI_RO_ATTR, | ||
114 | rmi_driver_phys_show, rmi_store_error), | ||
115 | #if REGISTER_DEBUG | ||
116 | __ATTR(reg, RMI_WO_ATTR, | ||
117 | rmi_show_error, rmi_driver_reg_store), | ||
118 | #endif | ||
119 | #if DELAY_DEBUG | ||
120 | __ATTR(delay, RMI_RW_ATTR, | ||
121 | rmi_delay_show, rmi_delay_store), | ||
122 | #endif | ||
123 | __ATTR(version, RMI_RO_ATTR, | ||
124 | rmi_driver_version_show, rmi_store_error), | ||
125 | }; | ||
126 | |||
127 | |||
128 | /* | ||
129 | ** ONLY needed for POLLING mode of the driver | ||
130 | */ | ||
131 | struct rmi_device *polled_synaptics_rmi_device = NULL; | ||
132 | EXPORT_SYMBOL(polled_synaptics_rmi_device); | ||
133 | |||
134 | /* Useful helper functions for u8* */ | ||
135 | |||
136 | void u8_set_bit(u8 *target, int pos) | ||
137 | { | ||
138 | target[pos/8] |= 1<<pos%8; | ||
139 | } | ||
140 | |||
141 | void u8_clear_bit(u8 *target, int pos) | ||
142 | { | ||
143 | target[pos/8] &= ~(1<<pos%8); | ||
144 | } | ||
145 | |||
146 | bool u8_is_set(u8 *target, int pos) | ||
147 | { | ||
148 | return target[pos/8] & 1<<pos%8; | ||
149 | } | ||
150 | |||
151 | bool u8_is_any_set(u8 *target, int size) | ||
152 | { | ||
153 | int i; | ||
154 | for (i = 0; i < size; i++) { | ||
155 | if (target[i]) | ||
156 | return true; | ||
157 | } | ||
158 | return false; | ||
159 | } | ||
160 | |||
161 | void u8_or(u8 *dest, u8 *target1, u8 *target2, int size) | ||
162 | { | ||
163 | int i; | ||
164 | for (i = 0; i < size; i++) | ||
165 | dest[i] = target1[i] | target2[i]; | ||
166 | } | ||
167 | |||
168 | void u8_and(u8 *dest, u8 *target1, u8 *target2, int size) | ||
169 | { | ||
170 | int i; | ||
171 | for (i = 0; i < size; i++) | ||
172 | dest[i] = target1[i] & target2[i]; | ||
173 | } | ||
174 | |||
175 | /* Helper fn to convert a byte array representing a short in the RMI | ||
176 | * endian-ness to a short in the native processor's specific endianness. | ||
177 | * We don't use ntohs/htons here because, well, we're not dealing with | ||
178 | * a pair of shorts. And casting dest to short* wouldn't work, because | ||
179 | * that would imply knowing the byte order of short in the first place. | ||
180 | */ | ||
181 | void batohs(unsigned short *dest, unsigned char *src) | ||
182 | { | ||
183 | *dest = src[1] * 0x100 + src[0]; | ||
184 | } | ||
185 | |||
186 | /* Helper function to convert a short (in host processor endianess) to | ||
187 | * a byte array in the RMI endianess for shorts. See above comment for | ||
188 | * why we dont us htons or something like that. | ||
189 | */ | ||
190 | void hstoba(unsigned char *dest, unsigned short src) | ||
191 | { | ||
192 | dest[0] = src % 0x100; | ||
193 | dest[1] = src / 0x100; | ||
194 | } | ||
195 | |||
196 | static bool has_bsr(struct rmi_driver_data *data) | ||
197 | { | ||
198 | return (data->pdt_props & HAS_BSR_MASK) != 0; | ||
199 | } | ||
200 | |||
201 | /* Utility routine to set bits in a register. */ | ||
202 | int rmi_set_bits(struct rmi_device *rmi_dev, unsigned short address, | ||
203 | unsigned char bits) | ||
204 | { | ||
205 | unsigned char reg_contents; | ||
206 | int retval; | ||
207 | |||
208 | retval = rmi_read_block(rmi_dev, address, ®_contents, 1); | ||
209 | if (retval) | ||
210 | return retval; | ||
211 | reg_contents = reg_contents | bits; | ||
212 | retval = rmi_write_block(rmi_dev, address, ®_contents, 1); | ||
213 | if (retval == 1) | ||
214 | return 0; | ||
215 | else if (retval == 0) | ||
216 | return -EIO; | ||
217 | return retval; | ||
218 | } | ||
219 | EXPORT_SYMBOL(rmi_set_bits); | ||
220 | |||
221 | /* Utility routine to clear bits in a register. */ | ||
222 | int rmi_clear_bits(struct rmi_device *rmi_dev, unsigned short address, | ||
223 | unsigned char bits) | ||
224 | { | ||
225 | unsigned char reg_contents; | ||
226 | int retval; | ||
227 | |||
228 | retval = rmi_read_block(rmi_dev, address, ®_contents, 1); | ||
229 | if (retval) | ||
230 | return retval; | ||
231 | reg_contents = reg_contents & ~bits; | ||
232 | retval = rmi_write_block(rmi_dev, address, ®_contents, 1); | ||
233 | if (retval == 1) | ||
234 | return 0; | ||
235 | else if (retval == 0) | ||
236 | return -EIO; | ||
237 | return retval; | ||
238 | } | ||
239 | EXPORT_SYMBOL(rmi_clear_bits); | ||
240 | |||
241 | static void rmi_free_function_list(struct rmi_device *rmi_dev) | ||
242 | { | ||
243 | struct rmi_function_container *entry, *n; | ||
244 | struct rmi_driver_data *data = rmi_get_driverdata(rmi_dev); | ||
245 | |||
246 | list_for_each_entry_safe(entry, n, &data->rmi_functions.list, list) { | ||
247 | kfree(entry->irq_mask); | ||
248 | list_del(&entry->list); | ||
249 | } | ||
250 | } | ||
251 | |||
252 | static int init_one_function(struct rmi_device *rmi_dev, | ||
253 | struct rmi_function_container *fc) | ||
254 | { | ||
255 | int retval; | ||
256 | |||
257 | dev_info(&rmi_dev->dev, "Initializing F%02X.\n", | ||
258 | fc->fd.function_number); | ||
259 | dev_dbg(&rmi_dev->dev, "Initializing F%02X.\n", | ||
260 | fc->fd.function_number); | ||
261 | |||
262 | if (!fc->fh) { | ||
263 | struct rmi_function_handler *fh = | ||
264 | rmi_get_function_handler(fc->fd.function_number); | ||
265 | if (!fh) { | ||
266 | dev_dbg(&rmi_dev->dev, "No handler for F%02X.\n", | ||
267 | fc->fd.function_number); | ||
268 | return 0; | ||
269 | } | ||
270 | fc->fh = fh; | ||
271 | } | ||
272 | |||
273 | if (!fc->fh->init) | ||
274 | return 0; | ||
275 | |||
276 | dev_set_name(&(fc->dev), "fn%02x", fc->fd.function_number); | ||
277 | |||
278 | fc->dev.parent = &rmi_dev->dev; | ||
279 | |||
280 | retval = device_register(&fc->dev); | ||
281 | if (retval) { | ||
282 | dev_err(&rmi_dev->dev, "Failed device_register for F%02X.\n", | ||
283 | fc->fd.function_number); | ||
284 | return retval; | ||
285 | } | ||
286 | |||
287 | retval = fc->fh->init(fc); | ||
288 | if (retval < 0) { | ||
289 | dev_err(&rmi_dev->dev, "Failed to initialize function F%02x\n", | ||
290 | fc->fd.function_number); | ||
291 | goto error_exit; | ||
292 | } | ||
293 | |||
294 | return 0; | ||
295 | |||
296 | error_exit: | ||
297 | device_unregister(&fc->dev); | ||
298 | return retval; | ||
299 | } | ||
300 | |||
301 | static void rmi_driver_fh_add(struct rmi_device *rmi_dev, | ||
302 | struct rmi_function_handler *fh) | ||
303 | { | ||
304 | struct rmi_function_container *entry; | ||
305 | struct rmi_driver_data *data = rmi_get_driverdata(rmi_dev); | ||
306 | |||
307 | if (fh->func == 0x01) | ||
308 | data->f01_container->fh = fh; | ||
309 | else { | ||
310 | list_for_each_entry(entry, &data->rmi_functions.list, list) | ||
311 | if (entry->fd.function_number == fh->func) { | ||
312 | entry->fh = fh; | ||
313 | init_one_function(rmi_dev, entry); | ||
314 | } | ||
315 | } | ||
316 | |||
317 | } | ||
318 | |||
319 | static void rmi_driver_fh_remove(struct rmi_device *rmi_dev, | ||
320 | struct rmi_function_handler *fh) | ||
321 | { | ||
322 | struct rmi_function_container *entry; | ||
323 | struct rmi_driver_data *data = rmi_get_driverdata(rmi_dev); | ||
324 | |||
325 | list_for_each_entry(entry, &data->rmi_functions.list, list) | ||
326 | if (entry->fd.function_number == fh->func) { | ||
327 | if (fh->remove) | ||
328 | fh->remove(entry); | ||
329 | |||
330 | entry->fh = NULL; | ||
331 | } | ||
332 | } | ||
333 | |||
334 | static void construct_mask(u8 *mask, int num, int pos) | ||
335 | { | ||
336 | int i; | ||
337 | |||
338 | for (i = 0; i < num; i++) | ||
339 | u8_set_bit(mask, pos+i); | ||
340 | } | ||
341 | |||
342 | static int process_interrupt_requests(struct rmi_device *rmi_dev) | ||
343 | { | ||
344 | struct rmi_driver_data *data = rmi_get_driverdata(rmi_dev); | ||
345 | struct device *dev = &rmi_dev->dev; | ||
346 | struct rmi_function_container *entry; | ||
347 | u8 irq_status[data->num_of_irq_regs]; | ||
348 | u8 irq_bits[data->num_of_irq_regs]; | ||
349 | int error; | ||
350 | |||
351 | error = rmi_read_block(rmi_dev, | ||
352 | data->f01_container->fd.data_base_addr + 1, | ||
353 | irq_status, data->num_of_irq_regs); | ||
354 | if (error < 0) { | ||
355 | dev_err(dev, "%s: failed to read irqs.", __func__); | ||
356 | return error; | ||
357 | } | ||
358 | /* Device control (F01) is handled before anything else. */ | ||
359 | u8_and(irq_bits, irq_status, data->f01_container->irq_mask, | ||
360 | data->num_of_irq_regs); | ||
361 | if (u8_is_any_set(irq_bits, data->num_of_irq_regs)) | ||
362 | data->f01_container->fh->attention( | ||
363 | data->f01_container, irq_bits); | ||
364 | |||
365 | //dev_info(dev, " irq_status = 0x%2x data->current_irq_mask = 0x%2x data->num_of_irq_regs = %d\n", | ||
366 | // irq_status[0], data->current_irq_mask[0], data->num_of_irq_regs ); | ||
367 | |||
368 | |||
369 | u8_and(irq_status, irq_status, data->current_irq_mask, | ||
370 | data->num_of_irq_regs); | ||
371 | |||
372 | /* At this point, irq_status has all bits that are set in the | ||
373 | * interrupt status register and are enabled. | ||
374 | */ | ||
375 | |||
376 | list_for_each_entry(entry, &data->rmi_functions.list, list){ | ||
377 | if (entry->irq_mask && entry->fh && entry->fh->attention) { | ||
378 | |||
379 | u8_and(irq_bits, irq_status, entry->irq_mask, | ||
380 | data->num_of_irq_regs); | ||
381 | if (u8_is_any_set(irq_bits, data->num_of_irq_regs)) { | ||
382 | error = entry->fh->attention(entry, irq_bits); | ||
383 | if (error < 0) | ||
384 | dev_err(dev, "%s: f%.2x" | ||
385 | " attention handler failed:" | ||
386 | " %d\n", __func__, | ||
387 | entry->fh->func, error); | ||
388 | } | ||
389 | } | ||
390 | } | ||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | |||
395 | static int rmi_driver_irq_handler(struct rmi_device *rmi_dev, int irq) | ||
396 | { | ||
397 | struct rmi_driver_data *data = rmi_get_driverdata(rmi_dev); | ||
398 | |||
399 | /* Can get called before the driver is fully ready to deal with | ||
400 | * interrupts. | ||
401 | */ | ||
402 | if (!data || !data->f01_container || !data->f01_container->fh) { | ||
403 | dev_warn(&rmi_dev->dev, | ||
404 | "Not ready to handle interrupts yet!\n"); | ||
405 | return 0; | ||
406 | } | ||
407 | |||
408 | return process_interrupt_requests(rmi_dev); | ||
409 | } | ||
410 | |||
411 | /* | ||
412 | * Construct a function's IRQ mask. This should | ||
413 | * be called once and stored. | ||
414 | */ | ||
415 | static u8 *rmi_driver_irq_get_mask(struct rmi_device *rmi_dev, | ||
416 | struct rmi_function_container *fc) { | ||
417 | struct rmi_driver_data *data = rmi_get_driverdata(rmi_dev); | ||
418 | |||
419 | /* TODO: Where should this be freed? */ | ||
420 | u8 *irq_mask = kzalloc(sizeof(u8) * data->num_of_irq_regs, GFP_KERNEL); | ||
421 | if (irq_mask) | ||
422 | construct_mask(irq_mask, fc->num_of_irqs, fc->irq_pos); | ||
423 | |||
424 | return irq_mask; | ||
425 | } | ||
426 | |||
427 | /* | ||
428 | * This pair of functions allows functions like function 54 to request to have | ||
429 | * other interupts disabled until the restore function is called. Only one store | ||
430 | * happens at a time. | ||
431 | */ | ||
432 | static int rmi_driver_irq_save(struct rmi_device *rmi_dev, u8 * new_ints) | ||
433 | { | ||
434 | int retval = 0; | ||
435 | struct rmi_driver_data *data = rmi_get_driverdata(rmi_dev); | ||
436 | struct device *dev = &rmi_dev->dev; | ||
437 | |||
438 | mutex_lock(&data->irq_mutex); | ||
439 | if (!data->irq_stored) { | ||
440 | /* Save current enabled interupts */ | ||
441 | retval = rmi_read_block(rmi_dev, | ||
442 | data->f01_container->fd.control_base_addr+1, | ||
443 | data->irq_mask_store, data->num_of_irq_regs); | ||
444 | if (retval < 0) { | ||
445 | dev_err(dev, "%s: Failed to read enabled interrupts!", | ||
446 | __func__); | ||
447 | goto error_unlock; | ||
448 | } | ||
449 | /* | ||
450 | * Disable every interupt except for function 54 | ||
451 | * TODO:Will also want to not disable function 1-like functions. | ||
452 | * No need to take care of this now, since there's no good way | ||
453 | * to identify them. | ||
454 | */ | ||
455 | retval = rmi_write_block(rmi_dev, | ||
456 | data->f01_container->fd.control_base_addr+1, | ||
457 | new_ints, data->num_of_irq_regs); | ||
458 | if (retval < 0) { | ||
459 | dev_err(dev, "%s: Failed to change enabled interrupts!", | ||
460 | __func__); | ||
461 | goto error_unlock; | ||
462 | } | ||
463 | memcpy(data->current_irq_mask, new_ints, | ||
464 | data->num_of_irq_regs * sizeof(u8)); | ||
465 | data->irq_stored = true; | ||
466 | } else { | ||
467 | retval = -ENOSPC; /* No space to store IRQs.*/ | ||
468 | dev_err(dev, "%s: Attempted to save values when" | ||
469 | " already stored!", __func__); | ||
470 | } | ||
471 | |||
472 | error_unlock: | ||
473 | mutex_unlock(&data->irq_mutex); | ||
474 | return retval; | ||
475 | } | ||
476 | |||
477 | static int rmi_driver_irq_restore(struct rmi_device *rmi_dev) | ||
478 | { | ||
479 | int retval = 0; | ||
480 | struct rmi_driver_data *data = rmi_get_driverdata(rmi_dev); | ||
481 | struct device *dev = &rmi_dev->dev; | ||
482 | mutex_lock(&data->irq_mutex); | ||
483 | |||
484 | if (data->irq_stored) { | ||
485 | retval = rmi_write_block(rmi_dev, | ||
486 | data->f01_container->fd.control_base_addr+1, | ||
487 | data->irq_mask_store, data->num_of_irq_regs); | ||
488 | if (retval < 0) { | ||
489 | dev_err(dev, "%s: Failed to write enabled interupts!", | ||
490 | __func__); | ||
491 | goto error_unlock; | ||
492 | } | ||
493 | memcpy(data->current_irq_mask, data->irq_mask_store, | ||
494 | data->num_of_irq_regs * sizeof(u8)); | ||
495 | data->irq_stored = false; | ||
496 | } else { | ||
497 | retval = -EINVAL; | ||
498 | dev_err(dev, "%s: Attempted to restore values when not stored!", | ||
499 | __func__); | ||
500 | } | ||
501 | |||
502 | error_unlock: | ||
503 | mutex_unlock(&data->irq_mutex); | ||
504 | return retval; | ||
505 | } | ||
506 | |||
507 | static int rmi_driver_fn_01_specific(struct rmi_device *rmi_dev, | ||
508 | struct pdt_entry *pdt_ptr, | ||
509 | int *current_irq_count, | ||
510 | u16 page_start) | ||
511 | { | ||
512 | struct rmi_driver_data *data = NULL; | ||
513 | struct rmi_function_container *fc = NULL; | ||
514 | int retval = 0; | ||
515 | struct device *dev = &rmi_dev->dev; | ||
516 | struct rmi_function_handler *fh = | ||
517 | rmi_get_function_handler(0x01); | ||
518 | |||
519 | data = rmi_get_driverdata(rmi_dev); | ||
520 | |||
521 | dev_info(dev, "%s: Found F01, initializing.\n", __func__); | ||
522 | if (!fh) | ||
523 | dev_dbg(dev, "%s: No function handler for F01?!", __func__); | ||
524 | |||
525 | fc = kzalloc(sizeof(struct rmi_function_container), GFP_KERNEL); | ||
526 | if (!fc) { | ||
527 | retval = -ENOMEM; | ||
528 | return retval; | ||
529 | } | ||
530 | |||
531 | copy_pdt_entry_to_fd(pdt_ptr, &fc->fd, page_start); | ||
532 | fc->num_of_irqs = pdt_ptr->interrupt_source_count; | ||
533 | fc->irq_pos = *current_irq_count; | ||
534 | |||
535 | *current_irq_count += fc->num_of_irqs; | ||
536 | |||
537 | fc->rmi_dev = rmi_dev; | ||
538 | fc->dev.parent = &fc->rmi_dev->dev; | ||
539 | fc->fh = fh; | ||
540 | |||
541 | dev_set_name(&(fc->dev), "fn%02x", fc->fd.function_number); | ||
542 | |||
543 | retval = device_register(&fc->dev); | ||
544 | if (retval) { | ||
545 | dev_err(dev, "%s: Failed device_register for F01.\n", __func__); | ||
546 | goto error_free_data; | ||
547 | } | ||
548 | |||
549 | data->f01_container = fc; | ||
550 | |||
551 | return retval; | ||
552 | |||
553 | error_free_data: | ||
554 | kfree(fc); | ||
555 | return retval; | ||
556 | } | ||
557 | |||
558 | /* | ||
559 | * Scan the PDT for F01 so we can force a reset before anything else | ||
560 | * is done. This forces the sensor into a known state, and also | ||
561 | * forces application of any pending updates from reflashing the | ||
562 | * firmware or configuration. We have to do this before actually | ||
563 | * building the PDT because the reflash might cause various registers | ||
564 | * to move around. | ||
565 | */ | ||
566 | static int do_initial_reset(struct rmi_device* rmi_dev) | ||
567 | { | ||
568 | struct pdt_entry pdt_entry; | ||
569 | int page; | ||
570 | struct device *dev = &rmi_dev->dev; | ||
571 | bool done = false; | ||
572 | int i; | ||
573 | int retval; | ||
574 | |||
575 | pr_info("in function ____%s____ \n", __func__); | ||
576 | |||
577 | polled_synaptics_rmi_device = rmi_dev; | ||
578 | |||
579 | for (page = 0; (page <= RMI4_MAX_PAGE) && !done; page++) { | ||
580 | |||
581 | u16 page_start = RMI4_PAGE_SIZE * page; | ||
582 | u16 pdt_start = page_start + PDT_START_SCAN_LOCATION; | ||
583 | u16 pdt_end = page_start + PDT_END_SCAN_LOCATION; | ||
584 | pr_info(" reading page = %d\n", page ); | ||
585 | done = true; | ||
586 | for (i = pdt_start; i >= pdt_end; i -= sizeof(pdt_entry)) { | ||
587 | |||
588 | pr_info(" reading PDT entry %3d (block %3d)\n", | ||
589 | i%sizeof(pdt_entry), i); | ||
590 | |||
591 | retval = rmi_read_block(rmi_dev, i, (u8 *)&pdt_entry, | ||
592 | sizeof(pdt_entry)); | ||
593 | if (retval != sizeof(pdt_entry)) { | ||
594 | dev_err(dev, "Read PDT entry at 0x%04x" | ||
595 | "failed, code = %d.\n", i, retval); | ||
596 | return retval; | ||
597 | } | ||
598 | |||
599 | if (RMI4_END_OF_PDT(pdt_entry.function_number)) | ||
600 | break; | ||
601 | done = false; | ||
602 | |||
603 | if (pdt_entry.function_number == 0x01) { | ||
604 | u16 cmd_addr = page_start + | ||
605 | pdt_entry.command_base_addr; | ||
606 | u8 cmd_buf = RMI_DEVICE_RESET_CMD; | ||
607 | retval = rmi_write_block(rmi_dev, cmd_addr, | ||
608 | &cmd_buf, 1); | ||
609 | if (retval < 0) { | ||
610 | dev_err(dev, "Initial reset failed. " | ||
611 | "Code = %d.\n", retval); | ||
612 | return retval; | ||
613 | } | ||
614 | mdelay(INITIAL_RESET_WAIT_MS); | ||
615 | return 0; | ||
616 | } | ||
617 | } | ||
618 | } | ||
619 | |||
620 | dev_warn(dev, "WARNING: Failed to find F01 for initial reset.\n"); | ||
621 | return -ENODEV; | ||
622 | } | ||
623 | |||
624 | |||
625 | static int rmi_scan_pdt(struct rmi_device *rmi_dev) | ||
626 | { | ||
627 | struct rmi_driver_data *data; | ||
628 | struct rmi_function_container *fc; | ||
629 | struct pdt_entry pdt_entry; | ||
630 | int page; | ||
631 | struct device *dev = &rmi_dev->dev; | ||
632 | int irq_count = 0; | ||
633 | bool done = false; | ||
634 | int i; | ||
635 | int retval; | ||
636 | pr_info("in function ____%s____ \n", __func__); | ||
637 | pr_info(" doing initial reset \n"); | ||
638 | |||
639 | retval = do_initial_reset(rmi_dev); | ||
640 | pr_info(" back in %s \n", __func__); | ||
641 | |||
642 | if (retval) | ||
643 | dev_err(dev, "WARNING: Initial reset failed! Soldiering on.\n"); | ||
644 | |||
645 | data = rmi_get_driverdata(rmi_dev); | ||
646 | |||
647 | INIT_LIST_HEAD(&data->rmi_functions.list); | ||
648 | |||
649 | /* parse the PDT */ | ||
650 | for (page = 0; (page <= RMI4_MAX_PAGE) && !done; page++) { | ||
651 | u16 page_start = RMI4_PAGE_SIZE * page; | ||
652 | u16 pdt_start = page_start + PDT_START_SCAN_LOCATION; | ||
653 | u16 pdt_end = page_start + PDT_END_SCAN_LOCATION; | ||
654 | |||
655 | done = true; | ||
656 | for (i = pdt_start; i >= pdt_end; i -= sizeof(pdt_entry)) { | ||
657 | retval = rmi_read_block(rmi_dev, i, (u8 *)&pdt_entry, | ||
658 | sizeof(pdt_entry)); | ||
659 | if (retval != sizeof(pdt_entry)) { | ||
660 | dev_err(dev, "Read PDT entry at 0x%04x" | ||
661 | "failed.\n", i); | ||
662 | goto error_exit; | ||
663 | } | ||
664 | |||
665 | if (RMI4_END_OF_PDT(pdt_entry.function_number)) | ||
666 | break; | ||
667 | |||
668 | dev_dbg(dev, "%s: Found F%.2X on page 0x%02X\n", | ||
669 | __func__, pdt_entry.function_number, page); | ||
670 | done = false; | ||
671 | |||
672 | /* | ||
673 | * F01 is handled by rmi_driver. Hopefully we will get | ||
674 | * rid of the special treatment of f01 at some point | ||
675 | * in time. | ||
676 | */ | ||
677 | if (pdt_entry.function_number == 0x01) { | ||
678 | retval = rmi_driver_fn_01_specific(rmi_dev, | ||
679 | &pdt_entry, &irq_count, | ||
680 | page_start); | ||
681 | if (retval) | ||
682 | goto error_exit; | ||
683 | continue; | ||
684 | } | ||
685 | |||
686 | fc = kzalloc(sizeof(struct rmi_function_container), | ||
687 | GFP_KERNEL); | ||
688 | if (!fc) { | ||
689 | dev_err(dev, "Failed to allocate function " | ||
690 | "container for F%02X.\n", | ||
691 | pdt_entry.function_number); | ||
692 | retval = -ENOMEM; | ||
693 | goto error_exit; | ||
694 | } | ||
695 | |||
696 | copy_pdt_entry_to_fd(&pdt_entry, &fc->fd, page_start); | ||
697 | |||
698 | fc->rmi_dev = rmi_dev; | ||
699 | fc->num_of_irqs = pdt_entry.interrupt_source_count; | ||
700 | fc->irq_pos = irq_count; | ||
701 | irq_count += fc->num_of_irqs; | ||
702 | |||
703 | retval = init_one_function(rmi_dev, fc); | ||
704 | if (retval < 0) { | ||
705 | dev_err(dev, "Failed to initialize F%.2x\n", | ||
706 | pdt_entry.function_number); | ||
707 | kfree(fc); | ||
708 | goto error_exit; | ||
709 | } | ||
710 | |||
711 | list_add_tail(&fc->list, &data->rmi_functions.list); | ||
712 | } | ||
713 | } | ||
714 | data->num_of_irq_regs = (irq_count + 7) / 8; | ||
715 | dev_dbg(dev, "%s: Done with PDT scan.\n", __func__); | ||
716 | return 0; | ||
717 | |||
718 | error_exit: | ||
719 | return retval; | ||
720 | } | ||
721 | |||
722 | |||
723 | #ifdef SYNAPTICS_SENSOR_POLL | ||
724 | void synaptics_sensor_poller(unsigned long data){ | ||
725 | pr_info("in function ____%s____ , rmi_device= 0x%8x \n", __func__, polled_synaptics_rmi_device); | ||
726 | // msleep(10000); | ||
727 | for (;;) { | ||
728 | msleep(100); | ||
729 | rmi_driver_irq_handler(polled_synaptics_rmi_device, 0); | ||
730 | } | ||
731 | |||
732 | return; | ||
733 | } | ||
734 | |||
735 | struct workqueue_struct *synaptics_rmi_polling_queue = NULL; | ||
736 | struct delayed_work synaptics_rmi_polling_work; | ||
737 | |||
738 | #endif | ||
739 | |||
740 | |||
741 | static int rmi_driver_probe(struct rmi_device *rmi_dev) | ||
742 | { | ||
743 | struct rmi_driver_data *data; | ||
744 | struct rmi_function_container *fc; | ||
745 | struct rmi_device_platform_data *pdata; | ||
746 | int error = 0; | ||
747 | struct device *dev = &rmi_dev->dev; | ||
748 | int attr_count = 0; | ||
749 | |||
750 | dev_dbg(dev, "%s: Starting probe.\n", __func__); | ||
751 | |||
752 | pdata = to_rmi_platform_data(rmi_dev); | ||
753 | |||
754 | data = kzalloc(sizeof(struct rmi_driver_data), GFP_KERNEL); | ||
755 | if (!data) { | ||
756 | dev_err(dev, "%s: Failed to allocate driver data.\n", __func__); | ||
757 | return -ENOMEM; | ||
758 | } | ||
759 | |||
760 | rmi_set_driverdata(rmi_dev, data); | ||
761 | |||
762 | error = rmi_scan_pdt(rmi_dev); | ||
763 | if (error) { | ||
764 | dev_err(dev, "PDT scan failed with code %d.\n", error); | ||
765 | goto err_free_data; | ||
766 | } | ||
767 | |||
768 | if (!data->f01_container) { | ||
769 | dev_err(dev, "missing f01 function!\n"); | ||
770 | error = -EINVAL; | ||
771 | goto err_free_data; | ||
772 | } | ||
773 | |||
774 | data->f01_container->irq_mask = kzalloc( | ||
775 | sizeof(u8) * data->num_of_irq_regs, GFP_KERNEL); | ||
776 | if (!data->f01_container->irq_mask) { | ||
777 | dev_err(dev, "Failed to allocate F01 IRQ mask.\n"); | ||
778 | error = -ENOMEM; | ||
779 | goto err_free_data; | ||
780 | } | ||
781 | construct_mask(data->f01_container->irq_mask, | ||
782 | data->f01_container->num_of_irqs, | ||
783 | data->f01_container->irq_pos); | ||
784 | list_for_each_entry(fc, &data->rmi_functions.list, list) | ||
785 | fc->irq_mask = rmi_driver_irq_get_mask(rmi_dev, fc); | ||
786 | |||
787 | error = rmi_driver_f01_init(rmi_dev); | ||
788 | if (error < 0) { | ||
789 | dev_err(dev, "Failed to initialize F01.\n"); | ||
790 | goto err_free_data; | ||
791 | } | ||
792 | |||
793 | error = rmi_read(rmi_dev, PDT_PROPERTIES_LOCATION, | ||
794 | (char *) &data->pdt_props); | ||
795 | if (error < 0) { | ||
796 | /* we'll print out a warning and continue since | ||
797 | * failure to get the PDT properties is not a cause to fail | ||
798 | */ | ||
799 | dev_warn(dev, "Could not read PDT properties from 0x%04x. " | ||
800 | "Assuming 0x00.\n", PDT_PROPERTIES_LOCATION); | ||
801 | } | ||
802 | |||
803 | dev_dbg(dev, "%s: Creating sysfs files.", __func__); | ||
804 | for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { | ||
805 | error = device_create_file(dev, &attrs[attr_count]); | ||
806 | if (error < 0) { | ||
807 | dev_err(dev, "%s: Failed to create sysfs file %s.\n", | ||
808 | __func__, attrs[attr_count].attr.name); | ||
809 | goto err_free_data; | ||
810 | } | ||
811 | } | ||
812 | |||
813 | __mutex_init(&data->irq_mutex, "irq_mutex", &data->irq_key); | ||
814 | data->current_irq_mask = kzalloc(sizeof(u8) * data->num_of_irq_regs, | ||
815 | GFP_KERNEL); | ||
816 | if (!data->current_irq_mask) { | ||
817 | dev_err(dev, "Failed to allocate current_irq_mask.\n"); | ||
818 | error = -ENOMEM; | ||
819 | goto err_free_data; | ||
820 | } | ||
821 | error = rmi_read_block(rmi_dev, | ||
822 | data->f01_container->fd.control_base_addr+1, | ||
823 | data->current_irq_mask, data->num_of_irq_regs); | ||
824 | if (error < 0) { | ||
825 | dev_err(dev, "%s: Failed to read current IRQ mask.\n", | ||
826 | __func__); | ||
827 | goto err_free_data; | ||
828 | } | ||
829 | data->irq_mask_store = kzalloc(sizeof(u8) * data->num_of_irq_regs, | ||
830 | GFP_KERNEL); | ||
831 | if (!data->irq_mask_store) { | ||
832 | dev_err(dev, "Failed to allocate mask store.\n"); | ||
833 | error = -ENOMEM; | ||
834 | goto err_free_data; | ||
835 | } | ||
836 | |||
837 | #if defined(CONFIG_RMI4_DEV) | ||
838 | if (rmi_char_dev_register(rmi_dev->phys)) | ||
839 | pr_err("%s: error register char device", __func__); | ||
840 | #endif /*CONFIG_RMI4_DEV*/ | ||
841 | |||
842 | #ifdef CONFIG_PM | ||
843 | data->pm_data = pdata->pm_data; | ||
844 | data->pre_suspend = pdata->pre_suspend; | ||
845 | data->post_resume = pdata->post_resume; | ||
846 | |||
847 | mutex_init(&data->suspend_mutex); | ||
848 | |||
849 | #ifdef CONFIG_HAS_EARLYSUSPEND | ||
850 | rmi_dev->early_suspend_handler.level = | ||
851 | EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; | ||
852 | rmi_dev->early_suspend_handler.suspend = rmi_driver_early_suspend; | ||
853 | rmi_dev->early_suspend_handler.resume = rmi_driver_late_resume; | ||
854 | register_early_suspend(&rmi_dev->early_suspend_handler); | ||
855 | #endif /* CONFIG_HAS_EARLYSUSPEND */ | ||
856 | #endif /* CONFIG_PM */ | ||
857 | data->enabled = true; | ||
858 | |||
859 | dev_info(dev, "connected RMI device manufacturer: %s product: %s\n", | ||
860 | data->manufacturer_id == 1 ? "synaptics" : "unknown", | ||
861 | data->product_id); | ||
862 | |||
863 | #ifdef SYNAPTICS_SENSOR_POLL | ||
864 | synaptics_rmi_polling_queue = create_singlethread_workqueue("rmi_poll_work"); | ||
865 | INIT_DELAYED_WORK_DEFERRABLE(&synaptics_rmi_polling_work, synaptics_sensor_poller); | ||
866 | pr_info("%s: setting up POLLING mode, rmi_device= 0x%8x \n", __func__, polled_synaptics_rmi_device); | ||
867 | queue_delayed_work(synaptics_rmi_polling_queue, &synaptics_rmi_polling_work, 1000); | ||
868 | #endif | ||
869 | return 0; | ||
870 | |||
871 | err_free_data: | ||
872 | rmi_free_function_list(rmi_dev); | ||
873 | for (attr_count--; attr_count >= 0; attr_count--) | ||
874 | device_remove_file(dev, &attrs[attr_count]); | ||
875 | kfree(data->f01_container->irq_mask); | ||
876 | kfree(data->irq_mask_store); | ||
877 | kfree(data->current_irq_mask); | ||
878 | kfree(data); | ||
879 | return error; | ||
880 | } | ||
881 | |||
882 | #ifdef CONFIG_PM | ||
883 | static int rmi_driver_suspend(struct device *dev) | ||
884 | { | ||
885 | struct rmi_device *rmi_dev; | ||
886 | struct rmi_driver_data *data; | ||
887 | struct rmi_function_container *entry; | ||
888 | int retval = 0; | ||
889 | |||
890 | rmi_dev = to_rmi_device(dev); | ||
891 | data = rmi_get_driverdata(rmi_dev); | ||
892 | |||
893 | mutex_lock(&data->suspend_mutex); | ||
894 | if (data->suspended) | ||
895 | goto exit; | ||
896 | |||
897 | if (data->pre_suspend) { | ||
898 | retval = data->pre_suspend(data->pm_data); | ||
899 | if (retval) | ||
900 | goto exit; | ||
901 | } | ||
902 | |||
903 | list_for_each_entry(entry, &data->rmi_functions.list, list) | ||
904 | if (entry->fh && entry->fh->suspend) { | ||
905 | retval = entry->fh->suspend(entry); | ||
906 | if (retval < 0) | ||
907 | goto exit; | ||
908 | } | ||
909 | |||
910 | if (data->f01_container && data->f01_container->fh | ||
911 | && data->f01_container->fh->suspend) { | ||
912 | retval = data->f01_container->fh->suspend(data->f01_container); | ||
913 | if (retval < 0) | ||
914 | goto exit; | ||
915 | } | ||
916 | data->suspended = true; | ||
917 | |||
918 | exit: | ||
919 | mutex_unlock(&data->suspend_mutex); | ||
920 | return retval; | ||
921 | } | ||
922 | |||
923 | static int rmi_driver_resume(struct device *dev) | ||
924 | { | ||
925 | struct rmi_device *rmi_dev; | ||
926 | struct rmi_driver_data *data; | ||
927 | struct rmi_function_container *entry; | ||
928 | int retval = 0; | ||
929 | |||
930 | rmi_dev = to_rmi_device(dev); | ||
931 | data = rmi_get_driverdata(rmi_dev); | ||
932 | |||
933 | mutex_lock(&data->suspend_mutex); | ||
934 | if (!data->suspended) | ||
935 | goto exit; | ||
936 | |||
937 | if (data->f01_container && data->f01_container->fh | ||
938 | && data->f01_container->fh->resume) { | ||
939 | retval = data->f01_container->fh->resume(data->f01_container); | ||
940 | if (retval < 0) | ||
941 | goto exit; | ||
942 | } | ||
943 | |||
944 | list_for_each_entry(entry, &data->rmi_functions.list, list) | ||
945 | if (entry->fh && entry->fh->resume) { | ||
946 | retval = entry->fh->resume(entry); | ||
947 | if (retval < 0) | ||
948 | goto exit; | ||
949 | } | ||
950 | |||
951 | if (data->post_resume) { | ||
952 | retval = data->post_resume(data->pm_data); | ||
953 | if (retval) | ||
954 | goto exit; | ||
955 | } | ||
956 | |||
957 | data->suspended = false; | ||
958 | |||
959 | exit: | ||
960 | mutex_unlock(&data->suspend_mutex); | ||
961 | return retval; | ||
962 | } | ||
963 | |||
964 | #ifdef CONFIG_HAS_EARLYSUSPEND | ||
965 | static void rmi_driver_early_suspend(struct early_suspend *h) | ||
966 | { | ||
967 | struct rmi_device *rmi_dev = | ||
968 | container_of(h, struct rmi_device, early_suspend_handler); | ||
969 | |||
970 | dev_dbg(&rmi_dev->dev, "Early suspend.\n"); | ||
971 | rmi_driver_suspend(&rmi_dev->dev); | ||
972 | } | ||
973 | |||
974 | static void rmi_driver_late_resume(struct early_suspend *h) | ||
975 | { | ||
976 | struct rmi_device *rmi_dev = | ||
977 | container_of(h, struct rmi_device, early_suspend_handler); | ||
978 | |||
979 | dev_dbg(&rmi_dev->dev, "Late resume.\n"); | ||
980 | rmi_driver_resume(&rmi_dev->dev); | ||
981 | } | ||
982 | #endif /* CONFIG_HAS_EARLYSUSPEND */ | ||
983 | #endif /* CONFIG_PM */ | ||
984 | |||
985 | static int __devexit rmi_driver_remove(struct rmi_device *rmi_dev) | ||
986 | { | ||
987 | struct rmi_driver_data *data = rmi_get_driverdata(rmi_dev); | ||
988 | struct rmi_function_container *entry; | ||
989 | int i; | ||
990 | |||
991 | list_for_each_entry(entry, &data->rmi_functions.list, list) | ||
992 | if (entry->fh && entry->fh->remove) | ||
993 | entry->fh->remove(entry); | ||
994 | |||
995 | rmi_free_function_list(rmi_dev); | ||
996 | for (i = 0; i < ARRAY_SIZE(attrs); i++) | ||
997 | device_remove_file(&rmi_dev->dev, &attrs[i]); | ||
998 | kfree(data->f01_container->irq_mask); | ||
999 | kfree(data->irq_mask_store); | ||
1000 | kfree(data->current_irq_mask); | ||
1001 | kfree(data); | ||
1002 | |||
1003 | return 0; | ||
1004 | } | ||
1005 | |||
1006 | #ifdef UNIVERSAL_DEV_PM_OPS | ||
1007 | static UNIVERSAL_DEV_PM_OPS(rmi_driver_pm, rmi_driver_suspend, | ||
1008 | rmi_driver_resume, NULL); | ||
1009 | #endif | ||
1010 | |||
1011 | static struct rmi_driver sensor_driver = { | ||
1012 | .driver = { | ||
1013 | .owner = THIS_MODULE, | ||
1014 | // .name = "rmi-generic", | ||
1015 | .name = "rmi_generic", | ||
1016 | #ifdef UNIVERSAL_DEV_PM_OPS | ||
1017 | .pm = &rmi_driver_pm, | ||
1018 | #endif | ||
1019 | }, | ||
1020 | .probe = rmi_driver_probe, | ||
1021 | .irq_handler = rmi_driver_irq_handler, | ||
1022 | .fh_add = rmi_driver_fh_add, | ||
1023 | .fh_remove = rmi_driver_fh_remove, | ||
1024 | .get_func_irq_mask = rmi_driver_irq_get_mask, | ||
1025 | .store_irq_mask = rmi_driver_irq_save, | ||
1026 | .restore_irq_mask = rmi_driver_irq_restore, | ||
1027 | .remove = __devexit_p(rmi_driver_remove) | ||
1028 | }; | ||
1029 | |||
1030 | /* Utility routine to handle writes to read-only attributes. Hopefully | ||
1031 | * this will never happen, but if the user does something stupid, we don't | ||
1032 | * want to accept it quietly (which is what can happen if you just put NULL | ||
1033 | * for the attribute's store function). | ||
1034 | */ | ||
1035 | ssize_t rmi_store_error(struct device *dev, | ||
1036 | struct device_attribute *attr, | ||
1037 | const char *buf, size_t count) | ||
1038 | { | ||
1039 | dev_warn(dev, | ||
1040 | "RMI4 WARNING: Attempt to write %d characters to read-only " | ||
1041 | "attribute %s.", count, attr->attr.name); | ||
1042 | return -EPERM; | ||
1043 | } | ||
1044 | |||
1045 | /* Utility routine to handle reads of write-only attributes. Hopefully | ||
1046 | * this will never happen, but if the user does something stupid, we don't | ||
1047 | * want to accept it quietly (which is what can happen if you just put NULL | ||
1048 | * for the attribute's show function). | ||
1049 | */ | ||
1050 | ssize_t rmi_show_error(struct device *dev, | ||
1051 | struct device_attribute *attr, | ||
1052 | char *buf) | ||
1053 | { | ||
1054 | dev_warn(dev, | ||
1055 | "RMI4 WARNING: Attempt to read from write-only attribute %s.", | ||
1056 | attr->attr.name); | ||
1057 | return -EPERM; | ||
1058 | } | ||
1059 | |||
1060 | /* sysfs show and store fns for driver attributes */ | ||
1061 | static ssize_t rmi_driver_hasbsr_show(struct device *dev, | ||
1062 | struct device_attribute *attr, | ||
1063 | char *buf) | ||
1064 | { | ||
1065 | struct rmi_device *rmi_dev; | ||
1066 | struct rmi_driver_data *data; | ||
1067 | rmi_dev = to_rmi_device(dev); | ||
1068 | data = rmi_get_driverdata(rmi_dev); | ||
1069 | |||
1070 | return snprintf(buf, PAGE_SIZE, "%u\n", has_bsr(data)); | ||
1071 | } | ||
1072 | |||
1073 | static ssize_t rmi_driver_bsr_show(struct device *dev, | ||
1074 | struct device_attribute *attr, char *buf) | ||
1075 | { | ||
1076 | struct rmi_device *rmi_dev; | ||
1077 | struct rmi_driver_data *data; | ||
1078 | rmi_dev = to_rmi_device(dev); | ||
1079 | data = rmi_get_driverdata(rmi_dev); | ||
1080 | |||
1081 | return snprintf(buf, PAGE_SIZE, "%u\n", data->bsr); | ||
1082 | } | ||
1083 | |||
1084 | static ssize_t rmi_driver_bsr_store(struct device *dev, | ||
1085 | struct device_attribute *attr, | ||
1086 | const char *buf, size_t count) | ||
1087 | { | ||
1088 | int retval; | ||
1089 | unsigned long val; | ||
1090 | struct rmi_device *rmi_dev; | ||
1091 | struct rmi_driver_data *data; | ||
1092 | |||
1093 | rmi_dev = to_rmi_device(dev); | ||
1094 | data = rmi_get_driverdata(rmi_dev); | ||
1095 | |||
1096 | /* need to convert the string data to an actual value */ | ||
1097 | retval = strict_strtoul(buf, 10, &val); | ||
1098 | if (retval < 0) { | ||
1099 | dev_err(dev, "Invalid value '%s' written to BSR.\n", buf); | ||
1100 | return -EINVAL; | ||
1101 | } | ||
1102 | |||
1103 | retval = rmi_write(rmi_dev, BSR_LOCATION, (unsigned char)val); | ||
1104 | if (retval) { | ||
1105 | dev_err(dev, "%s : failed to write bsr %u to 0x%x\n", | ||
1106 | __func__, (unsigned int)val, BSR_LOCATION); | ||
1107 | return retval; | ||
1108 | } | ||
1109 | |||
1110 | data->bsr = val; | ||
1111 | |||
1112 | return count; | ||
1113 | } | ||
1114 | |||
1115 | static void disable_sensor(struct rmi_device *rmi_dev) | ||
1116 | { | ||
1117 | struct rmi_driver_data *data = rmi_get_driverdata(rmi_dev); | ||
1118 | |||
1119 | rmi_dev->phys->disable_device(rmi_dev->phys); | ||
1120 | |||
1121 | data->enabled = false; | ||
1122 | } | ||
1123 | |||
1124 | static int enable_sensor(struct rmi_device *rmi_dev) | ||
1125 | { | ||
1126 | struct rmi_driver_data *data = rmi_get_driverdata(rmi_dev); | ||
1127 | int retval = 0; | ||
1128 | pr_info("in function ____%s____ \n", __func__); | ||
1129 | retval = rmi_dev->phys->enable_device(rmi_dev->phys); | ||
1130 | /* non-zero means error occurred */ | ||
1131 | if (retval) | ||
1132 | return retval; | ||
1133 | |||
1134 | data->enabled = true; | ||
1135 | |||
1136 | return 0; | ||
1137 | } | ||
1138 | |||
1139 | static ssize_t rmi_driver_enabled_show(struct device *dev, | ||
1140 | struct device_attribute *attr, char *buf) | ||
1141 | { | ||
1142 | struct rmi_device *rmi_dev; | ||
1143 | struct rmi_driver_data *data; | ||
1144 | |||
1145 | rmi_dev = to_rmi_device(dev); | ||
1146 | data = rmi_get_driverdata(rmi_dev); | ||
1147 | |||
1148 | return snprintf(buf, PAGE_SIZE, "%u\n", data->enabled); | ||
1149 | } | ||
1150 | |||
1151 | static ssize_t rmi_driver_enabled_store(struct device *dev, | ||
1152 | struct device_attribute *attr, | ||
1153 | const char *buf, size_t count) | ||
1154 | { | ||
1155 | int retval; | ||
1156 | int new_value; | ||
1157 | struct rmi_device *rmi_dev; | ||
1158 | struct rmi_driver_data *data; | ||
1159 | |||
1160 | rmi_dev = to_rmi_device(dev); | ||
1161 | data = rmi_get_driverdata(rmi_dev); | ||
1162 | |||
1163 | if (sysfs_streq(buf, "0")) | ||
1164 | new_value = false; | ||
1165 | else if (sysfs_streq(buf, "1")) | ||
1166 | new_value = true; | ||
1167 | else | ||
1168 | return -EINVAL; | ||
1169 | |||
1170 | if (new_value) { | ||
1171 | retval = enable_sensor(rmi_dev); | ||
1172 | if (retval) { | ||
1173 | dev_err(dev, "Failed to enable sensor, code=%d.\n", | ||
1174 | retval); | ||
1175 | return -EIO; | ||
1176 | } | ||
1177 | } else { | ||
1178 | disable_sensor(rmi_dev); | ||
1179 | } | ||
1180 | |||
1181 | return count; | ||
1182 | } | ||
1183 | |||
1184 | #if REGISTER_DEBUG | ||
1185 | static ssize_t rmi_driver_reg_store(struct device *dev, | ||
1186 | struct device_attribute *attr, | ||
1187 | const char *buf, size_t count) | ||
1188 | { | ||
1189 | int retval; | ||
1190 | unsigned int address; | ||
1191 | unsigned int bytes; | ||
1192 | struct rmi_device *rmi_dev; | ||
1193 | struct rmi_driver_data *data; | ||
1194 | u8 readbuf[128]; | ||
1195 | unsigned char outbuf[512]; | ||
1196 | unsigned char *bufptr = outbuf; | ||
1197 | int i; | ||
1198 | |||
1199 | rmi_dev = to_rmi_device(dev); | ||
1200 | data = rmi_get_driverdata(rmi_dev); | ||
1201 | |||
1202 | retval = sscanf(buf, "%x %u", &address, &bytes); | ||
1203 | if (retval != 2) { | ||
1204 | dev_err(dev, "Invalid input (code %d) for reg store: %s", | ||
1205 | retval, buf); | ||
1206 | return -EINVAL; | ||
1207 | } | ||
1208 | if (address < 0 || address > 0xFFFF) { | ||
1209 | dev_err(dev, "Invalid address for reg store '%#06x'.\n", | ||
1210 | address); | ||
1211 | return -EINVAL; | ||
1212 | } | ||
1213 | if (bytes < 0 || bytes >= sizeof(readbuf) || address+bytes > 65535) { | ||
1214 | dev_err(dev, "Invalid byte count for reg store '%d'.\n", | ||
1215 | bytes); | ||
1216 | return -EINVAL; | ||
1217 | } | ||
1218 | |||
1219 | retval = rmi_read_block(rmi_dev, address, readbuf, bytes); | ||
1220 | if (retval != bytes) { | ||
1221 | dev_err(dev, "Failed to read %d registers at %#06x, code %d.\n", | ||
1222 | bytes, address, retval); | ||
1223 | return retval; | ||
1224 | } | ||
1225 | |||
1226 | dev_info(dev, "Reading %d bytes from %#06x.\n", bytes, address); | ||
1227 | for (i = 0; i < bytes; i++) { | ||
1228 | retval = snprintf(bufptr, 4, "%02X ", readbuf[i]); | ||
1229 | if (retval < 0) { | ||
1230 | dev_err(dev, "Failed to format string. Code: %d", | ||
1231 | retval); | ||
1232 | return retval; | ||
1233 | } | ||
1234 | bufptr += retval; | ||
1235 | } | ||
1236 | dev_info(dev, "%s\n", outbuf); | ||
1237 | |||
1238 | return count; | ||
1239 | } | ||
1240 | #endif | ||
1241 | |||
1242 | #if DELAY_DEBUG | ||
1243 | static ssize_t rmi_delay_store(struct device *dev, | ||
1244 | struct device_attribute *attr, | ||
1245 | const char *buf, size_t count) | ||
1246 | { | ||
1247 | int retval; | ||
1248 | struct rmi_device *rmi_dev; | ||
1249 | struct rmi_device_platform_data *pdata; | ||
1250 | unsigned int new_read_delay; | ||
1251 | unsigned int new_write_delay; | ||
1252 | unsigned int new_block_delay; | ||
1253 | unsigned int new_pre_delay; | ||
1254 | unsigned int new_post_delay; | ||
1255 | |||
1256 | retval = sscanf(buf, "%u %u %u %u %u", &new_read_delay, | ||
1257 | &new_write_delay, &new_block_delay, | ||
1258 | &new_pre_delay, &new_post_delay); | ||
1259 | if (retval != 5) { | ||
1260 | dev_err(dev, "Incorrect number of values provided for delay."); | ||
1261 | return -EINVAL; | ||
1262 | } | ||
1263 | if (new_read_delay < 0) { | ||
1264 | dev_err(dev, "Byte delay must be positive microseconds.\n"); | ||
1265 | return -EINVAL; | ||
1266 | } | ||
1267 | if (new_write_delay < 0) { | ||
1268 | dev_err(dev, "Write delay must be positive microseconds.\n"); | ||
1269 | return -EINVAL; | ||
1270 | } | ||
1271 | if (new_block_delay < 0) { | ||
1272 | dev_err(dev, "Block delay must be positive microseconds.\n"); | ||
1273 | return -EINVAL; | ||
1274 | } | ||
1275 | if (new_pre_delay < 0) { | ||
1276 | dev_err(dev, | ||
1277 | "Pre-transfer delay must be positive microseconds.\n"); | ||
1278 | return -EINVAL; | ||
1279 | } | ||
1280 | if (new_post_delay < 0) { | ||
1281 | dev_err(dev, | ||
1282 | "Post-transfer delay must be positive microseconds.\n"); | ||
1283 | return -EINVAL; | ||
1284 | } | ||
1285 | |||
1286 | rmi_dev = to_rmi_device(dev); | ||
1287 | pdata = rmi_dev->phys->dev->platform_data; | ||
1288 | |||
1289 | dev_info(dev, "Setting delays to %u %u %u %u %u.\n", new_read_delay, | ||
1290 | new_write_delay, new_block_delay, new_pre_delay, | ||
1291 | new_post_delay); | ||
1292 | pdata->spi_data.read_delay_us = new_read_delay; | ||
1293 | pdata->spi_data.write_delay_us = new_write_delay; | ||
1294 | pdata->spi_data.block_delay_us = new_block_delay; | ||
1295 | pdata->spi_data.pre_delay_us = new_pre_delay; | ||
1296 | pdata->spi_data.post_delay_us = new_post_delay; | ||
1297 | |||
1298 | return count; | ||
1299 | } | ||
1300 | |||
1301 | static ssize_t rmi_delay_show(struct device *dev, | ||
1302 | struct device_attribute *attr, char *buf) | ||
1303 | { | ||
1304 | struct rmi_device *rmi_dev; | ||
1305 | struct rmi_device_platform_data *pdata; | ||
1306 | |||
1307 | rmi_dev = to_rmi_device(dev); | ||
1308 | pdata = rmi_dev->phys->dev->platform_data; | ||
1309 | |||
1310 | return snprintf(buf, PAGE_SIZE, "%d %d %d %d %d\n", | ||
1311 | pdata->spi_data.read_delay_us, pdata->spi_data.write_delay_us, | ||
1312 | pdata->spi_data.block_delay_us, | ||
1313 | pdata->spi_data.pre_delay_us, pdata->spi_data.post_delay_us); | ||
1314 | } | ||
1315 | #endif | ||
1316 | |||
1317 | static ssize_t rmi_driver_phys_show(struct device *dev, | ||
1318 | struct device_attribute *attr, char *buf) | ||
1319 | { | ||
1320 | struct rmi_device *rmi_dev; | ||
1321 | struct rmi_phys_info *info; | ||
1322 | |||
1323 | rmi_dev = to_rmi_device(dev); | ||
1324 | info = &rmi_dev->phys->info; | ||
1325 | |||
1326 | return snprintf(buf, PAGE_SIZE, "%-5s %ld %ld %ld %ld %ld %ld %ld\n", | ||
1327 | info->proto ? info->proto : "unk", | ||
1328 | info->tx_count, info->tx_bytes, info->tx_errs, | ||
1329 | info->rx_count, info->rx_bytes, info->rx_errs, | ||
1330 | info->attn_count); | ||
1331 | } | ||
1332 | |||
1333 | static ssize_t rmi_driver_version_show(struct device *dev, | ||
1334 | struct device_attribute *attr, char *buf) | ||
1335 | { | ||
1336 | return snprintf(buf, PAGE_SIZE, "%s\n", | ||
1337 | RMI_DRIVER_VERSION_STRING); | ||
1338 | } | ||
1339 | |||
1340 | static int __init rmi_driver_init(void) | ||
1341 | { | ||
1342 | return rmi_register_driver(&sensor_driver); | ||
1343 | } | ||
1344 | |||
1345 | static void __exit rmi_driver_exit(void) | ||
1346 | { | ||
1347 | rmi_unregister_driver(&sensor_driver); | ||
1348 | } | ||
1349 | |||
1350 | module_init(rmi_driver_init); | ||
1351 | module_exit(rmi_driver_exit); | ||
1352 | |||
1353 | MODULE_AUTHOR("Eric Andersson <eric.andersson@unixphere.com>"); | ||
1354 | MODULE_DESCRIPTION("RMI generic driver"); | ||
diff --git a/drivers/input/touchscreen/rmi4/rmi_driver.h b/drivers/input/touchscreen/rmi4/rmi_driver.h new file mode 100644 index 00000000000..9e9f2c09822 --- /dev/null +++ b/drivers/input/touchscreen/rmi4/rmi_driver.h | |||
@@ -0,0 +1,109 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Synaptics Incorporated | ||
3 | * Copyright (c) 2011 Unixphere | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | #ifndef _RMI_DRIVER_H | ||
20 | #define _RMI_DRIVER_H | ||
21 | |||
22 | #define RMI_DRIVER_MAJOR_VERSION 1 | ||
23 | #define RMI_DRIVER_MINOR_VERSION 3 | ||
24 | #define RMI_DRIVER_SUB_MINOR_VERSION 0 | ||
25 | |||
26 | /* TODO: Figure out some way to construct this string in the define macro | ||
27 | * using the values defined above. | ||
28 | */ | ||
29 | #define RMI_DRIVER_VERSION_STRING "1.3.0" | ||
30 | |||
31 | |||
32 | #define RMI_PRODUCT_ID_LENGTH 10 | ||
33 | #define RMI_PRODUCT_INFO_LENGTH 2 | ||
34 | #define RMI_DATE_CODE_LENGTH 3 | ||
35 | |||
36 | struct rmi_driver_data { | ||
37 | struct rmi_function_container rmi_functions; | ||
38 | |||
39 | struct rmi_function_container *f01_container; | ||
40 | |||
41 | int num_of_irq_regs; | ||
42 | u8 *current_irq_mask; | ||
43 | u8 *irq_mask_store; | ||
44 | bool irq_stored; | ||
45 | struct mutex irq_mutex; | ||
46 | struct lock_class_key irq_key; | ||
47 | |||
48 | unsigned char pdt_props; | ||
49 | unsigned char bsr; | ||
50 | bool enabled; | ||
51 | |||
52 | u8 manufacturer_id; | ||
53 | /* product id + null termination */ | ||
54 | u8 product_id[RMI_PRODUCT_ID_LENGTH + 1]; | ||
55 | |||
56 | #ifdef CONFIG_PM | ||
57 | bool suspended; | ||
58 | struct mutex suspend_mutex; | ||
59 | |||
60 | void *pm_data; | ||
61 | int (*pre_suspend) (const void *pm_data); | ||
62 | int (*post_resume) (const void *pm_data); | ||
63 | #endif | ||
64 | |||
65 | void *data; | ||
66 | }; | ||
67 | |||
68 | struct pdt_entry { | ||
69 | u8 query_base_addr:8; | ||
70 | u8 command_base_addr:8; | ||
71 | u8 control_base_addr:8; | ||
72 | u8 data_base_addr:8; | ||
73 | u8 interrupt_source_count:3; | ||
74 | u8 bits3and4:2; | ||
75 | u8 function_version:2; | ||
76 | u8 bit7:1; | ||
77 | u8 function_number:8; | ||
78 | }; | ||
79 | |||
80 | int rmi_driver_f01_init(struct rmi_device *rmi_dev); | ||
81 | |||
82 | static inline void copy_pdt_entry_to_fd(struct pdt_entry *pdt, | ||
83 | struct rmi_function_descriptor *fd, | ||
84 | u16 page_start) | ||
85 | { | ||
86 | fd->query_base_addr = pdt->query_base_addr + page_start; | ||
87 | fd->command_base_addr = pdt->command_base_addr + page_start; | ||
88 | fd->control_base_addr = pdt->control_base_addr + page_start; | ||
89 | fd->data_base_addr = pdt->data_base_addr + page_start; | ||
90 | fd->function_number = pdt->function_number; | ||
91 | fd->interrupt_source_count = pdt->interrupt_source_count; | ||
92 | fd->function_version = pdt->function_version; | ||
93 | } | ||
94 | |||
95 | /* Helper function to convert a short (in host processor endianess) to | ||
96 | * a byte array in the RMI endianess for shorts. See above comment for | ||
97 | * why we dont us htons or something like that. | ||
98 | */ | ||
99 | void hstoba(u8 *dest, u16 src); | ||
100 | |||
101 | /* Helper fn to convert a byte array representing a short in the RMI | ||
102 | * endian-ness to a short in the native processor's specific endianness. | ||
103 | * We don't use ntohs/htons here because, well, we're not dealing with | ||
104 | * a pair of shorts. And casting dest to short* wouldn't work, because | ||
105 | * that would imply knowing the byte order of short in the first place. | ||
106 | */ | ||
107 | void batohs(u16 *dest, u8 *src); | ||
108 | |||
109 | #endif | ||
diff --git a/drivers/input/touchscreen/rmi4/rmi_f01.c b/drivers/input/touchscreen/rmi4/rmi_f01.c new file mode 100644 index 00000000000..ef9adb0586b --- /dev/null +++ b/drivers/input/touchscreen/rmi4/rmi_f01.c | |||
@@ -0,0 +1,775 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Synaptics Incorporated | ||
3 | * Copyright (c) 2011 Unixphere | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | |||
20 | #define DEBUG | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/rmi.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include "rmi_driver.h" | ||
26 | |||
27 | /* control register bits */ | ||
28 | #define RMI_SLEEP_MODE_NORMAL (0x00) | ||
29 | #define RMI_SLEEP_MODE_SENSOR_SLEEP (0x01) | ||
30 | #define RMI_SLEEP_MODE_RESERVED0 (0x02) | ||
31 | #define RMI_SLEEP_MODE_RESERVED1 (0x03) | ||
32 | |||
33 | #define RMI_IS_VALID_SLEEPMODE(mode) \ | ||
34 | (mode >= RMI_SLEEP_MODE_NORMAL && mode <= RMI_SLEEP_MODE_RESERVED1) | ||
35 | |||
36 | union f01_device_commands { | ||
37 | struct { | ||
38 | u8 reset:1; | ||
39 | u8 reserved:1; | ||
40 | }; | ||
41 | u8 reg; | ||
42 | }; | ||
43 | |||
44 | union f01_device_control { | ||
45 | struct { | ||
46 | u8 sleep_mode:2; | ||
47 | u8 nosleep:1; | ||
48 | u8 reserved:2; | ||
49 | u8 charger_input:1; | ||
50 | u8 report_rate:1; | ||
51 | u8 configured:1; | ||
52 | }; | ||
53 | u8 reg; | ||
54 | }; | ||
55 | |||
56 | union f01_device_status { | ||
57 | struct { | ||
58 | u8 status_code:4; | ||
59 | u8 reserved:2; | ||
60 | u8 flash_prog:1; | ||
61 | u8 unconfigured:1; | ||
62 | }; | ||
63 | u8 reg; | ||
64 | }; | ||
65 | |||
66 | union f01_basic_queries { | ||
67 | struct { | ||
68 | u8 manufacturer_id:8; | ||
69 | |||
70 | u8 custom_map:1; | ||
71 | u8 non_compliant:1; | ||
72 | u8 q1_bit_2:1; | ||
73 | u8 has_sensor_id:1; | ||
74 | u8 has_charger_input:1; | ||
75 | u8 has_adjustable_doze:1; | ||
76 | u8 has_adjustable_doze_holdoff:1; | ||
77 | u8 q1_bit_7:1; | ||
78 | |||
79 | u8 productinfo_1:7; | ||
80 | u8 q2_bit_7:1; | ||
81 | u8 productinfo_2:7; | ||
82 | u8 q3_bit_7:1; | ||
83 | |||
84 | u8 year:5; | ||
85 | u8 month:4; | ||
86 | u8 day:5; | ||
87 | u8 cp1:1; | ||
88 | u8 cp2:1; | ||
89 | u8 wafer_id1_lsb:8; | ||
90 | u8 wafer_id1_msb:8; | ||
91 | u8 wafer_id2_lsb:8; | ||
92 | u8 wafer_id2_msb:8; | ||
93 | u8 wafer_id3_lsb:8; | ||
94 | }; | ||
95 | u8 regs[11]; | ||
96 | }; | ||
97 | |||
98 | struct f01_data { | ||
99 | union f01_device_control device_control; | ||
100 | union f01_basic_queries basic_queries; | ||
101 | union f01_device_status device_status; | ||
102 | u8 product_id[RMI_PRODUCT_ID_LENGTH+1]; | ||
103 | |||
104 | #ifdef CONFIG_PM | ||
105 | bool suspended; | ||
106 | bool old_nosleep; | ||
107 | #endif | ||
108 | }; | ||
109 | |||
110 | |||
111 | static ssize_t rmi_fn_01_productinfo_show(struct device *dev, | ||
112 | struct device_attribute *attr, | ||
113 | char *buf); | ||
114 | |||
115 | static ssize_t rmi_fn_01_productid_show(struct device *dev, | ||
116 | struct device_attribute *attr, | ||
117 | char *buf); | ||
118 | |||
119 | static ssize_t rmi_fn_01_manufacturer_show(struct device *dev, | ||
120 | struct device_attribute *attr, | ||
121 | char *buf); | ||
122 | |||
123 | static ssize_t rmi_fn_01_datecode_show(struct device *dev, | ||
124 | struct device_attribute *attr, | ||
125 | char *buf); | ||
126 | |||
127 | static ssize_t rmi_fn_01_reportrate_show(struct device *dev, | ||
128 | struct device_attribute *attr, | ||
129 | char *buf); | ||
130 | |||
131 | static ssize_t rmi_fn_01_reportrate_store(struct device *dev, | ||
132 | struct device_attribute *attr, | ||
133 | const char *buf, size_t count); | ||
134 | |||
135 | static ssize_t rmi_fn_01_reset_store(struct device *dev, | ||
136 | struct device_attribute *attr, | ||
137 | const char *buf, size_t count); | ||
138 | |||
139 | static ssize_t rmi_fn_01_sleepmode_show(struct device *dev, | ||
140 | struct device_attribute *attr, | ||
141 | char *buf); | ||
142 | |||
143 | static ssize_t rmi_fn_01_sleepmode_store(struct device *dev, | ||
144 | struct device_attribute *attr, | ||
145 | const char *buf, size_t count); | ||
146 | |||
147 | static ssize_t rmi_fn_01_nosleep_show(struct device *dev, | ||
148 | struct device_attribute *attr, | ||
149 | char *buf); | ||
150 | |||
151 | static ssize_t rmi_fn_01_nosleep_store(struct device *dev, | ||
152 | struct device_attribute *attr, | ||
153 | const char *buf, size_t count); | ||
154 | |||
155 | static ssize_t rmi_fn_01_chargerinput_show(struct device *dev, | ||
156 | struct device_attribute *attr, | ||
157 | char *buf); | ||
158 | |||
159 | static ssize_t rmi_fn_01_chargerinput_store(struct device *dev, | ||
160 | struct device_attribute *attr, | ||
161 | const char *buf, size_t count); | ||
162 | |||
163 | static ssize_t rmi_fn_01_configured_show(struct device *dev, | ||
164 | struct device_attribute *attr, | ||
165 | char *buf); | ||
166 | |||
167 | static ssize_t rmi_fn_01_unconfigured_show(struct device *dev, | ||
168 | struct device_attribute *attr, | ||
169 | char *buf); | ||
170 | |||
171 | static ssize_t rmi_fn_01_flashprog_show(struct device *dev, | ||
172 | struct device_attribute *attr, | ||
173 | char *buf); | ||
174 | |||
175 | static ssize_t rmi_fn_01_statuscode_show(struct device *dev, | ||
176 | struct device_attribute *attr, | ||
177 | char *buf); | ||
178 | |||
179 | static struct device_attribute fn_01_attrs[] = { | ||
180 | __ATTR(productinfo, RMI_RO_ATTR, | ||
181 | rmi_fn_01_productinfo_show, rmi_store_error), | ||
182 | __ATTR(productid, RMI_RO_ATTR, | ||
183 | rmi_fn_01_productid_show, rmi_store_error), | ||
184 | __ATTR(manufacturer, RMI_RO_ATTR, | ||
185 | rmi_fn_01_manufacturer_show, rmi_store_error), | ||
186 | __ATTR(datecode, RMI_RO_ATTR, | ||
187 | rmi_fn_01_datecode_show, rmi_store_error), | ||
188 | |||
189 | /* control register access */ | ||
190 | __ATTR(sleepmode, RMI_RW_ATTR, | ||
191 | rmi_fn_01_sleepmode_show, rmi_fn_01_sleepmode_store), | ||
192 | __ATTR(nosleep, RMI_RW_ATTR, | ||
193 | rmi_fn_01_nosleep_show, rmi_fn_01_nosleep_store), | ||
194 | __ATTR(chargerinput, RMI_RW_ATTR, | ||
195 | rmi_fn_01_chargerinput_show, rmi_fn_01_chargerinput_store), | ||
196 | __ATTR(reportrate, RMI_RW_ATTR, | ||
197 | rmi_fn_01_reportrate_show, rmi_fn_01_reportrate_store), | ||
198 | /* We make report rate RO, since the driver uses that to look for | ||
199 | * resets. We don't want someone faking us out by changing that | ||
200 | * bit. | ||
201 | */ | ||
202 | __ATTR(configured, RMI_RO_ATTR, | ||
203 | rmi_fn_01_configured_show, rmi_store_error), | ||
204 | |||
205 | /* Command register access. */ | ||
206 | __ATTR(reset, RMI_WO_ATTR, | ||
207 | rmi_show_error, rmi_fn_01_reset_store), | ||
208 | |||
209 | /* STatus register access. */ | ||
210 | __ATTR(unconfigured, RMI_RO_ATTR, | ||
211 | rmi_fn_01_unconfigured_show, rmi_store_error), | ||
212 | __ATTR(flashprog, RMI_RO_ATTR, | ||
213 | rmi_fn_01_flashprog_show, rmi_store_error), | ||
214 | __ATTR(statuscode, RMI_RO_ATTR, | ||
215 | rmi_fn_01_statuscode_show, rmi_store_error), | ||
216 | }; | ||
217 | |||
218 | /* Utility routine to set the value of a bit field in a register. */ | ||
219 | int rmi_set_bit_field(struct rmi_device *rmi_dev, | ||
220 | unsigned short address, | ||
221 | unsigned char field_mask, | ||
222 | unsigned char bits) | ||
223 | { | ||
224 | unsigned char reg_contents; | ||
225 | int retval; | ||
226 | |||
227 | retval = rmi_read(rmi_dev, address, ®_contents); | ||
228 | if (retval) | ||
229 | return retval; | ||
230 | reg_contents = (reg_contents & ~field_mask) | bits; | ||
231 | retval = rmi_write(rmi_dev, address, reg_contents); | ||
232 | if (retval == 1) | ||
233 | return 0; | ||
234 | else if (retval == 0) | ||
235 | return -EIO; | ||
236 | return retval; | ||
237 | } | ||
238 | |||
239 | static ssize_t rmi_fn_01_productinfo_show(struct device *dev, | ||
240 | struct device_attribute *attr, | ||
241 | char *buf) | ||
242 | { | ||
243 | struct f01_data *data = NULL; | ||
244 | struct rmi_function_container *fc = to_rmi_function_container(dev); | ||
245 | |||
246 | data = fc->data; | ||
247 | |||
248 | return snprintf(buf, PAGE_SIZE, "0x%02x 0x%02x\n", | ||
249 | data->basic_queries.productinfo_1, | ||
250 | data->basic_queries.productinfo_2); | ||
251 | } | ||
252 | |||
253 | static ssize_t rmi_fn_01_productid_show(struct device *dev, | ||
254 | struct device_attribute *attr, | ||
255 | char *buf) | ||
256 | { | ||
257 | struct f01_data *data = NULL; | ||
258 | struct rmi_function_container *fc = to_rmi_function_container(dev); | ||
259 | |||
260 | data = fc->data; | ||
261 | |||
262 | return snprintf(buf, PAGE_SIZE, "%s\n", data->product_id); | ||
263 | } | ||
264 | |||
265 | static ssize_t rmi_fn_01_manufacturer_show(struct device *dev, | ||
266 | struct device_attribute *attr, | ||
267 | char *buf) | ||
268 | { | ||
269 | struct f01_data *data = NULL; | ||
270 | struct rmi_function_container *fc = to_rmi_function_container(dev); | ||
271 | |||
272 | data = fc->data; | ||
273 | |||
274 | return snprintf(buf, PAGE_SIZE, "0x%02x\n", | ||
275 | data->basic_queries.manufacturer_id); | ||
276 | } | ||
277 | |||
278 | static ssize_t rmi_fn_01_datecode_show(struct device *dev, | ||
279 | struct device_attribute *attr, | ||
280 | char *buf) | ||
281 | { | ||
282 | struct f01_data *data = NULL; | ||
283 | struct rmi_function_container *fc = to_rmi_function_container(dev); | ||
284 | |||
285 | data = fc->data; | ||
286 | |||
287 | return snprintf(buf, PAGE_SIZE, "20%02u-%02u-%02u\n", | ||
288 | data->basic_queries.year, | ||
289 | data->basic_queries.month, | ||
290 | data->basic_queries.day); | ||
291 | } | ||
292 | |||
293 | static ssize_t rmi_fn_01_reset_store(struct device *dev, | ||
294 | struct device_attribute *attr, | ||
295 | const char *buf, size_t count) | ||
296 | { | ||
297 | struct rmi_function_container *fc = NULL; | ||
298 | unsigned int reset; | ||
299 | int retval = 0; | ||
300 | /* Command register always reads as 0, so we can just use a local. */ | ||
301 | union f01_device_commands commands = {}; | ||
302 | |||
303 | fc = to_rmi_function_container(dev); | ||
304 | |||
305 | if (sscanf(buf, "%u", &reset) != 1) | ||
306 | return -EINVAL; | ||
307 | if (reset < 0 || reset > 1) | ||
308 | return -EINVAL; | ||
309 | |||
310 | /* Per spec, 0 has no effect, so we skip it entirely. */ | ||
311 | if (reset) { | ||
312 | commands.reset = 1; | ||
313 | retval = rmi_write_block(fc->rmi_dev, fc->fd.command_base_addr, | ||
314 | &commands.reg, sizeof(commands.reg)); | ||
315 | if (retval < 0) { | ||
316 | dev_err(dev, "%s: failed to issue reset command, " | ||
317 | "error = %d.", __func__, retval); | ||
318 | return retval; | ||
319 | } | ||
320 | } | ||
321 | |||
322 | return count; | ||
323 | } | ||
324 | |||
325 | static ssize_t rmi_fn_01_sleepmode_show(struct device *dev, | ||
326 | struct device_attribute *attr, | ||
327 | char *buf) | ||
328 | { | ||
329 | struct f01_data *data = NULL; | ||
330 | struct rmi_function_container *fc = to_rmi_function_container(dev); | ||
331 | |||
332 | data = fc->data; | ||
333 | |||
334 | return snprintf(buf, PAGE_SIZE, | ||
335 | "%d\n", data->device_control.sleep_mode); | ||
336 | } | ||
337 | |||
338 | static ssize_t rmi_fn_01_sleepmode_store(struct device *dev, | ||
339 | struct device_attribute *attr, | ||
340 | const char *buf, | ||
341 | size_t count) | ||
342 | { | ||
343 | struct f01_data *data = NULL; | ||
344 | unsigned long new_value; | ||
345 | int retval; | ||
346 | struct rmi_function_container *fc = to_rmi_function_container(dev); | ||
347 | |||
348 | data = fc->data; | ||
349 | |||
350 | retval = strict_strtoul(buf, 10, &new_value); | ||
351 | if (retval < 0 || !RMI_IS_VALID_SLEEPMODE(new_value)) { | ||
352 | dev_err(dev, "%s: Invalid sleep mode %s.", __func__, buf); | ||
353 | return -EINVAL; | ||
354 | } | ||
355 | |||
356 | dev_dbg(dev, "Setting sleep mode to %ld.", new_value); | ||
357 | data->device_control.sleep_mode = new_value; | ||
358 | retval = rmi_write_block(fc->rmi_dev, fc->fd.control_base_addr, | ||
359 | &data->device_control.reg, | ||
360 | sizeof(data->device_control.reg)); | ||
361 | if (retval >= 0) | ||
362 | retval = count; | ||
363 | else | ||
364 | dev_err(dev, "Failed to write sleep mode, code %d.\n", retval); | ||
365 | return retval; | ||
366 | } | ||
367 | |||
368 | static ssize_t rmi_fn_01_nosleep_show(struct device *dev, | ||
369 | struct device_attribute *attr, | ||
370 | char *buf) | ||
371 | { | ||
372 | struct f01_data *data = NULL; | ||
373 | struct rmi_function_container *fc = to_rmi_function_container(dev); | ||
374 | |||
375 | data = fc->data; | ||
376 | |||
377 | return snprintf(buf, PAGE_SIZE, "%d\n", data->device_control.nosleep); | ||
378 | } | ||
379 | |||
380 | static ssize_t rmi_fn_01_nosleep_store(struct device *dev, | ||
381 | struct device_attribute *attr, | ||
382 | const char *buf, | ||
383 | size_t count) | ||
384 | { | ||
385 | struct f01_data *data = NULL; | ||
386 | unsigned long new_value; | ||
387 | int retval; | ||
388 | struct rmi_function_container *fc = to_rmi_function_container(dev); | ||
389 | |||
390 | data = fc->data; | ||
391 | |||
392 | retval = strict_strtoul(buf, 10, &new_value); | ||
393 | if (retval < 0 || new_value < 0 || new_value > 1) { | ||
394 | dev_err(dev, "%s: Invalid nosleep bit %s.", __func__, buf); | ||
395 | return -EINVAL; | ||
396 | } | ||
397 | |||
398 | data->device_control.nosleep = new_value; | ||
399 | retval = rmi_write_block(fc->rmi_dev, fc->fd.control_base_addr, | ||
400 | &data->device_control.reg, | ||
401 | sizeof(data->device_control.reg)); | ||
402 | if (retval >= 0) | ||
403 | retval = count; | ||
404 | else | ||
405 | dev_err(dev, "Failed to write nosleep bit.\n"); | ||
406 | return retval; | ||
407 | } | ||
408 | |||
409 | static ssize_t rmi_fn_01_chargerinput_show(struct device *dev, | ||
410 | struct device_attribute *attr, | ||
411 | char *buf) | ||
412 | { | ||
413 | struct f01_data *data = NULL; | ||
414 | struct rmi_function_container *fc = to_rmi_function_container(dev); | ||
415 | |||
416 | data = fc->data; | ||
417 | |||
418 | return snprintf(buf, PAGE_SIZE, "%d\n", | ||
419 | data->device_control.charger_input); | ||
420 | } | ||
421 | |||
422 | static ssize_t rmi_fn_01_chargerinput_store(struct device *dev, | ||
423 | struct device_attribute *attr, | ||
424 | const char *buf, | ||
425 | size_t count) | ||
426 | { | ||
427 | struct f01_data *data = NULL; | ||
428 | unsigned long new_value; | ||
429 | int retval; | ||
430 | struct rmi_function_container *fc = to_rmi_function_container(dev); | ||
431 | |||
432 | data = fc->data; | ||
433 | |||
434 | retval = strict_strtoul(buf, 10, &new_value); | ||
435 | if (retval < 0 || new_value < 0 || new_value > 1) { | ||
436 | dev_err(dev, "%s: Invalid chargerinput bit %s.", __func__, buf); | ||
437 | return -EINVAL; | ||
438 | } | ||
439 | |||
440 | data->device_control.charger_input = new_value; | ||
441 | retval = rmi_write_block(fc->rmi_dev, fc->fd.control_base_addr, | ||
442 | &data->device_control.reg, | ||
443 | sizeof(data->device_control.reg)); | ||
444 | if (retval >= 0) | ||
445 | retval = count; | ||
446 | else | ||
447 | dev_err(dev, "Failed to write chargerinput bit.\n"); | ||
448 | return retval; | ||
449 | } | ||
450 | |||
451 | static ssize_t rmi_fn_01_reportrate_show(struct device *dev, | ||
452 | struct device_attribute *attr, | ||
453 | char *buf) | ||
454 | { | ||
455 | struct f01_data *data = NULL; | ||
456 | struct rmi_function_container *fc = to_rmi_function_container(dev); | ||
457 | |||
458 | data = fc->data; | ||
459 | |||
460 | return snprintf(buf, PAGE_SIZE, "%d\n", | ||
461 | data->device_control.report_rate); | ||
462 | } | ||
463 | |||
464 | static ssize_t rmi_fn_01_reportrate_store(struct device *dev, | ||
465 | struct device_attribute *attr, | ||
466 | const char *buf, | ||
467 | size_t count) | ||
468 | { | ||
469 | struct f01_data *data = NULL; | ||
470 | unsigned long new_value; | ||
471 | int retval; | ||
472 | struct rmi_function_container *fc = to_rmi_function_container(dev); | ||
473 | |||
474 | data = fc->data; | ||
475 | |||
476 | retval = strict_strtoul(buf, 10, &new_value); | ||
477 | if (retval < 0 || new_value < 0 || new_value > 1) { | ||
478 | dev_err(dev, "%s: Invalid reportrate bit %s.", __func__, buf); | ||
479 | return -EINVAL; | ||
480 | } | ||
481 | |||
482 | data->device_control.report_rate = new_value; | ||
483 | retval = rmi_write_block(fc->rmi_dev, fc->fd.control_base_addr, | ||
484 | &data->device_control.reg, | ||
485 | sizeof(data->device_control.reg)); | ||
486 | if (retval >= 0) | ||
487 | retval = count; | ||
488 | else | ||
489 | dev_err(dev, "Failed to write reportrate bit.\n"); | ||
490 | return retval; | ||
491 | } | ||
492 | |||
493 | static ssize_t rmi_fn_01_configured_show(struct device *dev, | ||
494 | struct device_attribute *attr, | ||
495 | char *buf) | ||
496 | { | ||
497 | struct f01_data *data = NULL; | ||
498 | struct rmi_function_container *fc = to_rmi_function_container(dev); | ||
499 | |||
500 | data = fc->data; | ||
501 | |||
502 | return snprintf(buf, PAGE_SIZE, "%d\n", | ||
503 | data->device_control.configured); | ||
504 | } | ||
505 | |||
506 | static ssize_t rmi_fn_01_unconfigured_show(struct device *dev, | ||
507 | struct device_attribute *attr, | ||
508 | char *buf) | ||
509 | { | ||
510 | struct f01_data *data = NULL; | ||
511 | struct rmi_function_container *fc = to_rmi_function_container(dev); | ||
512 | |||
513 | data = fc->data; | ||
514 | |||
515 | return snprintf(buf, PAGE_SIZE, "%d\n", | ||
516 | data->device_status.unconfigured); | ||
517 | } | ||
518 | |||
519 | static ssize_t rmi_fn_01_flashprog_show(struct device *dev, | ||
520 | struct device_attribute *attr, | ||
521 | char *buf) | ||
522 | { | ||
523 | struct f01_data *data = NULL; | ||
524 | struct rmi_function_container *fc = to_rmi_function_container(dev); | ||
525 | |||
526 | data = fc->data; | ||
527 | |||
528 | return snprintf(buf, PAGE_SIZE, "%d\n", | ||
529 | data->device_status.flash_prog); | ||
530 | } | ||
531 | |||
532 | static ssize_t rmi_fn_01_statuscode_show(struct device *dev, | ||
533 | struct device_attribute *attr, | ||
534 | char *buf) | ||
535 | { | ||
536 | struct f01_data *data = NULL; | ||
537 | struct rmi_function_container *fc = to_rmi_function_container(dev); | ||
538 | |||
539 | data = fc->data; | ||
540 | |||
541 | return snprintf(buf, PAGE_SIZE, "0x%02x\n", | ||
542 | data->device_status.status_code); | ||
543 | } | ||
544 | |||
545 | int rmi_driver_f01_init(struct rmi_device *rmi_dev) | ||
546 | { | ||
547 | struct rmi_driver_data *driver_data = rmi_get_driverdata(rmi_dev); | ||
548 | struct rmi_function_container *fc = driver_data->f01_container; | ||
549 | struct f01_data *data; | ||
550 | int error; | ||
551 | u8 temp; | ||
552 | int attr_count; | ||
553 | |||
554 | data = kzalloc(sizeof(struct f01_data), GFP_KERNEL); | ||
555 | if (!data) { | ||
556 | dev_err(&rmi_dev->dev, "Failed to allocate F01 data.\n"); | ||
557 | return -ENOMEM; | ||
558 | } | ||
559 | fc->data = data; | ||
560 | |||
561 | /* Set the configured bit. */ | ||
562 | error = rmi_read_block(rmi_dev, fc->fd.control_base_addr, | ||
563 | &data->device_control.reg, | ||
564 | sizeof(data->device_control.reg)); | ||
565 | if (error < 0) { | ||
566 | dev_err(&fc->dev, "Failed to read F01 control.\n"); | ||
567 | goto error_exit; | ||
568 | } | ||
569 | |||
570 | /* Sleep mode might be set as a hangover from a system crash or | ||
571 | * reboot without power cycle. If so, clear it so the sensor | ||
572 | * is certain to function. | ||
573 | */ | ||
574 | if (data->device_control.sleep_mode != RMI_SLEEP_MODE_NORMAL) { | ||
575 | dev_warn(&fc->dev, | ||
576 | "WARNING: Non-zero sleep mode found. Clearing...\n"); | ||
577 | data->device_control.sleep_mode = RMI_SLEEP_MODE_NORMAL; | ||
578 | } | ||
579 | |||
580 | data->device_control.configured = 1; | ||
581 | error = rmi_write_block(rmi_dev, fc->fd.control_base_addr, | ||
582 | &data->device_control.reg, | ||
583 | sizeof(data->device_control.reg)); | ||
584 | if (error < 0) { | ||
585 | dev_err(&fc->dev, "Failed to write F01 control.\n"); | ||
586 | goto error_exit; | ||
587 | } | ||
588 | |||
589 | /* dummy read in order to clear irqs */ | ||
590 | error = rmi_read(rmi_dev, fc->fd.data_base_addr + 1, &temp); | ||
591 | if (error < 0) { | ||
592 | dev_err(&fc->dev, "Failed to read Interrupt Status.\n"); | ||
593 | goto error_exit; | ||
594 | } | ||
595 | |||
596 | error = rmi_read_block(rmi_dev, fc->fd.query_base_addr, | ||
597 | data->basic_queries.regs, | ||
598 | sizeof(data->basic_queries.regs)); | ||
599 | if (error < 0) { | ||
600 | dev_err(&fc->dev, "Failed to read device query registers.\n"); | ||
601 | goto error_exit; | ||
602 | } | ||
603 | driver_data->manufacturer_id = data->basic_queries.manufacturer_id; | ||
604 | |||
605 | error = rmi_read_block(rmi_dev, | ||
606 | fc->fd.query_base_addr + sizeof(data->basic_queries.regs), | ||
607 | data->product_id, RMI_PRODUCT_ID_LENGTH); | ||
608 | if (error < 0) { | ||
609 | dev_err(&fc->dev, "Failed to read product ID.\n"); | ||
610 | goto error_exit; | ||
611 | } | ||
612 | data->product_id[RMI_PRODUCT_ID_LENGTH] = '\0'; | ||
613 | memcpy(driver_data->product_id, data->product_id, | ||
614 | sizeof(data->product_id)); | ||
615 | |||
616 | error = rmi_read_block(rmi_dev, fc->fd.data_base_addr, | ||
617 | &data->device_status.reg, | ||
618 | sizeof(data->device_status.reg)); | ||
619 | if (error < 0) { | ||
620 | dev_err(&fc->dev, "Failed to read device status.\n"); | ||
621 | goto error_exit; | ||
622 | } | ||
623 | if (data->device_status.unconfigured) { | ||
624 | dev_err(&fc->dev, | ||
625 | "Device reset during configuration process, status: " | ||
626 | "%#02x!\n", data->device_status.status_code); | ||
627 | error = -EINVAL; | ||
628 | goto error_exit; | ||
629 | } | ||
630 | /* | ||
631 | ** attach the routines that handle sysfs interaction | ||
632 | ** Meaning: Set up sysfs device attributes. | ||
633 | */ | ||
634 | for (attr_count = 0; attr_count < ARRAY_SIZE(fn_01_attrs); | ||
635 | attr_count++) { | ||
636 | if (sysfs_create_file(&fc->dev.kobj, | ||
637 | &fn_01_attrs[attr_count].attr) < 0) { | ||
638 | dev_err(&fc->dev, "Failed to create sysfs file for %s.", | ||
639 | fn_01_attrs[attr_count].attr.name); | ||
640 | error = -ENODEV; | ||
641 | goto error_exit; | ||
642 | } | ||
643 | } | ||
644 | |||
645 | return error; | ||
646 | |||
647 | error_exit: | ||
648 | kfree(data); | ||
649 | return error; | ||
650 | } | ||
651 | |||
652 | #ifdef CONFIG_PM | ||
653 | |||
654 | static int rmi_f01_suspend(struct rmi_function_container *fc) | ||
655 | { | ||
656 | struct rmi_device *rmi_dev = fc->rmi_dev; | ||
657 | struct rmi_driver_data *driver_data = rmi_get_driverdata(rmi_dev); | ||
658 | struct f01_data *data = driver_data->f01_container->data; | ||
659 | int retval = 0; | ||
660 | |||
661 | dev_dbg(&fc->dev, "Suspending...\n"); | ||
662 | if (data->suspended) | ||
663 | return 0; | ||
664 | |||
665 | data->old_nosleep = data->device_control.nosleep; | ||
666 | data->device_control.nosleep = 0; | ||
667 | data->device_control.sleep_mode = RMI_SLEEP_MODE_SENSOR_SLEEP; | ||
668 | |||
669 | retval = rmi_write_block(rmi_dev, | ||
670 | driver_data->f01_container->fd.control_base_addr, | ||
671 | &data->device_control.reg, | ||
672 | sizeof(data->device_control.reg)); | ||
673 | if (retval < 0) { | ||
674 | dev_err(&fc->dev, "Failed to write sleep mode. " | ||
675 | "Code: %d.\n", retval); | ||
676 | data->device_control.nosleep = data->old_nosleep; | ||
677 | data->device_control.sleep_mode = RMI_SLEEP_MODE_NORMAL; | ||
678 | } else { | ||
679 | data->suspended = true; | ||
680 | retval = 0; | ||
681 | } | ||
682 | |||
683 | return retval; | ||
684 | } | ||
685 | |||
686 | static int rmi_f01_resume(struct rmi_function_container *fc) | ||
687 | { | ||
688 | struct rmi_device *rmi_dev = fc->rmi_dev; | ||
689 | struct rmi_driver_data *driver_data = rmi_get_driverdata(rmi_dev); | ||
690 | struct f01_data *data = driver_data->f01_container->data; | ||
691 | int retval = 0; | ||
692 | |||
693 | dev_dbg(&fc->dev, "Resuming...\n"); | ||
694 | if (!data->suspended) | ||
695 | return 0; | ||
696 | |||
697 | data->device_control.nosleep = data->old_nosleep; | ||
698 | data->device_control.sleep_mode = RMI_SLEEP_MODE_NORMAL; | ||
699 | |||
700 | retval = rmi_write_block(rmi_dev, | ||
701 | driver_data->f01_container->fd.control_base_addr, | ||
702 | &data->device_control.reg, | ||
703 | sizeof(data->device_control.reg)); | ||
704 | if (retval < 0) | ||
705 | dev_err(&fc->dev, "Failed to restore normal operation. " | ||
706 | "Code: %d.\n", retval); | ||
707 | else { | ||
708 | data->suspended = false; | ||
709 | retval = 0; | ||
710 | } | ||
711 | |||
712 | return retval; | ||
713 | } | ||
714 | #endif /* CONFIG_PM */ | ||
715 | |||
716 | static int rmi_f01_init(struct rmi_function_container *fc) | ||
717 | { | ||
718 | return 0; | ||
719 | } | ||
720 | |||
721 | static int rmi_f01_attention(struct rmi_function_container *fc, u8 *irq_bits) | ||
722 | { | ||
723 | struct rmi_device *rmi_dev = fc->rmi_dev; | ||
724 | struct f01_data *data = fc->data; | ||
725 | int error; | ||
726 | |||
727 | error = rmi_read_block(rmi_dev, fc->fd.data_base_addr, | ||
728 | &data->device_status.reg, | ||
729 | sizeof(data->device_status.reg)); | ||
730 | if (error < 0) { | ||
731 | dev_err(&fc->dev, "Failed to read device status.\n"); | ||
732 | return error; | ||
733 | } | ||
734 | |||
735 | /* TODO: Do we handle reset here or elsewhere? */ | ||
736 | if (data->device_status.unconfigured) | ||
737 | dev_warn(&rmi_dev->dev, "Reset detected! Status code: %#04x.\n", | ||
738 | data->device_status.status_code); | ||
739 | return 0; | ||
740 | } | ||
741 | |||
742 | static struct rmi_function_handler function_handler = { | ||
743 | .func = 0x01, | ||
744 | .init = rmi_f01_init, | ||
745 | .attention = rmi_f01_attention, | ||
746 | #ifdef CONFIG_PM | ||
747 | .suspend = rmi_f01_suspend, | ||
748 | .resume = rmi_f01_resume, | ||
749 | #endif | ||
750 | }; | ||
751 | |||
752 | static int __init rmi_f01_module_init(void) | ||
753 | { | ||
754 | int error; | ||
755 | |||
756 | error = rmi_register_function_driver(&function_handler); | ||
757 | if (error < 0) { | ||
758 | pr_err("%s: register failed!\n", __func__); | ||
759 | return error; | ||
760 | } | ||
761 | |||
762 | return 0; | ||
763 | } | ||
764 | |||
765 | static void __exit rmi_f01_module_exit(void) | ||
766 | { | ||
767 | rmi_unregister_function_driver(&function_handler); | ||
768 | } | ||
769 | |||
770 | module_init(rmi_f01_module_init); | ||
771 | module_exit(rmi_f01_module_exit); | ||
772 | |||
773 | MODULE_AUTHOR("Christopher Heiny <cheiny@synaptics.com>"); | ||
774 | MODULE_DESCRIPTION("RMI F01 module"); | ||
775 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/rmi4/rmi_f09.c b/drivers/input/touchscreen/rmi4/rmi_f09.c new file mode 100644 index 00000000000..0ec980d7db0 --- /dev/null +++ b/drivers/input/touchscreen/rmi4/rmi_f09.c | |||
@@ -0,0 +1,298 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Synaptics Incorporated | ||
3 | * Copyright (c) 2011 Unixphere | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/rmi.h> | ||
21 | #include <linux/input.h> | ||
22 | #include <linux/slab.h> | ||
23 | |||
24 | #define QUERY_BASE_INDEX 1 | ||
25 | #define MAX_LEN 256 | ||
26 | |||
27 | /* data specific to fn $09 that needs to be kept around */ | ||
28 | struct f09_query { | ||
29 | u8 Limit_Register_Count; | ||
30 | union { | ||
31 | struct { | ||
32 | u8 Result_Register_Count:3; | ||
33 | u8 Reserved:3; | ||
34 | u8 InternalLimits:1; | ||
35 | u8 HostTestEn:1; | ||
36 | }; | ||
37 | u8 f09_bist_query1; | ||
38 | }; | ||
39 | }; | ||
40 | |||
41 | struct f09_control { | ||
42 | /* test1 */ | ||
43 | u8 Test1LimitLo; | ||
44 | u8 Test1LimitHi; | ||
45 | u8 Test1LimitDiff; | ||
46 | /* test2 */ | ||
47 | u8 Test2LimitLo; | ||
48 | u8 Test2LimitHi; | ||
49 | u8 Test2LimitDiff; | ||
50 | }; | ||
51 | |||
52 | struct f09_data { | ||
53 | u8 TestNumberControl; | ||
54 | u8 Overall_BIST_Result; | ||
55 | u8 TestResult1; | ||
56 | u8 TestResult2; | ||
57 | u8 Transmitter_Number; | ||
58 | |||
59 | union { | ||
60 | struct { | ||
61 | u8 Receiver_Number:6; | ||
62 | u8 Limit_Failure_Code:2; | ||
63 | }; | ||
64 | u8 f09_bist_data2; | ||
65 | }; | ||
66 | }; | ||
67 | |||
68 | struct f09_cmd { | ||
69 | union { | ||
70 | struct { | ||
71 | u8 RunBIST:1; | ||
72 | }; | ||
73 | u8 f09_bist_cmd0; | ||
74 | }; | ||
75 | }; | ||
76 | |||
77 | struct rmi_fn_09_data { | ||
78 | struct f09_query query; | ||
79 | }; | ||
80 | |||
81 | static ssize_t rmi_f09_Limit_Register_Count_show(struct device *dev, | ||
82 | struct device_attribute *attr, char *buf); | ||
83 | |||
84 | static ssize_t rmi_f09_HostTestEn_show(struct device *dev, | ||
85 | struct device_attribute *attr, char *buf); | ||
86 | |||
87 | static ssize_t rmi_f09_HostTestEn_store(struct device *dev, | ||
88 | struct device_attribute *attr, | ||
89 | char *buf, size_t count); | ||
90 | |||
91 | static ssize_t rmi_f09_InternalLimits_show(struct device *dev, | ||
92 | struct device_attribute *attr, char *buf); | ||
93 | |||
94 | static ssize_t rmi_f09_Result_Register_Count_show(struct device *dev, | ||
95 | struct device_attribute *attr, char *buf); | ||
96 | |||
97 | static ssize_t rmi_f09_Overall_BIST_Result_show(struct device *dev, | ||
98 | struct device_attribute *attr, char *buf); | ||
99 | |||
100 | static ssize_t rmi_f09_Overall_BIST_Result_store(struct device *dev, | ||
101 | struct device_attribute *attr, | ||
102 | const char *buf, size_t count); | ||
103 | |||
104 | static struct device_attribute attrs[] = { | ||
105 | __ATTR(Limit_Register_Count, RMI_RO_ATTR, | ||
106 | rmi_f09_Limit_Register_Count_show, rmi_store_error), | ||
107 | __ATTR(HostTestEn, RMI_RW_ATTR, | ||
108 | rmi_f09_HostTestEn_show, rmi_f09_HostTestEn_store), | ||
109 | __ATTR(InternalLimits, RMI_RO_ATTR, | ||
110 | rmi_f09_Limit_Register_Count_show, rmi_store_error), | ||
111 | __ATTR(Result_Register_Count, RMI_RO_ATTR, | ||
112 | rmi_f09_Result_Register_Count_show, rmi_store_error), | ||
113 | }; | ||
114 | |||
115 | static int rmi_f09_init(struct rmi_function_container *fc) | ||
116 | { | ||
117 | struct rmi_device *rmi_dev = fc->rmi_dev; | ||
118 | struct rmi_device_platform_data *pdata; | ||
119 | struct rmi_fn_09_data *f09; | ||
120 | u8 query_base_addr; | ||
121 | int rc; | ||
122 | int i; | ||
123 | int attr_count = 0; | ||
124 | int retval = 0; | ||
125 | |||
126 | dev_info(&fc->dev, "Intializing F09 values."); | ||
127 | |||
128 | f09 = kzalloc(sizeof(struct rmi_fn_09_data), GFP_KERNEL); | ||
129 | if (!f09) { | ||
130 | dev_err(&fc->dev, "Failed to allocate rmi_fn_09_data.\n"); | ||
131 | retval = -ENOMEM; | ||
132 | goto error_exit; | ||
133 | } | ||
134 | fc->data = f09; | ||
135 | |||
136 | pdata = to_rmi_platform_data(rmi_dev); | ||
137 | query_base_addr = fc->fd.query_base_addr; | ||
138 | |||
139 | /* initial all default values for f09 query here */ | ||
140 | rc = rmi_read_block(rmi_dev, query_base_addr, | ||
141 | (u8 *)&f09->query, sizeof(f09->query)); | ||
142 | if (rc < 0) { | ||
143 | dev_err(&fc->dev, "Failed to read query register." | ||
144 | " from 0x%04x\n", query_base_addr); | ||
145 | goto error_exit; | ||
146 | } | ||
147 | |||
148 | dev_dbg(&fc->dev, "Creating sysfs files."); | ||
149 | /* Set up sysfs device attributes. */ | ||
150 | for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { | ||
151 | if (sysfs_create_file | ||
152 | (&fc->dev.kobj, &attrs[attr_count].attr) < 0) { | ||
153 | dev_err(&fc->dev, "Failed to create sysfs file for %s.", | ||
154 | attrs[attr_count].attr.name); | ||
155 | retval = -ENODEV; | ||
156 | goto error_exit; | ||
157 | } | ||
158 | } | ||
159 | return 0; | ||
160 | |||
161 | error_exit: | ||
162 | dev_err(&fc->dev, "An error occured in F09 init!\n"); | ||
163 | for (attr_count--; attr_count >= 0; attr_count--) | ||
164 | sysfs_remove_file(&fc->dev.kobj, | ||
165 | &attrs[attr_count].attr); | ||
166 | kfree(f09); | ||
167 | return retval; | ||
168 | } | ||
169 | |||
170 | static void rmi_f09_remove(struct rmi_function_container *fc) | ||
171 | { | ||
172 | struct rmi_fn_09_data *data = fc->data; | ||
173 | if (data) { | ||
174 | kfree(data->query.Limit_Register_Count); | ||
175 | kfree(data->query.f09_bist_query1); | ||
176 | } | ||
177 | kfree(fc->data); | ||
178 | } | ||
179 | |||
180 | static struct rmi_function_handler function_handler = { | ||
181 | .func = 0x09, | ||
182 | .init = rmi_f09_init, | ||
183 | .remove = rmi_f09_remove | ||
184 | }; | ||
185 | |||
186 | static int __init rmi_f09_module_init(void) | ||
187 | { | ||
188 | int error; | ||
189 | |||
190 | error = rmi_register_function_driver(&function_handler); | ||
191 | if (error < 0) { | ||
192 | pr_err("%s: register failed!\n", __func__); | ||
193 | return error; | ||
194 | } | ||
195 | |||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | static void rmi_f09_module_exit(void) | ||
200 | { | ||
201 | rmi_unregister_function_driver(&function_handler); | ||
202 | } | ||
203 | |||
204 | |||
205 | static ssize_t rmi_f09_Limit_Register_Count_show(struct device *dev, | ||
206 | struct device_attribute *attr, | ||
207 | char *buf) | ||
208 | { | ||
209 | struct rmi_function_container *fc; | ||
210 | struct rmi_fn_09_data *data; | ||
211 | |||
212 | fc = to_rmi_function_container(dev); | ||
213 | data = fc->data; | ||
214 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
215 | data->query.Limit_Register_Count); | ||
216 | } | ||
217 | |||
218 | static ssize_t rmi_f09_HostTestEn_show(struct device *dev, | ||
219 | struct device_attribute *attr, | ||
220 | char *buf) | ||
221 | { | ||
222 | struct rmi_function_container *fc; | ||
223 | struct rmi_fn_09_data *data; | ||
224 | |||
225 | fc = to_rmi_function_container(dev); | ||
226 | data = fc->data; | ||
227 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
228 | data->query.HostTestEn); | ||
229 | } | ||
230 | |||
231 | static ssize_t rmi_f09_HostTestEn_store(struct device *dev, | ||
232 | struct device_attribute *attr, | ||
233 | char *buf, size_t count) | ||
234 | { | ||
235 | struct rmi_function_container *fc; | ||
236 | struct rmi_fn_09_data *data; | ||
237 | unsigned int new_value; | ||
238 | int result; | ||
239 | |||
240 | fc = to_rmi_function_container(dev); | ||
241 | data = fc->data; | ||
242 | if (sscanf(buf, "%u", &new_value) != 1) { | ||
243 | dev_err(dev, | ||
244 | "%s: Error - HostTestEn_store has an " | ||
245 | "invalid len.\n", | ||
246 | __func__); | ||
247 | return -EINVAL; | ||
248 | } | ||
249 | |||
250 | if (new_value < 0 || new_value > 1) { | ||
251 | dev_err(dev, "%s: Invalid HostTestEn bit %s.", __func__, buf); | ||
252 | return -EINVAL; | ||
253 | } | ||
254 | data->query.HostTestEn = new_value; | ||
255 | result = rmi_write(fc->rmi_dev, fc->fd.query_base_addr, | ||
256 | data->query.HostTestEn); | ||
257 | if (result < 0) { | ||
258 | dev_err(dev, "%s : Could not write HostTestEn_store to 0x%x\n", | ||
259 | __func__, fc->fd.query_base_addr); | ||
260 | return result; | ||
261 | } | ||
262 | |||
263 | return count; | ||
264 | |||
265 | } | ||
266 | |||
267 | static ssize_t rmi_f09_InternalLimits_show(struct device *dev, | ||
268 | struct device_attribute *attr, | ||
269 | char *buf) | ||
270 | { | ||
271 | struct rmi_function_container *fc; | ||
272 | struct rmi_fn_09_data *data; | ||
273 | |||
274 | fc = to_rmi_function_container(dev); | ||
275 | data = fc->data; | ||
276 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
277 | data->query.InternalLimits); | ||
278 | } | ||
279 | |||
280 | static ssize_t rmi_f09_Result_Register_Count_show(struct device *dev, | ||
281 | struct device_attribute *attr, | ||
282 | char *buf) | ||
283 | { | ||
284 | struct rmi_function_container *fc; | ||
285 | struct rmi_fn_09_data *data; | ||
286 | |||
287 | fc = to_rmi_function_container(dev); | ||
288 | data = fc->data; | ||
289 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
290 | data->query.Result_Register_Count); | ||
291 | } | ||
292 | |||
293 | module_init(rmi_f09_module_init); | ||
294 | module_exit(rmi_f09_module_exit); | ||
295 | |||
296 | MODULE_AUTHOR("Allie Xiong <axiong@Synaptics.com>"); | ||
297 | MODULE_DESCRIPTION("RMI F09 module"); | ||
298 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/rmi4/rmi_f11.c b/drivers/input/touchscreen/rmi4/rmi_f11.c new file mode 100644 index 00000000000..35bb945143d --- /dev/null +++ b/drivers/input/touchscreen/rmi4/rmi_f11.c | |||
@@ -0,0 +1,1513 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Synaptics Incorporated | ||
3 | * Copyright (c) 2011 Unixphere | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/input.h> | ||
23 | #include <linux/rmi.h> | ||
24 | |||
25 | #define F11_MAX_NUM_OF_SENSORS 8 | ||
26 | #define F11_MAX_NUM_OF_FINGERS 10 | ||
27 | #define F11_MAX_NUM_OF_TOUCH_SHAPES 16 | ||
28 | |||
29 | #define F11_REL_POS_MIN -128 | ||
30 | #define F11_REL_POS_MAX 127 | ||
31 | |||
32 | #define F11_FINGER_STATE_MASK 0x03 | ||
33 | #define F11_FINGER_STATE_SIZE 0x02 | ||
34 | #define F11_FINGER_STATE_MASK_N(i) \ | ||
35 | (F11_FINGER_STATE_MASK << (i%4 * F11_FINGER_STATE_SIZE)) | ||
36 | |||
37 | #define F11_FINGER_STATE_VAL_N(f_state, i) \ | ||
38 | (f_state >> (i%4 * F11_FINGER_STATE_SIZE)) | ||
39 | |||
40 | #define F11_CTRL_SENSOR_MAX_X_POS_OFFSET 6 | ||
41 | #define F11_CTRL_SENSOR_MAX_Y_POS_OFFSET 8 | ||
42 | |||
43 | #define F11_CEIL(x, y) (((x) + ((y)-1)) / (y)) | ||
44 | |||
45 | /* By default, we'll support two fingers if we can't figure out how many we | ||
46 | * really need to handle. | ||
47 | */ | ||
48 | #define DEFAULT_NR_OF_FINGERS 2 | ||
49 | #define DEFAULT_XY_MAX 9999 | ||
50 | #define DEFAULT_MAX_ABS_MT_PRESSURE 255 | ||
51 | #define DEFAULT_MAX_ABS_MT_TOUCH 15 | ||
52 | #define DEFAULT_MAX_ABS_MT_ORIENTATION 1 | ||
53 | #define DEFAULT_MIN_ABS_MT_TRACKING_ID 1 | ||
54 | #define DEFAULT_MAX_ABS_MT_TRACKING_ID 10 | ||
55 | #define MAX_LEN 256 | ||
56 | |||
57 | static ssize_t rmi_fn_11_flip_show(struct device *dev, | ||
58 | struct device_attribute *attr, char *buf); | ||
59 | |||
60 | static ssize_t rmi_fn_11_flip_store(struct device *dev, | ||
61 | struct device_attribute *attr, | ||
62 | const char *buf, size_t count); | ||
63 | |||
64 | static ssize_t rmi_fn_11_clip_show(struct device *dev, | ||
65 | struct device_attribute *attr, char *buf); | ||
66 | |||
67 | static ssize_t rmi_fn_11_clip_store(struct device *dev, | ||
68 | struct device_attribute *attr, | ||
69 | const char *buf, size_t count); | ||
70 | |||
71 | static ssize_t rmi_fn_11_offset_show(struct device *dev, | ||
72 | struct device_attribute *attr, char *buf); | ||
73 | |||
74 | static ssize_t rmi_fn_11_offset_store(struct device *dev, | ||
75 | struct device_attribute *attr, | ||
76 | const char *buf, size_t count); | ||
77 | |||
78 | static ssize_t rmi_fn_11_swap_show(struct device *dev, | ||
79 | struct device_attribute *attr, char *buf); | ||
80 | |||
81 | static ssize_t rmi_fn_11_swap_store(struct device *dev, | ||
82 | struct device_attribute *attr, | ||
83 | const char *buf, size_t count); | ||
84 | |||
85 | static ssize_t rmi_fn_11_relreport_show(struct device *dev, | ||
86 | struct device_attribute *attr, | ||
87 | char *buf); | ||
88 | |||
89 | static ssize_t rmi_fn_11_relreport_store(struct device *dev, | ||
90 | struct device_attribute *attr, | ||
91 | const char *buf, size_t count); | ||
92 | |||
93 | static ssize_t rmi_fn_11_maxPos_show(struct device *dev, | ||
94 | struct device_attribute *attr, char *buf); | ||
95 | |||
96 | static ssize_t rmi_f11_rezero_store(struct device *dev, | ||
97 | struct device_attribute *attr, | ||
98 | const char *buf, size_t count); | ||
99 | |||
100 | |||
101 | static struct device_attribute attrs[] = { | ||
102 | __ATTR(flip, RMI_RW_ATTR, rmi_fn_11_flip_show, rmi_fn_11_flip_store), | ||
103 | __ATTR(clip, RMI_RW_ATTR, rmi_fn_11_clip_show, rmi_fn_11_clip_store), | ||
104 | __ATTR(offset, RMI_RW_ATTR, | ||
105 | rmi_fn_11_offset_show, rmi_fn_11_offset_store), | ||
106 | __ATTR(swap, RMI_RW_ATTR, rmi_fn_11_swap_show, rmi_fn_11_swap_store), | ||
107 | __ATTR(relreport, RMI_RW_ATTR, | ||
108 | rmi_fn_11_relreport_show, rmi_fn_11_relreport_store), | ||
109 | __ATTR(maxPos, RMI_RO_ATTR, rmi_fn_11_maxPos_show, rmi_store_error), | ||
110 | __ATTR(rezero, RMI_WO_ATTR, rmi_show_error, rmi_f11_rezero_store) | ||
111 | }; | ||
112 | |||
113 | |||
114 | union f11_2d_commands { | ||
115 | struct { | ||
116 | u8 rezero:1; | ||
117 | }; | ||
118 | u8 reg; | ||
119 | }; | ||
120 | |||
121 | |||
122 | struct f11_2d_device_query { | ||
123 | union { | ||
124 | struct { | ||
125 | u8 nbr_of_sensors:3; | ||
126 | u8 has_query9:1; | ||
127 | u8 has_query11:1; | ||
128 | }; | ||
129 | u8 f11_2d_query0; | ||
130 | }; | ||
131 | |||
132 | u8 f11_2d_query9; | ||
133 | |||
134 | union { | ||
135 | struct { | ||
136 | u8 has_z_tuning:1; | ||
137 | u8 has_pos_interpolation_tuning:1; | ||
138 | u8 has_w_tuning:1; | ||
139 | u8 has_pitch_info:1; | ||
140 | u8 has_default_finger_width:1; | ||
141 | u8 has_segmentation_aggressiveness:1; | ||
142 | u8 has_tx_rw_clip:1; | ||
143 | u8 has_drumming_correction:1; | ||
144 | }; | ||
145 | u8 f11_2d_query11; | ||
146 | }; | ||
147 | }; | ||
148 | |||
149 | struct f11_2d_sensor_query { | ||
150 | union { | ||
151 | struct { | ||
152 | /* query1 */ | ||
153 | u8 number_of_fingers:3; | ||
154 | u8 has_rel:1; | ||
155 | u8 has_abs:1; | ||
156 | u8 has_gestures:1; | ||
157 | u8 has_sensitivity_adjust:1; | ||
158 | u8 configurable:1; | ||
159 | /* query2 */ | ||
160 | u8 num_of_x_electrodes:7; | ||
161 | /* query3 */ | ||
162 | u8 num_of_y_electrodes:7; | ||
163 | /* query4 */ | ||
164 | u8 max_electrodes:7; | ||
165 | }; | ||
166 | u8 f11_2d_query1__4[4]; | ||
167 | }; | ||
168 | |||
169 | union { | ||
170 | struct { | ||
171 | u8 abs_data_size:3; | ||
172 | u8 has_anchored_finger:1; | ||
173 | u8 has_adj_hyst:1; | ||
174 | u8 has_dribble:1; | ||
175 | }; | ||
176 | u8 f11_2d_query5; | ||
177 | }; | ||
178 | |||
179 | u8 f11_2d_query6; | ||
180 | |||
181 | union { | ||
182 | struct { | ||
183 | u8 has_single_tap:1; | ||
184 | u8 has_tap_n_hold:1; | ||
185 | u8 has_double_tap:1; | ||
186 | u8 has_early_tap:1; | ||
187 | u8 has_flick:1; | ||
188 | u8 has_press:1; | ||
189 | u8 has_pinch:1; | ||
190 | u8 padding:1; | ||
191 | |||
192 | u8 has_palm_det:1; | ||
193 | u8 has_rotate:1; | ||
194 | u8 has_touch_shapes:1; | ||
195 | u8 has_scroll_zones:1; | ||
196 | u8 has_individual_scroll_zones:1; | ||
197 | u8 has_multi_finger_scroll:1; | ||
198 | }; | ||
199 | u8 f11_2d_query7__8[2]; | ||
200 | }; | ||
201 | |||
202 | /* Empty */ | ||
203 | u8 f11_2d_query9; | ||
204 | |||
205 | union { | ||
206 | struct { | ||
207 | u8 nbr_touch_shapes:5; | ||
208 | }; | ||
209 | u8 f11_2d_query10; | ||
210 | }; | ||
211 | }; | ||
212 | |||
213 | struct f11_2d_data_0 { | ||
214 | u8 finger_n; | ||
215 | }; | ||
216 | |||
217 | struct f11_2d_data_1_5 { | ||
218 | u8 x_msb; | ||
219 | u8 y_msb; | ||
220 | u8 x_lsb:4; | ||
221 | u8 y_lsb:4; | ||
222 | u8 w_y:4; | ||
223 | u8 w_x:4; | ||
224 | u8 z; | ||
225 | }; | ||
226 | |||
227 | struct f11_2d_data_6_7 { | ||
228 | s8 delta_x; | ||
229 | s8 delta_y; | ||
230 | }; | ||
231 | |||
232 | struct f11_2d_data_8 { | ||
233 | u8 single_tap:1; | ||
234 | u8 tap_and_hold:1; | ||
235 | u8 double_tap:1; | ||
236 | u8 early_tap:1; | ||
237 | u8 flick:1; | ||
238 | u8 press:1; | ||
239 | u8 pinch:1; | ||
240 | }; | ||
241 | |||
242 | struct f11_2d_data_9 { | ||
243 | u8 palm_detect:1; | ||
244 | u8 rotate:1; | ||
245 | u8 shape:1; | ||
246 | u8 scrollzone:1; | ||
247 | u8 finger_count:3; | ||
248 | }; | ||
249 | |||
250 | struct f11_2d_data_10 { | ||
251 | u8 pinch_motion; | ||
252 | }; | ||
253 | |||
254 | struct f11_2d_data_10_12 { | ||
255 | u8 x_flick_dist; | ||
256 | u8 y_flick_dist; | ||
257 | u8 flick_time; | ||
258 | }; | ||
259 | |||
260 | struct f11_2d_data_11_12 { | ||
261 | u8 motion; | ||
262 | u8 finger_separation; | ||
263 | }; | ||
264 | |||
265 | struct f11_2d_data_13 { | ||
266 | u8 shape_n; | ||
267 | }; | ||
268 | |||
269 | struct f11_2d_data_14_15 { | ||
270 | u8 horizontal; | ||
271 | u8 vertical; | ||
272 | }; | ||
273 | |||
274 | struct f11_2d_data_14_17 { | ||
275 | u8 x_low; | ||
276 | u8 y_right; | ||
277 | u8 x_upper; | ||
278 | u8 y_left; | ||
279 | }; | ||
280 | |||
281 | struct f11_2d_data { | ||
282 | const struct f11_2d_data_0 *f_state; | ||
283 | const struct f11_2d_data_1_5 *abs_pos; | ||
284 | const struct f11_2d_data_6_7 *rel_pos; | ||
285 | const struct f11_2d_data_8 *gest_1; | ||
286 | const struct f11_2d_data_9 *gest_2; | ||
287 | const struct f11_2d_data_10 *pinch; | ||
288 | const struct f11_2d_data_10_12 *flick; | ||
289 | const struct f11_2d_data_11_12 *rotate; | ||
290 | const struct f11_2d_data_13 *shapes; | ||
291 | const struct f11_2d_data_14_15 *multi_scroll; | ||
292 | const struct f11_2d_data_14_17 *scroll_zones; | ||
293 | }; | ||
294 | |||
295 | struct f11_2d_sensor { | ||
296 | struct rmi_f11_2d_axis_alignment axis_align; | ||
297 | struct f11_2d_sensor_query sens_query; | ||
298 | struct f11_2d_data data; | ||
299 | u16 max_x; | ||
300 | u16 max_y; | ||
301 | u8 nbr_fingers; | ||
302 | u8 finger_tracker[F11_MAX_NUM_OF_FINGERS]; | ||
303 | u8 *data_pkt; | ||
304 | int pkt_size; | ||
305 | u8 sensor_index; | ||
306 | char input_name[MAX_LEN]; | ||
307 | char input_phys[MAX_LEN]; | ||
308 | |||
309 | struct input_dev *input; | ||
310 | struct input_dev *mouse_input; | ||
311 | }; | ||
312 | |||
313 | struct f11_data { | ||
314 | struct f11_2d_device_query dev_query; | ||
315 | struct rmi_f11_2d_ctrl dev_controls; | ||
316 | struct f11_2d_sensor sensors[F11_MAX_NUM_OF_SENSORS]; | ||
317 | }; | ||
318 | |||
319 | enum finger_state_values { | ||
320 | F11_NO_FINGER = 0x00, | ||
321 | F11_PRESENT = 0x01, | ||
322 | F11_INACCURATE = 0x02, | ||
323 | F11_RESERVED = 0x03 | ||
324 | }; | ||
325 | |||
326 | static void rmi_f11_rel_pos_report(struct f11_2d_sensor *sensor, u8 n_finger) | ||
327 | { | ||
328 | struct f11_2d_data *data = &sensor->data; | ||
329 | struct rmi_f11_2d_axis_alignment *axis_align = &sensor->axis_align; | ||
330 | s8 x, y; | ||
331 | s8 temp; | ||
332 | |||
333 | x = data->rel_pos[n_finger].delta_x; | ||
334 | y = data->rel_pos[n_finger].delta_y; | ||
335 | |||
336 | x = min(F11_REL_POS_MAX, max(F11_REL_POS_MIN, (int)x)); | ||
337 | y = min(F11_REL_POS_MAX, max(F11_REL_POS_MIN, (int)y)); | ||
338 | |||
339 | if (axis_align->swap_axes) { | ||
340 | temp = x; | ||
341 | x = y; | ||
342 | y = temp; | ||
343 | } | ||
344 | if (axis_align->flip_x) | ||
345 | x = min(F11_REL_POS_MAX, -x); | ||
346 | if (axis_align->flip_y) | ||
347 | y = min(F11_REL_POS_MAX, -y); | ||
348 | |||
349 | if (x || y) { | ||
350 | input_report_rel(sensor->input, REL_X, x); | ||
351 | input_report_rel(sensor->input, REL_Y, y); | ||
352 | input_report_rel(sensor->mouse_input, REL_X, x); | ||
353 | input_report_rel(sensor->mouse_input, REL_Y, y); | ||
354 | } | ||
355 | input_sync(sensor->mouse_input); | ||
356 | } | ||
357 | |||
358 | static void rmi_f11_abs_pos_report(struct f11_2d_sensor *sensor, | ||
359 | u8 finger_state, u8 n_finger) | ||
360 | { | ||
361 | struct f11_2d_data *data = &sensor->data; | ||
362 | struct rmi_f11_2d_axis_alignment *axis_align = &sensor->axis_align; | ||
363 | int prev_state = sensor->finger_tracker[n_finger]; | ||
364 | int x, y, z; | ||
365 | int w_x, w_y, w_max, w_min, orient; | ||
366 | int temp; | ||
367 | if (prev_state && !finger_state) { | ||
368 | /* this is a release */ | ||
369 | x = y = z = w_max = w_min = orient = 0; | ||
370 | } else if (!prev_state && !finger_state) { | ||
371 | /* nothing to report */ | ||
372 | return; | ||
373 | } else { | ||
374 | x = ((data->abs_pos[n_finger].x_msb << 4) | | ||
375 | data->abs_pos[n_finger].x_lsb); | ||
376 | y = ((data->abs_pos[n_finger].y_msb << 4) | | ||
377 | data->abs_pos[n_finger].y_lsb); | ||
378 | z = data->abs_pos[n_finger].z; | ||
379 | w_x = data->abs_pos[n_finger].w_x; | ||
380 | w_y = data->abs_pos[n_finger].w_y; | ||
381 | w_max = max(w_x, w_y); | ||
382 | w_min = min(w_x, w_y); | ||
383 | |||
384 | if (axis_align->swap_axes) { | ||
385 | temp = x; | ||
386 | x = y; | ||
387 | y = temp; | ||
388 | temp = w_x; | ||
389 | w_x = w_y; | ||
390 | w_y = temp; | ||
391 | } | ||
392 | |||
393 | orient = w_x > w_y ? 1 : 0; | ||
394 | |||
395 | if (axis_align->flip_x) | ||
396 | x = max(sensor->max_x - x, 0); | ||
397 | |||
398 | if (axis_align->flip_y) | ||
399 | y = max(sensor->max_y - y, 0); | ||
400 | |||
401 | /* | ||
402 | ** here checking if X offset or y offset are specified is | ||
403 | ** redundant. We just add the offsets or, clip the values | ||
404 | ** | ||
405 | ** note: offsets need to be done before clipping occurs, | ||
406 | ** or we could get funny values that are outside | ||
407 | ** clipping boundaries. | ||
408 | */ | ||
409 | x += axis_align->offset_X; | ||
410 | y += axis_align->offset_Y; | ||
411 | x = max(axis_align->clip_X_low, x); | ||
412 | y = max(axis_align->clip_Y_low, y); | ||
413 | if (axis_align->clip_X_high) | ||
414 | x = min(axis_align->clip_X_high, x); | ||
415 | if (axis_align->clip_Y_high) | ||
416 | y = min(axis_align->clip_Y_high, y); | ||
417 | |||
418 | } | ||
419 | |||
420 | pr_debug("%s: f_state[%d]:%d - x:%d y:%d z:%d w_max:%d w_min:%d\n", | ||
421 | __func__, n_finger, finger_state, x, y, z, w_max, w_min); | ||
422 | |||
423 | |||
424 | #ifdef ABS_MT_PRESSURE | ||
425 | input_report_abs(sensor->input, ABS_MT_PRESSURE, z); | ||
426 | #endif | ||
427 | input_report_abs(sensor->input, ABS_MT_TOUCH_MAJOR, w_max); | ||
428 | input_report_abs(sensor->input, ABS_MT_TOUCH_MINOR, w_min); | ||
429 | input_report_abs(sensor->input, ABS_MT_ORIENTATION, orient); | ||
430 | input_report_abs(sensor->input, ABS_MT_POSITION_X, x); | ||
431 | input_report_abs(sensor->input, ABS_MT_POSITION_Y, y); | ||
432 | input_report_abs(sensor->input, ABS_MT_TRACKING_ID, n_finger); | ||
433 | |||
434 | /* MT sync between fingers */ | ||
435 | input_mt_sync(sensor->input); | ||
436 | sensor->finger_tracker[n_finger] = finger_state; | ||
437 | } | ||
438 | |||
439 | static void rmi_f11_finger_handler(struct f11_2d_sensor *sensor) | ||
440 | { | ||
441 | const struct f11_2d_data_0 *f_state = sensor->data.f_state; | ||
442 | u8 finger_state; | ||
443 | u8 finger_pressed_count; | ||
444 | u8 i; | ||
445 | |||
446 | for (i = 0, finger_pressed_count = 0; i < sensor->nbr_fingers; i++) { | ||
447 | /* Possible of having 4 fingers per f_statet register */ | ||
448 | finger_state = (f_state[i >> 2].finger_n & | ||
449 | F11_FINGER_STATE_MASK_N(i)); | ||
450 | finger_state = F11_FINGER_STATE_VAL_N(finger_state, i); | ||
451 | |||
452 | if (finger_state == F11_RESERVED) { | ||
453 | pr_err("%s: Invalid finger state[%d]:0x%02x.", __func__, | ||
454 | i, finger_state); | ||
455 | continue; | ||
456 | } else if ((finger_state == F11_PRESENT) || | ||
457 | (finger_state == F11_INACCURATE)) { | ||
458 | finger_pressed_count++; | ||
459 | } | ||
460 | |||
461 | if (sensor->data.abs_pos) | ||
462 | rmi_f11_abs_pos_report(sensor, finger_state, i); | ||
463 | |||
464 | if (sensor->data.rel_pos) | ||
465 | rmi_f11_rel_pos_report(sensor, i); | ||
466 | } | ||
467 | input_report_key(sensor->input, BTN_TOUCH, finger_pressed_count); | ||
468 | input_sync(sensor->input); | ||
469 | } | ||
470 | |||
471 | static inline int rmi_f11_2d_construct_data(struct f11_2d_sensor *sensor) | ||
472 | { | ||
473 | struct f11_2d_sensor_query *query = &sensor->sens_query; | ||
474 | struct f11_2d_data *data = &sensor->data; | ||
475 | int i; | ||
476 | |||
477 | sensor->nbr_fingers = (query->number_of_fingers == 5 ? 10 : | ||
478 | query->number_of_fingers + 1); | ||
479 | |||
480 | sensor->pkt_size = F11_CEIL(sensor->nbr_fingers, 4); | ||
481 | |||
482 | if (query->has_abs) | ||
483 | sensor->pkt_size += (sensor->nbr_fingers * 5); | ||
484 | |||
485 | if (query->has_rel) | ||
486 | sensor->pkt_size += (sensor->nbr_fingers * 2); | ||
487 | |||
488 | /* Check if F11_2D_Query7 is non-zero */ | ||
489 | if (query->f11_2d_query7__8[0]) | ||
490 | sensor->pkt_size += sizeof(u8); | ||
491 | |||
492 | /* Check if F11_2D_Query7 or F11_2D_Query8 is non-zero */ | ||
493 | if (query->f11_2d_query7__8[0] || query->f11_2d_query7__8[1]) | ||
494 | sensor->pkt_size += sizeof(u8); | ||
495 | |||
496 | if (query->has_pinch || query->has_flick || query->has_rotate) { | ||
497 | sensor->pkt_size += 3; | ||
498 | if (!query->has_flick) | ||
499 | sensor->pkt_size--; | ||
500 | if (!query->has_rotate) | ||
501 | sensor->pkt_size--; | ||
502 | } | ||
503 | |||
504 | if (query->has_touch_shapes) | ||
505 | sensor->pkt_size += F11_CEIL(query->nbr_touch_shapes + 1, 8); | ||
506 | |||
507 | sensor->data_pkt = kzalloc(sensor->pkt_size, GFP_KERNEL); | ||
508 | if (!sensor->data_pkt) | ||
509 | return -ENOMEM; | ||
510 | |||
511 | data->f_state = (struct f11_2d_data_0 *)sensor->data_pkt; | ||
512 | i = F11_CEIL(sensor->nbr_fingers, 4); | ||
513 | |||
514 | if (query->has_abs) { | ||
515 | data->abs_pos = (struct f11_2d_data_1_5 *) | ||
516 | &sensor->data_pkt[i]; | ||
517 | i += (sensor->nbr_fingers * 5); | ||
518 | } | ||
519 | |||
520 | if (query->has_rel) { | ||
521 | data->rel_pos = (struct f11_2d_data_6_7 *) | ||
522 | &sensor->data_pkt[i]; | ||
523 | i += (sensor->nbr_fingers * 2); | ||
524 | } | ||
525 | |||
526 | if (query->f11_2d_query7__8[0]) { | ||
527 | data->gest_1 = (struct f11_2d_data_8 *)&sensor->data_pkt[i]; | ||
528 | i++; | ||
529 | } | ||
530 | |||
531 | if (query->f11_2d_query7__8[0] || query->f11_2d_query7__8[1]) { | ||
532 | data->gest_2 = (struct f11_2d_data_9 *)&sensor->data_pkt[i]; | ||
533 | i++; | ||
534 | } | ||
535 | |||
536 | if (query->has_pinch) { | ||
537 | data->pinch = (struct f11_2d_data_10 *)&sensor->data_pkt[i]; | ||
538 | i++; | ||
539 | } | ||
540 | |||
541 | if (query->has_flick) { | ||
542 | if (query->has_pinch) { | ||
543 | data->flick = (struct f11_2d_data_10_12 *)data->pinch; | ||
544 | i += 2; | ||
545 | } else { | ||
546 | data->flick = (struct f11_2d_data_10_12 *) | ||
547 | &sensor->data_pkt[i]; | ||
548 | i += 3; | ||
549 | } | ||
550 | } | ||
551 | |||
552 | if (query->has_rotate) { | ||
553 | if (query->has_flick) { | ||
554 | data->rotate = (struct f11_2d_data_11_12 *) | ||
555 | (data->flick + 1); | ||
556 | } else { | ||
557 | data->rotate = (struct f11_2d_data_11_12 *) | ||
558 | &sensor->data_pkt[i]; | ||
559 | i += 2; | ||
560 | } | ||
561 | } | ||
562 | |||
563 | if (query->has_touch_shapes) | ||
564 | data->shapes = (struct f11_2d_data_13 *)&sensor->data_pkt[i]; | ||
565 | |||
566 | return 0; | ||
567 | } | ||
568 | |||
569 | static int rmi_f11_read_control_parameters(struct rmi_device *rmi_dev, | ||
570 | struct f11_2d_device_query *query, | ||
571 | struct rmi_f11_2d_ctrl *ctrl, | ||
572 | int ctrl_base_addr) { | ||
573 | int read_address = ctrl_base_addr; | ||
574 | int error = 0; | ||
575 | |||
576 | if (ctrl->ctrl0) { | ||
577 | error = rmi_read_block(rmi_dev, read_address, &ctrl->ctrl0->reg, | ||
578 | sizeof(union rmi_f11_2d_ctrl0)); | ||
579 | if (error < 0) { | ||
580 | dev_err(&rmi_dev->dev, | ||
581 | "Failed to read F11 ctrl0, code: %d.\n", error); | ||
582 | return error; | ||
583 | } | ||
584 | read_address = read_address + sizeof(union rmi_f11_2d_ctrl0); | ||
585 | } | ||
586 | |||
587 | if (ctrl->ctrl1) { | ||
588 | error = rmi_read_block(rmi_dev, read_address, &ctrl->ctrl1->reg, | ||
589 | sizeof(union rmi_f11_2d_ctrl1)); | ||
590 | if (error < 0) { | ||
591 | dev_err(&rmi_dev->dev, | ||
592 | "Failed to read F11 ctrl1, code: %d.\n", error); | ||
593 | return error; | ||
594 | } | ||
595 | read_address = read_address + sizeof(union rmi_f11_2d_ctrl1); | ||
596 | } | ||
597 | |||
598 | if (ctrl->ctrl2__3) { | ||
599 | error = rmi_read_block(rmi_dev, read_address, | ||
600 | ctrl->ctrl2__3->regs, | ||
601 | sizeof(ctrl->ctrl2__3->regs)); | ||
602 | if (error < 0) { | ||
603 | dev_err(&rmi_dev->dev, | ||
604 | "Failed to read F11 ctrl2__3, code: %d.\n", | ||
605 | error); | ||
606 | return error; | ||
607 | } | ||
608 | read_address = read_address + sizeof(ctrl->ctrl2__3->regs); | ||
609 | } | ||
610 | |||
611 | if (ctrl->ctrl4) { | ||
612 | error = rmi_read_block(rmi_dev, read_address, &ctrl->ctrl4->reg, | ||
613 | sizeof(ctrl->ctrl4->reg)); | ||
614 | if (error < 0) { | ||
615 | dev_err(&rmi_dev->dev, | ||
616 | "Failed to read F11 ctrl4, code: %d.\n", error); | ||
617 | return error; | ||
618 | } | ||
619 | read_address = read_address + sizeof(ctrl->ctrl4->reg); | ||
620 | } | ||
621 | |||
622 | if (ctrl->ctrl5) { | ||
623 | error = rmi_read_block(rmi_dev, read_address, &ctrl->ctrl5->reg, | ||
624 | sizeof(ctrl->ctrl5->reg)); | ||
625 | if (error < 0) { | ||
626 | dev_err(&rmi_dev->dev, | ||
627 | "Failed to read F11 ctrl5, code: %d.\n", error); | ||
628 | return error; | ||
629 | } | ||
630 | read_address = read_address + sizeof(ctrl->ctrl5->reg); | ||
631 | } | ||
632 | |||
633 | if (ctrl->ctrl6__7) { | ||
634 | error = rmi_read_block(rmi_dev, read_address, | ||
635 | ctrl->ctrl6__7->regs, | ||
636 | sizeof(ctrl->ctrl6__7->regs)); | ||
637 | if (error < 0) { | ||
638 | dev_err(&rmi_dev->dev, | ||
639 | "Failed to read F11 ctrl6__7, code: %d.\n", | ||
640 | error); | ||
641 | return error; | ||
642 | } | ||
643 | read_address = read_address + sizeof(ctrl->ctrl6__7->regs); | ||
644 | } | ||
645 | |||
646 | if (ctrl->ctrl8__9) { | ||
647 | error = rmi_read_block(rmi_dev, read_address, | ||
648 | ctrl->ctrl8__9->regs, | ||
649 | sizeof(ctrl->ctrl8__9->regs)); | ||
650 | if (error < 0) { | ||
651 | dev_err(&rmi_dev->dev, | ||
652 | "Failed to read F11 ctrl8__9, code: %d.\n", | ||
653 | error); | ||
654 | return error; | ||
655 | } | ||
656 | read_address = read_address + sizeof(ctrl->ctrl8__9->regs); | ||
657 | } | ||
658 | |||
659 | return 0; | ||
660 | } | ||
661 | |||
662 | static int rmi_f11_initialize_control_parameters(struct rmi_device *rmi_dev, | ||
663 | struct f11_2d_device_query *query, | ||
664 | struct rmi_f11_2d_ctrl *ctrl, | ||
665 | int ctrl_base_addr) { | ||
666 | int error = 0; | ||
667 | |||
668 | ctrl->ctrl0 = kzalloc(sizeof(union rmi_f11_2d_ctrl0), GFP_KERNEL); | ||
669 | if (!ctrl->ctrl0) { | ||
670 | dev_err(&rmi_dev->dev, "Failed to allocate F11 ctrl0.\n"); | ||
671 | error = -ENOMEM; | ||
672 | goto error_exit; | ||
673 | } | ||
674 | |||
675 | ctrl->ctrl1 = kzalloc(sizeof(union rmi_f11_2d_ctrl1), GFP_KERNEL); | ||
676 | if (!ctrl->ctrl1) { | ||
677 | dev_err(&rmi_dev->dev, "Failed to allocate F11 ctrl1.\n"); | ||
678 | error = -ENOMEM; | ||
679 | goto error_exit; | ||
680 | } | ||
681 | |||
682 | ctrl->ctrl2__3 = kzalloc(sizeof(union rmi_f11_2d_ctrl2__3), GFP_KERNEL); | ||
683 | if (!ctrl->ctrl2__3) { | ||
684 | dev_err(&rmi_dev->dev, "Failed to allocate F11 ctrl2__3.\n"); | ||
685 | error = -ENOMEM; | ||
686 | goto error_exit; | ||
687 | } | ||
688 | |||
689 | ctrl->ctrl4 = kzalloc(sizeof(union rmi_f11_2d_ctrl4), GFP_KERNEL); | ||
690 | if (!ctrl->ctrl4) { | ||
691 | dev_err(&rmi_dev->dev, "Failed to allocate F11 ctrl4.\n"); | ||
692 | error = -ENOMEM; | ||
693 | goto error_exit; | ||
694 | } | ||
695 | |||
696 | ctrl->ctrl5 = kzalloc(sizeof(union rmi_f11_2d_ctrl5), GFP_KERNEL); | ||
697 | if (!ctrl->ctrl5) { | ||
698 | dev_err(&rmi_dev->dev, "Failed to allocate F11 ctrl5.\n"); | ||
699 | error = -ENOMEM; | ||
700 | goto error_exit; | ||
701 | } | ||
702 | |||
703 | ctrl->ctrl6__7 = kzalloc(sizeof(union rmi_f11_2d_ctrl6__7), GFP_KERNEL); | ||
704 | if (!ctrl->ctrl6__7) { | ||
705 | dev_err(&rmi_dev->dev, "Failed to allocate F11 ctrl6__7.\n"); | ||
706 | error = -ENOMEM; | ||
707 | goto error_exit; | ||
708 | } | ||
709 | |||
710 | ctrl->ctrl8__9 = kzalloc(sizeof(union rmi_f11_2d_ctrl8__9), GFP_KERNEL); | ||
711 | if (!ctrl->ctrl8__9) { | ||
712 | dev_err(&rmi_dev->dev, "Failed to allocate F11 ctrl8__9.\n"); | ||
713 | error = -ENOMEM; | ||
714 | goto error_exit; | ||
715 | } | ||
716 | |||
717 | return rmi_f11_read_control_parameters(rmi_dev, query, | ||
718 | ctrl, ctrl_base_addr); | ||
719 | |||
720 | error_exit: | ||
721 | kfree(ctrl->ctrl0); | ||
722 | kfree(ctrl->ctrl1); | ||
723 | kfree(ctrl->ctrl2__3); | ||
724 | kfree(ctrl->ctrl4); | ||
725 | kfree(ctrl->ctrl5); | ||
726 | kfree(ctrl->ctrl6__7); | ||
727 | kfree(ctrl->ctrl8__9); | ||
728 | |||
729 | return error; | ||
730 | } | ||
731 | |||
732 | static inline int rmi_f11_set_control_parameters(struct rmi_device *rmi_dev, | ||
733 | struct f11_2d_sensor_query *query, | ||
734 | struct rmi_f11_2d_ctrl *ctrl, | ||
735 | int ctrl_base_addr) | ||
736 | { | ||
737 | int write_address = ctrl_base_addr; | ||
738 | int error; | ||
739 | |||
740 | if (ctrl->ctrl0) { | ||
741 | error = rmi_write_block(rmi_dev, write_address, | ||
742 | &ctrl->ctrl0->reg, | ||
743 | 1); | ||
744 | if (error < 0) | ||
745 | return error; | ||
746 | write_address++; | ||
747 | } | ||
748 | |||
749 | if (ctrl->ctrl1) { | ||
750 | error = rmi_write_block(rmi_dev, write_address, | ||
751 | &ctrl->ctrl1->reg, | ||
752 | 1); | ||
753 | if (error < 0) | ||
754 | return error; | ||
755 | write_address++; | ||
756 | } | ||
757 | |||
758 | if (ctrl->ctrl2__3) { | ||
759 | error = rmi_write_block(rmi_dev, write_address, | ||
760 | ctrl->ctrl2__3->regs, | ||
761 | sizeof(ctrl->ctrl2__3->regs)); | ||
762 | if (error < 0) | ||
763 | return error; | ||
764 | write_address += sizeof(ctrl->ctrl2__3->regs); | ||
765 | } | ||
766 | |||
767 | if (ctrl->ctrl4) { | ||
768 | error = rmi_write_block(rmi_dev, write_address, | ||
769 | &ctrl->ctrl4->reg, | ||
770 | 1); | ||
771 | if (error < 0) | ||
772 | return error; | ||
773 | write_address++; | ||
774 | } | ||
775 | |||
776 | if (ctrl->ctrl5) { | ||
777 | error = rmi_write_block(rmi_dev, write_address, | ||
778 | &ctrl->ctrl5->reg, | ||
779 | 1); | ||
780 | if (error < 0) | ||
781 | return error; | ||
782 | write_address++; | ||
783 | } | ||
784 | |||
785 | if (ctrl->ctrl6__7) { | ||
786 | error = rmi_write_block(rmi_dev, write_address, | ||
787 | &ctrl->ctrl6__7->regs[0], | ||
788 | sizeof(ctrl->ctrl6__7->regs)); | ||
789 | if (error < 0) | ||
790 | return error; | ||
791 | write_address += sizeof(ctrl->ctrl6__7->regs); | ||
792 | } | ||
793 | |||
794 | if (ctrl->ctrl8__9) { | ||
795 | error = rmi_write_block(rmi_dev, write_address, | ||
796 | &ctrl->ctrl8__9->regs[0], | ||
797 | sizeof(ctrl->ctrl8__9->regs)); | ||
798 | if (error < 0) | ||
799 | return error; | ||
800 | write_address += sizeof(ctrl->ctrl8__9->regs); | ||
801 | } | ||
802 | |||
803 | if (ctrl->ctrl10) { | ||
804 | error = rmi_write_block(rmi_dev, write_address, | ||
805 | &ctrl->ctrl10->reg, | ||
806 | 1); | ||
807 | if (error < 0) | ||
808 | return error; | ||
809 | write_address++; | ||
810 | } | ||
811 | |||
812 | if (ctrl->ctrl11) { | ||
813 | error = rmi_write_block(rmi_dev, write_address, | ||
814 | &ctrl->ctrl11->reg, | ||
815 | 1); | ||
816 | if (error < 0) | ||
817 | return error; | ||
818 | write_address++; | ||
819 | } | ||
820 | |||
821 | if (ctrl->ctrl12 && ctrl->ctrl12_size && query->configurable) { | ||
822 | if (ctrl->ctrl12_size > query->max_electrodes) { | ||
823 | dev_err(&rmi_dev->dev, | ||
824 | "%s: invalid cfg size:%d, should be < %d.\n", | ||
825 | __func__, ctrl->ctrl12_size, | ||
826 | query->max_electrodes); | ||
827 | return -EINVAL; | ||
828 | } | ||
829 | error = rmi_write_block(rmi_dev, write_address, | ||
830 | &ctrl->ctrl12->reg, | ||
831 | ctrl->ctrl12_size); | ||
832 | if (error < 0) | ||
833 | return error; | ||
834 | write_address += ctrl->ctrl12_size; | ||
835 | } | ||
836 | |||
837 | if (ctrl->ctrl14) { | ||
838 | error = rmi_write_block(rmi_dev, | ||
839 | write_address, | ||
840 | &ctrl->ctrl0->reg, | ||
841 | 1); | ||
842 | if (error < 0) | ||
843 | return error; | ||
844 | write_address++; | ||
845 | } | ||
846 | |||
847 | if (ctrl->ctrl15) { | ||
848 | error = rmi_write_block(rmi_dev, write_address, | ||
849 | ctrl->ctrl15, | ||
850 | 1); | ||
851 | if (error < 0) | ||
852 | return error; | ||
853 | write_address++; | ||
854 | } | ||
855 | |||
856 | if (ctrl->ctrl16) { | ||
857 | error = rmi_write_block(rmi_dev, write_address, | ||
858 | ctrl->ctrl16, | ||
859 | 1); | ||
860 | if (error < 0) | ||
861 | return error; | ||
862 | write_address++; | ||
863 | } | ||
864 | |||
865 | if (ctrl->ctrl17) { | ||
866 | error = rmi_write_block(rmi_dev, write_address, | ||
867 | ctrl->ctrl17, | ||
868 | 1); | ||
869 | if (error < 0) | ||
870 | return error; | ||
871 | write_address++; | ||
872 | } | ||
873 | |||
874 | if (ctrl->ctrl18) { | ||
875 | error = rmi_write_block(rmi_dev, write_address, | ||
876 | ctrl->ctrl18, | ||
877 | 1); | ||
878 | if (error < 0) | ||
879 | return error; | ||
880 | write_address++; | ||
881 | } | ||
882 | |||
883 | if (ctrl->ctrl19) { | ||
884 | error = rmi_write_block(rmi_dev, write_address, | ||
885 | ctrl->ctrl19, | ||
886 | 1); | ||
887 | if (error < 0) | ||
888 | return error; | ||
889 | write_address++; | ||
890 | } | ||
891 | |||
892 | return 0; | ||
893 | } | ||
894 | |||
895 | static inline int rmi_f11_get_query_parameters(struct rmi_device *rmi_dev, | ||
896 | struct f11_2d_sensor_query *query, u8 query_base_addr) | ||
897 | { | ||
898 | int query_size; | ||
899 | int rc; | ||
900 | |||
901 | rc = rmi_read_block(rmi_dev, query_base_addr, query->f11_2d_query1__4, | ||
902 | sizeof(query->f11_2d_query1__4)); | ||
903 | if (rc < 0) | ||
904 | return rc; | ||
905 | query_size = rc; | ||
906 | |||
907 | if (query->has_abs) { | ||
908 | rc = rmi_read(rmi_dev, query_base_addr + query_size, | ||
909 | &query->f11_2d_query5); | ||
910 | if (rc < 0) | ||
911 | return rc; | ||
912 | query_size++; | ||
913 | } | ||
914 | |||
915 | if (query->has_rel) { | ||
916 | rc = rmi_read(rmi_dev, query_base_addr + query_size, | ||
917 | &query->f11_2d_query6); | ||
918 | if (rc < 0) | ||
919 | return rc; | ||
920 | query_size++; | ||
921 | } | ||
922 | |||
923 | if (query->has_gestures) { | ||
924 | rc = rmi_read_block(rmi_dev, query_base_addr + query_size, | ||
925 | query->f11_2d_query7__8, | ||
926 | sizeof(query->f11_2d_query7__8)); | ||
927 | if (rc < 0) | ||
928 | return rc; | ||
929 | query_size += sizeof(query->f11_2d_query7__8); | ||
930 | } | ||
931 | |||
932 | if (query->has_touch_shapes) { | ||
933 | rc = rmi_read(rmi_dev, query_base_addr + query_size, | ||
934 | &query->f11_2d_query10); | ||
935 | if (rc < 0) | ||
936 | return rc; | ||
937 | query_size++; | ||
938 | } | ||
939 | |||
940 | return query_size; | ||
941 | } | ||
942 | |||
943 | /* This operation is done in a number of places, so we have a handy routine | ||
944 | * for it. | ||
945 | */ | ||
946 | static void f11_set_abs_params(struct rmi_function_container *fc, int index) | ||
947 | { | ||
948 | struct f11_data *instance_data = fc->data; | ||
949 | struct input_dev *input = instance_data->sensors[index].input; | ||
950 | int device_x_max = | ||
951 | instance_data->dev_controls.ctrl6__7->sensor_max_x_pos; | ||
952 | int device_y_max = | ||
953 | instance_data->dev_controls.ctrl8__9->sensor_max_y_pos; | ||
954 | int x_min, x_max, y_min, y_max; | ||
955 | |||
956 | if (instance_data->sensors[index].axis_align.swap_axes) { | ||
957 | int temp = device_x_max; | ||
958 | device_x_max = device_y_max; | ||
959 | device_y_max = temp; | ||
960 | } | ||
961 | |||
962 | /* Use the max X and max Y read from the device, or the clip values, | ||
963 | * whichever is stricter. | ||
964 | */ | ||
965 | x_min = instance_data->sensors[index].axis_align.clip_X_low; | ||
966 | if (instance_data->sensors[index].axis_align.clip_X_high) | ||
967 | x_max = min((int) device_x_max, | ||
968 | instance_data->sensors[index].axis_align.clip_X_high); | ||
969 | else | ||
970 | x_max = device_x_max; | ||
971 | |||
972 | y_min = instance_data->sensors[index].axis_align.clip_Y_low; | ||
973 | if (instance_data->sensors[index].axis_align.clip_Y_high) | ||
974 | y_max = min((int) device_y_max, | ||
975 | instance_data->sensors[index].axis_align.clip_Y_high); | ||
976 | else | ||
977 | y_max = device_y_max; | ||
978 | |||
979 | dev_dbg(&fc->dev, "Set ranges X=[%d..%d] Y=[%d..%d].", | ||
980 | x_min, x_max, y_min, y_max); | ||
981 | |||
982 | #ifdef ABS_MT_PRESSURE | ||
983 | input_set_abs_params(input, ABS_MT_PRESSURE, 0, | ||
984 | DEFAULT_MAX_ABS_MT_PRESSURE, 0, 0); | ||
985 | #endif | ||
986 | input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, | ||
987 | 0, DEFAULT_MAX_ABS_MT_TOUCH, 0, 0); | ||
988 | input_set_abs_params(input, ABS_MT_TOUCH_MINOR, | ||
989 | 0, DEFAULT_MAX_ABS_MT_TOUCH, 0, 0); | ||
990 | input_set_abs_params(input, ABS_MT_ORIENTATION, | ||
991 | 0, DEFAULT_MAX_ABS_MT_ORIENTATION, 0, 0); | ||
992 | input_set_abs_params(input, ABS_MT_TRACKING_ID, | ||
993 | DEFAULT_MIN_ABS_MT_TRACKING_ID, | ||
994 | DEFAULT_MAX_ABS_MT_TRACKING_ID, 0, 0); | ||
995 | /* TODO get max_x_pos (and y) from control registers. */ | ||
996 | input_set_abs_params(input, ABS_MT_POSITION_X, | ||
997 | x_min, x_max, 0, 0); | ||
998 | input_set_abs_params(input, ABS_MT_POSITION_Y, | ||
999 | y_min, y_max, 0, 0); | ||
1000 | } | ||
1001 | |||
1002 | static int rmi_f11_init(struct rmi_function_container *fc) | ||
1003 | { | ||
1004 | struct rmi_device *rmi_dev = fc->rmi_dev; | ||
1005 | struct rmi_device_platform_data *pdata; | ||
1006 | struct f11_data *f11; | ||
1007 | struct input_dev *input_dev; | ||
1008 | struct input_dev *input_dev_mouse; | ||
1009 | u8 query_offset; | ||
1010 | u8 query_base_addr; | ||
1011 | u8 control_base_addr; | ||
1012 | u16 max_x_pos, max_y_pos, temp; | ||
1013 | int rc; | ||
1014 | int i; | ||
1015 | int retval = 0; | ||
1016 | int attr_count = 0; | ||
1017 | |||
1018 | dev_info(&fc->dev, "Intializing F11 values."); | ||
1019 | |||
1020 | /* | ||
1021 | ** init instance data, fill in values and create any sysfs files | ||
1022 | */ | ||
1023 | f11 = kzalloc(sizeof(struct f11_data), GFP_KERNEL); | ||
1024 | if (!f11) | ||
1025 | return -ENOMEM; | ||
1026 | fc->data = f11; | ||
1027 | |||
1028 | query_base_addr = fc->fd.query_base_addr; | ||
1029 | control_base_addr = fc->fd.control_base_addr; | ||
1030 | |||
1031 | rc = rmi_read(rmi_dev, query_base_addr, &f11->dev_query.f11_2d_query0); | ||
1032 | if (rc < 0) | ||
1033 | goto err_free_data; | ||
1034 | |||
1035 | rc = rmi_f11_initialize_control_parameters(rmi_dev, &f11->dev_query, | ||
1036 | &f11->dev_controls, control_base_addr); | ||
1037 | if (rc < 0) { | ||
1038 | dev_err(&fc->dev, | ||
1039 | "Failed to initialize F11 control params.\n"); | ||
1040 | goto err_free_data; | ||
1041 | } | ||
1042 | |||
1043 | query_offset = (query_base_addr + 1); | ||
1044 | /* Increase with one since number of sensors is zero based */ | ||
1045 | for (i = 0; i < (f11->dev_query.nbr_of_sensors + 1); i++) { | ||
1046 | f11->sensors[i].sensor_index = i; | ||
1047 | |||
1048 | rc = rmi_f11_get_query_parameters(rmi_dev, | ||
1049 | &f11->sensors[i].sens_query, | ||
1050 | query_offset); | ||
1051 | if (rc < 0) | ||
1052 | goto err_free_data; | ||
1053 | |||
1054 | query_offset += rc; | ||
1055 | |||
1056 | pdata = to_rmi_platform_data(rmi_dev); | ||
1057 | if (pdata) | ||
1058 | f11->sensors[i].axis_align = pdata->axis_align; | ||
1059 | |||
1060 | if (pdata && pdata->f11_ctrl) { | ||
1061 | rc = rmi_f11_set_control_parameters(rmi_dev, | ||
1062 | &f11->sensors[i].sens_query, | ||
1063 | pdata->f11_ctrl, | ||
1064 | control_base_addr); | ||
1065 | if (rc < 0) | ||
1066 | goto err_free_data; | ||
1067 | } | ||
1068 | |||
1069 | if (pdata && pdata->f11_ctrl && | ||
1070 | pdata->f11_ctrl->ctrl6__7 && | ||
1071 | pdata->f11_ctrl->ctrl8__9) { | ||
1072 | max_x_pos = pdata->f11_ctrl->ctrl6__7->sensor_max_x_pos; | ||
1073 | max_y_pos = pdata->f11_ctrl->ctrl8__9->sensor_max_y_pos; | ||
1074 | |||
1075 | } else { | ||
1076 | rc = rmi_read_block(rmi_dev, | ||
1077 | control_base_addr + F11_CTRL_SENSOR_MAX_X_POS_OFFSET, | ||
1078 | (u8 *)&max_x_pos, sizeof(max_x_pos)); | ||
1079 | if (rc < 0) | ||
1080 | goto err_free_data; | ||
1081 | |||
1082 | rc = rmi_read_block(rmi_dev, | ||
1083 | control_base_addr + F11_CTRL_SENSOR_MAX_Y_POS_OFFSET, | ||
1084 | (u8 *)&max_y_pos, sizeof(max_y_pos)); | ||
1085 | if (rc < 0) | ||
1086 | goto err_free_data; | ||
1087 | } | ||
1088 | |||
1089 | if (pdata->axis_align.swap_axes) { | ||
1090 | temp = max_x_pos; | ||
1091 | max_x_pos = max_y_pos; | ||
1092 | max_y_pos = temp; | ||
1093 | } | ||
1094 | f11->sensors[i].max_x = max_x_pos; | ||
1095 | f11->sensors[i].max_y = max_y_pos; | ||
1096 | |||
1097 | rc = rmi_f11_2d_construct_data(&f11->sensors[i]); | ||
1098 | if (rc < 0) | ||
1099 | goto err_free_data; | ||
1100 | |||
1101 | input_dev = input_allocate_device(); | ||
1102 | if (!input_dev) { | ||
1103 | rc = -ENOMEM; | ||
1104 | goto err_free_data; | ||
1105 | } | ||
1106 | |||
1107 | f11->sensors[i].input = input_dev; | ||
1108 | /* TODO how to modify the dev name and | ||
1109 | * phys name for input device */ | ||
1110 | sprintf(f11->sensors[i].input_name, "%sfn%02x", | ||
1111 | dev_name(&rmi_dev->dev), fc->fd.function_number); | ||
1112 | input_dev->name = f11->sensors[i].input_name; | ||
1113 | sprintf(f11->sensors[i].input_phys, "%s/input0", | ||
1114 | input_dev->name); | ||
1115 | input_dev->phys = f11->sensors[i].input_phys; | ||
1116 | input_dev->dev.parent = &rmi_dev->dev; | ||
1117 | input_set_drvdata(input_dev, f11); | ||
1118 | |||
1119 | set_bit(EV_SYN, input_dev->evbit); | ||
1120 | set_bit(EV_KEY, input_dev->evbit); | ||
1121 | set_bit(EV_ABS, input_dev->evbit); | ||
1122 | |||
1123 | f11_set_abs_params(fc, i); | ||
1124 | |||
1125 | dev_dbg(&fc->dev, "%s: Sensor %d hasRel %d.\n", | ||
1126 | __func__, i, f11->sensors[i].sens_query.has_rel); | ||
1127 | if (f11->sensors[i].sens_query.has_rel) { | ||
1128 | set_bit(EV_REL, input_dev->evbit); | ||
1129 | set_bit(REL_X, input_dev->relbit); | ||
1130 | set_bit(REL_Y, input_dev->relbit); | ||
1131 | } | ||
1132 | rc = input_register_device(input_dev); | ||
1133 | if (rc < 0) | ||
1134 | goto err_free_input; | ||
1135 | |||
1136 | if (f11->sensors[i].sens_query.has_rel) { | ||
1137 | /*create input device for mouse events */ | ||
1138 | input_dev_mouse = input_allocate_device(); | ||
1139 | if (!input_dev_mouse) { | ||
1140 | rc = -ENOMEM; | ||
1141 | goto err_free_data; | ||
1142 | } | ||
1143 | |||
1144 | f11->sensors[i].mouse_input = input_dev_mouse; | ||
1145 | input_dev_mouse->name = "rmi_mouse"; | ||
1146 | input_dev_mouse->phys = "rmi_f11/input0"; | ||
1147 | |||
1148 | input_dev_mouse->id.vendor = 0x18d1; | ||
1149 | input_dev_mouse->id.product = 0x0210; | ||
1150 | input_dev_mouse->id.version = 0x0100; | ||
1151 | |||
1152 | set_bit(EV_REL, input_dev_mouse->evbit); | ||
1153 | set_bit(REL_X, input_dev_mouse->relbit); | ||
1154 | set_bit(REL_Y, input_dev_mouse->relbit); | ||
1155 | |||
1156 | set_bit(BTN_MOUSE, input_dev_mouse->evbit); | ||
1157 | /* Register device's buttons and keys */ | ||
1158 | set_bit(EV_KEY, input_dev_mouse->evbit); | ||
1159 | set_bit(BTN_LEFT, input_dev_mouse->keybit); | ||
1160 | set_bit(BTN_MIDDLE, input_dev_mouse->keybit); | ||
1161 | set_bit(BTN_RIGHT, input_dev_mouse->keybit); | ||
1162 | |||
1163 | rc = input_register_device(input_dev_mouse); | ||
1164 | if (rc < 0) | ||
1165 | goto err_free_input; | ||
1166 | set_bit(BTN_RIGHT, input_dev_mouse->keybit); | ||
1167 | } | ||
1168 | |||
1169 | } | ||
1170 | |||
1171 | dev_info(&fc->dev, "Creating sysfs files."); | ||
1172 | dev_dbg(&fc->dev, "Creating fn11 sysfs files."); | ||
1173 | |||
1174 | /* Set up sysfs device attributes. */ | ||
1175 | for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { | ||
1176 | if (sysfs_create_file | ||
1177 | (&fc->dev.kobj, &attrs[attr_count].attr) < 0) { | ||
1178 | dev_err(&fc->dev, "Failed to create sysfs file for %s.", | ||
1179 | attrs[attr_count].attr.name); | ||
1180 | retval = -ENODEV; | ||
1181 | goto err_free_input; | ||
1182 | } | ||
1183 | } | ||
1184 | |||
1185 | dev_info(&fc->dev, "Done Creating fn11 sysfs files."); | ||
1186 | return 0; | ||
1187 | |||
1188 | err_free_input: | ||
1189 | for (i = 0; i < (f11->dev_query.nbr_of_sensors + 1); i++) { | ||
1190 | if (f11->sensors[i].input) | ||
1191 | input_free_device(f11->sensors[i].input); | ||
1192 | if (f11->sensors[i].sens_query.has_rel && | ||
1193 | f11->sensors[i].mouse_input) | ||
1194 | input_free_device(f11->sensors[i].mouse_input); | ||
1195 | } | ||
1196 | err_free_data: | ||
1197 | for (attr_count--; attr_count >= 0; attr_count--) | ||
1198 | device_remove_file(&fc->rmi_dev->dev, &attrs[attr_count]); | ||
1199 | |||
1200 | kfree(f11); | ||
1201 | return rc; | ||
1202 | } | ||
1203 | |||
1204 | int rmi_f11_attention(struct rmi_function_container *fc, u8 *irq_bits) | ||
1205 | { | ||
1206 | struct rmi_device *rmi_dev = fc->rmi_dev; | ||
1207 | struct f11_data *f11 = fc->data; | ||
1208 | u8 data_base_addr = fc->fd.data_base_addr; | ||
1209 | int data_base_addr_offset = 0; | ||
1210 | int error; | ||
1211 | int i; | ||
1212 | |||
1213 | for (i = 0; i < f11->dev_query.nbr_of_sensors + 1; i++) { | ||
1214 | error = rmi_read_block(rmi_dev, | ||
1215 | data_base_addr + data_base_addr_offset, | ||
1216 | f11->sensors[i].data_pkt, | ||
1217 | f11->sensors[i].pkt_size); | ||
1218 | if (error < 0) | ||
1219 | return error; | ||
1220 | |||
1221 | rmi_f11_finger_handler(&f11->sensors[i]); | ||
1222 | data_base_addr_offset += f11->sensors[i].pkt_size; | ||
1223 | } | ||
1224 | return 0; | ||
1225 | } | ||
1226 | |||
1227 | static void rmi_f11_remove(struct rmi_function_container *fc) | ||
1228 | { | ||
1229 | struct f11_data *data = fc->data; | ||
1230 | int i; | ||
1231 | |||
1232 | for (i = 0; i < (data->dev_query.nbr_of_sensors + 1); i++) { | ||
1233 | input_unregister_device(data->sensors[i].input); | ||
1234 | if (data->sensors[i].sens_query.has_rel) | ||
1235 | input_unregister_device(data->sensors[i].mouse_input); | ||
1236 | } | ||
1237 | kfree(fc->data); | ||
1238 | } | ||
1239 | |||
1240 | static struct rmi_function_handler function_handler = { | ||
1241 | .func = 0x11, | ||
1242 | .init = rmi_f11_init, | ||
1243 | .attention = rmi_f11_attention, | ||
1244 | .remove = rmi_f11_remove | ||
1245 | }; | ||
1246 | |||
1247 | static int __init rmi_f11_module_init(void) | ||
1248 | { | ||
1249 | int error; | ||
1250 | |||
1251 | error = rmi_register_function_driver(&function_handler); | ||
1252 | if (error < 0) { | ||
1253 | pr_err("%s: register failed!\n", __func__); | ||
1254 | return error; | ||
1255 | } | ||
1256 | |||
1257 | return 0; | ||
1258 | } | ||
1259 | |||
1260 | static void __exit rmi_f11_module_exit(void) | ||
1261 | { | ||
1262 | rmi_unregister_function_driver(&function_handler); | ||
1263 | } | ||
1264 | |||
1265 | static ssize_t rmi_fn_11_maxPos_show(struct device *dev, | ||
1266 | struct device_attribute *attr, | ||
1267 | char *buf) | ||
1268 | { | ||
1269 | struct rmi_function_container *fc; | ||
1270 | struct f11_data *data; | ||
1271 | |||
1272 | fc = to_rmi_function_container(dev); | ||
1273 | data = fc->data; | ||
1274 | |||
1275 | return snprintf(buf, PAGE_SIZE, "%u %u\n", | ||
1276 | data->sensors[0].max_x, data->sensors[0].max_y); | ||
1277 | } | ||
1278 | |||
1279 | static ssize_t rmi_fn_11_flip_show(struct device *dev, | ||
1280 | struct device_attribute *attr, | ||
1281 | char *buf) | ||
1282 | { | ||
1283 | struct rmi_function_container *fc; | ||
1284 | struct f11_data *data; | ||
1285 | |||
1286 | fc = to_rmi_function_container(dev); | ||
1287 | data = fc->data; | ||
1288 | |||
1289 | return snprintf(buf, PAGE_SIZE, "%u %u\n", | ||
1290 | data->sensors[0].axis_align.flip_x, | ||
1291 | data->sensors[0].axis_align.flip_y); | ||
1292 | } | ||
1293 | |||
1294 | static ssize_t rmi_fn_11_flip_store(struct device *dev, | ||
1295 | struct device_attribute *attr, | ||
1296 | const char *buf, | ||
1297 | size_t count) | ||
1298 | { | ||
1299 | struct rmi_function_container *fc; | ||
1300 | struct f11_data *instance_data; | ||
1301 | unsigned int new_X, new_Y; | ||
1302 | |||
1303 | fc = to_rmi_function_container(dev); | ||
1304 | instance_data = fc->data; | ||
1305 | |||
1306 | |||
1307 | if (sscanf(buf, "%u %u", &new_X, &new_Y) != 2) | ||
1308 | return -EINVAL; | ||
1309 | if (new_X < 0 || new_X > 1 || new_Y < 0 || new_Y > 1) | ||
1310 | return -EINVAL; | ||
1311 | instance_data->sensors[0].axis_align.flip_x = new_X; | ||
1312 | instance_data->sensors[0].axis_align.flip_y = new_Y; | ||
1313 | |||
1314 | return count; | ||
1315 | } | ||
1316 | |||
1317 | static ssize_t rmi_fn_11_swap_show(struct device *dev, | ||
1318 | struct device_attribute *attr, char *buf) | ||
1319 | { | ||
1320 | struct rmi_function_container *fc; | ||
1321 | struct f11_data *instance_data; | ||
1322 | |||
1323 | fc = to_rmi_function_container(dev); | ||
1324 | instance_data = fc->data; | ||
1325 | |||
1326 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1327 | instance_data->sensors[0].axis_align.swap_axes); | ||
1328 | } | ||
1329 | |||
1330 | static ssize_t rmi_fn_11_swap_store(struct device *dev, | ||
1331 | struct device_attribute *attr, | ||
1332 | const char *buf, size_t count) | ||
1333 | { | ||
1334 | struct rmi_function_container *fc; | ||
1335 | struct f11_data *instance_data; | ||
1336 | unsigned int newSwap; | ||
1337 | |||
1338 | fc = to_rmi_function_container(dev); | ||
1339 | instance_data = fc->data; | ||
1340 | |||
1341 | |||
1342 | if (sscanf(buf, "%u", &newSwap) != 1) | ||
1343 | return -EINVAL; | ||
1344 | if (newSwap < 0 || newSwap > 1) | ||
1345 | return -EINVAL; | ||
1346 | instance_data->sensors[0].axis_align.swap_axes = newSwap; | ||
1347 | |||
1348 | f11_set_abs_params(fc, 0); | ||
1349 | |||
1350 | return count; | ||
1351 | } | ||
1352 | |||
1353 | static ssize_t rmi_fn_11_relreport_show(struct device *dev, | ||
1354 | struct device_attribute *attr, | ||
1355 | char *buf) | ||
1356 | { | ||
1357 | struct rmi_function_container *fc; | ||
1358 | struct f11_data *instance_data; | ||
1359 | |||
1360 | fc = to_rmi_function_container(dev); | ||
1361 | instance_data = fc->data; | ||
1362 | |||
1363 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1364 | instance_data-> | ||
1365 | sensors[0].axis_align.rel_report_enabled); | ||
1366 | } | ||
1367 | |||
1368 | static ssize_t rmi_fn_11_relreport_store(struct device *dev, | ||
1369 | struct device_attribute *attr, | ||
1370 | const char *buf, | ||
1371 | size_t count) | ||
1372 | { | ||
1373 | struct rmi_function_container *fc; | ||
1374 | struct f11_data *instance_data; | ||
1375 | unsigned int new_value; | ||
1376 | |||
1377 | fc = to_rmi_function_container(dev); | ||
1378 | instance_data = fc->data; | ||
1379 | |||
1380 | |||
1381 | if (sscanf(buf, "%u", &new_value) != 1) | ||
1382 | return -EINVAL; | ||
1383 | if (new_value < 0 || new_value > 1) | ||
1384 | return -EINVAL; | ||
1385 | instance_data->sensors[0].axis_align.rel_report_enabled = new_value; | ||
1386 | |||
1387 | return count; | ||
1388 | } | ||
1389 | |||
1390 | static ssize_t rmi_fn_11_offset_show(struct device *dev, | ||
1391 | struct device_attribute *attr, | ||
1392 | char *buf) | ||
1393 | { | ||
1394 | struct rmi_function_container *fc; | ||
1395 | struct f11_data *instance_data; | ||
1396 | |||
1397 | fc = to_rmi_function_container(dev); | ||
1398 | instance_data = fc->data; | ||
1399 | |||
1400 | return snprintf(buf, PAGE_SIZE, "%d %d\n", | ||
1401 | instance_data->sensors[0].axis_align.offset_X, | ||
1402 | instance_data->sensors[0].axis_align.offset_Y); | ||
1403 | } | ||
1404 | |||
1405 | static ssize_t rmi_fn_11_offset_store(struct device *dev, | ||
1406 | struct device_attribute *attr, | ||
1407 | const char *buf, | ||
1408 | size_t count) | ||
1409 | { | ||
1410 | struct rmi_function_container *fc; | ||
1411 | struct f11_data *instance_data; | ||
1412 | int new_X, new_Y; | ||
1413 | |||
1414 | fc = to_rmi_function_container(dev); | ||
1415 | instance_data = fc->data; | ||
1416 | |||
1417 | |||
1418 | if (sscanf(buf, "%d %d", &new_X, &new_Y) != 2) | ||
1419 | return -EINVAL; | ||
1420 | instance_data->sensors[0].axis_align.offset_X = new_X; | ||
1421 | instance_data->sensors[0].axis_align.offset_Y = new_Y; | ||
1422 | |||
1423 | return count; | ||
1424 | } | ||
1425 | |||
1426 | static ssize_t rmi_fn_11_clip_show(struct device *dev, | ||
1427 | struct device_attribute *attr, | ||
1428 | char *buf) | ||
1429 | { | ||
1430 | |||
1431 | struct rmi_function_container *fc; | ||
1432 | struct f11_data *instance_data; | ||
1433 | |||
1434 | fc = to_rmi_function_container(dev); | ||
1435 | instance_data = fc->data; | ||
1436 | |||
1437 | return snprintf(buf, PAGE_SIZE, "%u %u %u %u\n", | ||
1438 | instance_data->sensors[0].axis_align.clip_X_low, | ||
1439 | instance_data->sensors[0].axis_align.clip_X_high, | ||
1440 | instance_data->sensors[0].axis_align.clip_Y_low, | ||
1441 | instance_data->sensors[0].axis_align.clip_Y_high); | ||
1442 | } | ||
1443 | |||
1444 | static ssize_t rmi_fn_11_clip_store(struct device *dev, | ||
1445 | struct device_attribute *attr, | ||
1446 | const char *buf, | ||
1447 | size_t count) | ||
1448 | { | ||
1449 | struct rmi_function_container *fc; | ||
1450 | struct f11_data *instance_data; | ||
1451 | unsigned int new_X_low, new_X_high, new_Y_low, new_Y_high; | ||
1452 | |||
1453 | fc = to_rmi_function_container(dev); | ||
1454 | instance_data = fc->data; | ||
1455 | |||
1456 | if (sscanf(buf, "%u %u %u %u", | ||
1457 | &new_X_low, &new_X_high, &new_Y_low, &new_Y_high) != 4) | ||
1458 | return -EINVAL; | ||
1459 | if (new_X_low < 0 || new_X_low >= new_X_high || new_Y_low < 0 | ||
1460 | || new_Y_low >= new_Y_high) | ||
1461 | return -EINVAL; | ||
1462 | instance_data->sensors[0].axis_align.clip_X_low = new_X_low; | ||
1463 | instance_data->sensors[0].axis_align.clip_X_high = new_X_high; | ||
1464 | instance_data->sensors[0].axis_align.clip_Y_low = new_Y_low; | ||
1465 | instance_data->sensors[0].axis_align.clip_Y_high = new_Y_high; | ||
1466 | |||
1467 | /* | ||
1468 | ** for now, we assume this is sensor index 0 | ||
1469 | */ | ||
1470 | f11_set_abs_params(fc, 0); | ||
1471 | |||
1472 | return count; | ||
1473 | } | ||
1474 | |||
1475 | static ssize_t rmi_f11_rezero_store(struct device *dev, | ||
1476 | struct device_attribute *attr, | ||
1477 | const char *buf, size_t count) | ||
1478 | { | ||
1479 | struct rmi_function_container *fc = NULL; | ||
1480 | unsigned int rezero; | ||
1481 | int retval = 0; | ||
1482 | /* Command register always reads as 0, so we can just use a local. */ | ||
1483 | union f11_2d_commands commands = {}; | ||
1484 | |||
1485 | fc = to_rmi_function_container(dev); | ||
1486 | |||
1487 | if (sscanf(buf, "%u", &rezero) != 1) | ||
1488 | return -EINVAL; | ||
1489 | if (rezero < 0 || rezero > 1) | ||
1490 | return -EINVAL; | ||
1491 | |||
1492 | /* Per spec, 0 has no effect, so we skip it entirely. */ | ||
1493 | if (rezero) { | ||
1494 | commands.rezero = 1; | ||
1495 | retval = rmi_write_block(fc->rmi_dev, fc->fd.command_base_addr, | ||
1496 | &commands.reg, sizeof(commands.reg)); | ||
1497 | if (retval < 0) { | ||
1498 | dev_err(dev, "%s: failed to issue rezero command, " | ||
1499 | "error = %d.", __func__, retval); | ||
1500 | return retval; | ||
1501 | } | ||
1502 | } | ||
1503 | |||
1504 | return count; | ||
1505 | } | ||
1506 | |||
1507 | |||
1508 | module_init(rmi_f11_module_init); | ||
1509 | module_exit(rmi_f11_module_exit); | ||
1510 | |||
1511 | MODULE_AUTHOR("Stefan Nilsson <stefan.nilsson@unixphere.com>"); | ||
1512 | MODULE_DESCRIPTION("RMI F11 module"); | ||
1513 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/rmi4/rmi_f19.c b/drivers/input/touchscreen/rmi4/rmi_f19.c new file mode 100644 index 00000000000..9ff9ff99f91 --- /dev/null +++ b/drivers/input/touchscreen/rmi4/rmi_f19.c | |||
@@ -0,0 +1,1419 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Synaptics Incorporated | ||
3 | * Copyright (c) 2011 Unixphere | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/rmi.h> | ||
21 | #include <linux/input.h> | ||
22 | #include <linux/slab.h> | ||
23 | |||
24 | #define QUERY_BASE_INDEX 1 | ||
25 | #define MAX_LEN 256 | ||
26 | |||
27 | struct f19_0d_query { | ||
28 | union { | ||
29 | struct { | ||
30 | u8 configurable:1; | ||
31 | u8 has_sensitivity_adjust:1; | ||
32 | u8 has_hysteresis_threshold:1; | ||
33 | }; | ||
34 | u8 f19_0d_query0; | ||
35 | }; | ||
36 | u8 f19_0d_query1:5; | ||
37 | }; | ||
38 | |||
39 | struct f19_0d_control_0 { | ||
40 | union { | ||
41 | struct { | ||
42 | u8 button_usage:2; | ||
43 | u8 filter_mode:2; | ||
44 | }; | ||
45 | u8 f19_0d_control0; | ||
46 | }; | ||
47 | }; | ||
48 | |||
49 | struct f19_0d_control_1 { | ||
50 | u8 int_enabled_button; | ||
51 | }; | ||
52 | |||
53 | struct f19_0d_control_2 { | ||
54 | u8 single_button; | ||
55 | }; | ||
56 | |||
57 | struct f19_0d_control_3_4 { | ||
58 | u8 sensor_map_button:7; | ||
59 | /*u8 sensitivity_button;*/ | ||
60 | }; | ||
61 | |||
62 | struct f19_0d_control_5 { | ||
63 | u8 sensitivity_adj; | ||
64 | }; | ||
65 | struct f19_0d_control_6 { | ||
66 | u8 hysteresis_threshold; | ||
67 | }; | ||
68 | |||
69 | struct f19_0d_control { | ||
70 | struct f19_0d_control_0 *general_control; | ||
71 | struct f19_0d_control_1 *button_int_enable; | ||
72 | struct f19_0d_control_2 *single_button_participation; | ||
73 | struct f19_0d_control_3_4 *sensor_map; | ||
74 | struct f19_0d_control_5 *all_button_sensitivity_adj; | ||
75 | struct f19_0d_control_6 *all_button_hysteresis_threshold; | ||
76 | }; | ||
77 | /* data specific to fn $19 that needs to be kept around */ | ||
78 | struct f19_data { | ||
79 | struct f19_0d_control *button_control; | ||
80 | struct f19_0d_query button_query; | ||
81 | u8 button_rezero; | ||
82 | bool *button_down; | ||
83 | unsigned char button_count; | ||
84 | unsigned char button_data_buffer_size; | ||
85 | unsigned char *button_data_buffer; | ||
86 | unsigned char *button_map; | ||
87 | char input_name[MAX_LEN]; | ||
88 | char input_phys[MAX_LEN]; | ||
89 | struct input_dev *input; | ||
90 | }; | ||
91 | |||
92 | static ssize_t rmi_f19_button_count_show(struct device *dev, | ||
93 | struct device_attribute *attr, | ||
94 | char *buf); | ||
95 | |||
96 | static ssize_t rmi_f19_button_map_show(struct device *dev, | ||
97 | struct device_attribute *attr, char *buf); | ||
98 | |||
99 | static ssize_t rmi_f19_button_map_store(struct device *dev, | ||
100 | struct device_attribute *attr, | ||
101 | const char *buf, size_t count); | ||
102 | static ssize_t rmi_f19_rezero_show(struct device *dev, | ||
103 | struct device_attribute *attr, | ||
104 | char *buf); | ||
105 | static ssize_t rmi_f19_rezero_store(struct device *dev, | ||
106 | struct device_attribute *attr, | ||
107 | const char *buf, size_t count); | ||
108 | static ssize_t rmi_f19_has_hysteresis_threshold_show(struct device *dev, | ||
109 | struct device_attribute *attr, char *buf); | ||
110 | static ssize_t rmi_f19_has_sensitivity_adjust_show(struct device *dev, | ||
111 | struct device_attribute *attr, char *buf); | ||
112 | static ssize_t rmi_f19_configurable_show(struct device *dev, | ||
113 | struct device_attribute *attr, char *buf); | ||
114 | static ssize_t rmi_f19_filter_mode_show(struct device *dev, | ||
115 | struct device_attribute *attr, | ||
116 | char *buf); | ||
117 | static ssize_t rmi_f19_filter_mode_store(struct device *dev, | ||
118 | struct device_attribute *attr, | ||
119 | const char *buf, size_t count); | ||
120 | static ssize_t rmi_f19_button_usage_show(struct device *dev, | ||
121 | struct device_attribute *attr, | ||
122 | char *buf); | ||
123 | static ssize_t rmi_f19_button_usage_store(struct device *dev, | ||
124 | struct device_attribute *attr, | ||
125 | const char *buf, size_t count); | ||
126 | static ssize_t rmi_f19_interrupt_enable_button_show(struct device *dev, | ||
127 | struct device_attribute *attr, | ||
128 | char *buf); | ||
129 | static ssize_t rmi_f19_interrupt_enable_button_store(struct device *dev, | ||
130 | struct device_attribute *attr, | ||
131 | const char *buf, size_t count); | ||
132 | static ssize_t rmi_f19_single_button_show(struct device *dev, | ||
133 | struct device_attribute *attr, | ||
134 | char *buf); | ||
135 | static ssize_t rmi_f19_single_button_store(struct device *dev, | ||
136 | struct device_attribute *attr, | ||
137 | const char *buf, size_t count); | ||
138 | static ssize_t rmi_f19_sensor_map_show(struct device *dev, | ||
139 | struct device_attribute *attr, | ||
140 | char *buf); | ||
141 | static ssize_t rmi_f19_sensor_map_store(struct device *dev, | ||
142 | struct device_attribute *attr, | ||
143 | const char *buf, size_t count); | ||
144 | static ssize_t rmi_f19_sensitivity_adjust_show(struct device *dev, | ||
145 | struct device_attribute *attr, | ||
146 | char *buf); | ||
147 | static ssize_t rmi_f19_sensitivity_adjust_store(struct device *dev, | ||
148 | struct device_attribute *attr, | ||
149 | const char *buf, size_t count); | ||
150 | static ssize_t rmi_f19_hysteresis_threshold_show(struct device *dev, | ||
151 | struct device_attribute *attr, | ||
152 | char *buf); | ||
153 | static ssize_t rmi_f19_hysteresis_threshold_store(struct device *dev, | ||
154 | struct device_attribute *attr, | ||
155 | const char *buf, size_t count); | ||
156 | |||
157 | |||
158 | static struct device_attribute attrs[] = { | ||
159 | __ATTR(button_count, RMI_RO_ATTR, | ||
160 | rmi_f19_button_count_show, rmi_store_error), | ||
161 | __ATTR(button_map, RMI_RW_ATTR, | ||
162 | rmi_f19_button_map_show, rmi_f19_button_map_store), | ||
163 | __ATTR(rezero, RMI_RW_ATTR, | ||
164 | rmi_f19_rezero_show, rmi_f19_rezero_store), | ||
165 | __ATTR(has_hysteresis_threshold, RMI_RO_ATTR, | ||
166 | rmi_f19_has_hysteresis_threshold_show, rmi_store_error), | ||
167 | __ATTR(has_sensitivity_adjust, RMI_RO_ATTR, | ||
168 | rmi_f19_has_sensitivity_adjust_show, rmi_store_error), | ||
169 | __ATTR(configurable, RMI_RO_ATTR, | ||
170 | rmi_f19_configurable_show, rmi_store_error), | ||
171 | __ATTR(filter_mode, RMI_RW_ATTR, | ||
172 | rmi_f19_filter_mode_show, rmi_f19_filter_mode_store), | ||
173 | __ATTR(button_usage, RMI_RW_ATTR, | ||
174 | rmi_f19_button_usage_show, rmi_f19_button_usage_store), | ||
175 | __ATTR(interrupt_enable_button, RMI_RW_ATTR, | ||
176 | rmi_f19_interrupt_enable_button_show, | ||
177 | rmi_f19_interrupt_enable_button_store), | ||
178 | __ATTR(single_button, RMI_RW_ATTR, | ||
179 | rmi_f19_single_button_show, rmi_f19_single_button_store), | ||
180 | __ATTR(sensor_map, RMI_RW_ATTR, | ||
181 | rmi_f19_sensor_map_show, rmi_f19_sensor_map_store), | ||
182 | __ATTR(sensitivity_adjust, RMI_RW_ATTR, | ||
183 | rmi_f19_sensitivity_adjust_show, | ||
184 | rmi_f19_sensitivity_adjust_store), | ||
185 | __ATTR(hysteresis_threshold, RMI_RW_ATTR, | ||
186 | rmi_f19_hysteresis_threshold_show, | ||
187 | rmi_f19_hysteresis_threshold_store) | ||
188 | }; | ||
189 | |||
190 | |||
191 | int rmi_f19_read_control_parameters(struct rmi_device *rmi_dev, | ||
192 | struct f19_0d_control *button_control, | ||
193 | unsigned char button_count, | ||
194 | unsigned char int_button_enabled_count, | ||
195 | u8 ctrl_base_addr) | ||
196 | { | ||
197 | int error = 0; | ||
198 | int i; | ||
199 | |||
200 | if (button_control->general_control) { | ||
201 | error = rmi_read_block(rmi_dev, ctrl_base_addr, | ||
202 | (u8 *)button_control->general_control, | ||
203 | sizeof(struct f19_0d_control_0)); | ||
204 | if (error < 0) { | ||
205 | dev_err(&rmi_dev->dev, | ||
206 | "Failed to read f19_0d_control_0, code:" | ||
207 | " %d.\n", error); | ||
208 | return error; | ||
209 | } | ||
210 | ctrl_base_addr = ctrl_base_addr + | ||
211 | sizeof(struct f19_0d_control_0); | ||
212 | } | ||
213 | |||
214 | if (button_control->button_int_enable) { | ||
215 | for (i = 0; i < int_button_enabled_count; i++) { | ||
216 | error = rmi_read_block(rmi_dev, ctrl_base_addr, | ||
217 | (u8 *)&button_control->button_int_enable[i], | ||
218 | sizeof(struct f19_0d_control_1)); | ||
219 | if (error < 0) { | ||
220 | dev_err(&rmi_dev->dev, | ||
221 | "Failed to read f19_0d_control_2," | ||
222 | " code: %d.\n", error); | ||
223 | return error; | ||
224 | } | ||
225 | ctrl_base_addr = ctrl_base_addr + | ||
226 | sizeof(struct f19_0d_control_1); | ||
227 | } | ||
228 | } | ||
229 | |||
230 | if (button_control->single_button_participation) { | ||
231 | for (i = 0; i < int_button_enabled_count; i++) { | ||
232 | error = rmi_read_block(rmi_dev, ctrl_base_addr, | ||
233 | (u8 *)&button_control-> | ||
234 | single_button_participation[i], | ||
235 | sizeof(struct f19_0d_control_2)); | ||
236 | if (error < 0) { | ||
237 | dev_err(&rmi_dev->dev, | ||
238 | "Failed to read f19_0d_control_2," | ||
239 | " code: %d.\n", error); | ||
240 | return error; | ||
241 | } | ||
242 | ctrl_base_addr = ctrl_base_addr + | ||
243 | sizeof(struct f19_0d_control_2); | ||
244 | } | ||
245 | } | ||
246 | |||
247 | if (button_control->sensor_map) { | ||
248 | for (i = 0; i < button_count; i++) { | ||
249 | error = rmi_read_block(rmi_dev, ctrl_base_addr, | ||
250 | (u8 *)&button_control->sensor_map[i], | ||
251 | sizeof(struct f19_0d_control_3_4)); | ||
252 | if (error < 0) { | ||
253 | dev_err(&rmi_dev->dev, | ||
254 | "Failed to read f19_0d_control_3_4," | ||
255 | " code: %d.\n", error); | ||
256 | return error; | ||
257 | } | ||
258 | ctrl_base_addr = ctrl_base_addr + | ||
259 | sizeof(struct f19_0d_control_3_4); | ||
260 | } | ||
261 | } | ||
262 | |||
263 | if (button_control->all_button_sensitivity_adj) { | ||
264 | error = rmi_read_block(rmi_dev, ctrl_base_addr, | ||
265 | (u8 *)button_control-> | ||
266 | all_button_sensitivity_adj, | ||
267 | sizeof(struct f19_0d_control_5)); | ||
268 | if (error < 0) { | ||
269 | dev_err(&rmi_dev->dev, | ||
270 | "Failed to read f19_0d_control_5," | ||
271 | " code: %d.\n", error); | ||
272 | return error; | ||
273 | } | ||
274 | ctrl_base_addr = ctrl_base_addr + | ||
275 | sizeof(struct f19_0d_control_5); | ||
276 | } | ||
277 | |||
278 | if (button_control->all_button_hysteresis_threshold) { | ||
279 | error = rmi_read_block(rmi_dev, ctrl_base_addr, | ||
280 | (u8 *)button_control-> | ||
281 | all_button_hysteresis_threshold, | ||
282 | sizeof(struct f19_0d_control_6)); | ||
283 | if (error < 0) { | ||
284 | dev_err(&rmi_dev->dev, | ||
285 | "Failed to read f19_0d_control_6," | ||
286 | " code: %d.\n", error); | ||
287 | return error; | ||
288 | } | ||
289 | ctrl_base_addr = ctrl_base_addr + | ||
290 | sizeof(struct f19_0d_control_6); | ||
291 | } | ||
292 | return 0; | ||
293 | } | ||
294 | |||
295 | |||
296 | int rmi_f19_initialize_control_parameters(struct rmi_device *rmi_dev, | ||
297 | struct f19_0d_control *button_control, | ||
298 | unsigned char button_count, | ||
299 | unsigned char int_button_enabled_count, | ||
300 | int control_base_addr) | ||
301 | { | ||
302 | int error = 0; | ||
303 | |||
304 | button_control->general_control = | ||
305 | kzalloc(sizeof(struct f19_0d_control_0), GFP_KERNEL); | ||
306 | if (!button_control->general_control) { | ||
307 | dev_err(&rmi_dev->dev, "Failed to allocate" | ||
308 | " f19_0d_control_0.\n"); | ||
309 | error = -ENOMEM; | ||
310 | goto error_exit; | ||
311 | } | ||
312 | |||
313 | button_control->button_int_enable = | ||
314 | kzalloc(int_button_enabled_count * | ||
315 | sizeof(struct f19_0d_control_2), GFP_KERNEL); | ||
316 | if (!button_control->button_int_enable) { | ||
317 | dev_err(&rmi_dev->dev, "Failed to allocate f19_0d_control_1.\n"); | ||
318 | error = -ENOMEM; | ||
319 | goto error_exit; | ||
320 | } | ||
321 | |||
322 | button_control->single_button_participation = | ||
323 | kzalloc(int_button_enabled_count * | ||
324 | sizeof(struct f19_0d_control_2), GFP_KERNEL); | ||
325 | if (!button_control->single_button_participation) { | ||
326 | dev_err(&rmi_dev->dev, "Failed to allocate" | ||
327 | " f19_0d_control_2.\n"); | ||
328 | error = -ENOMEM; | ||
329 | goto error_exit; | ||
330 | } | ||
331 | |||
332 | button_control->sensor_map = | ||
333 | kzalloc(button_count * | ||
334 | sizeof(struct f19_0d_control_3_4), GFP_KERNEL); | ||
335 | if (!button_control->sensor_map) { | ||
336 | dev_err(&rmi_dev->dev, "Failed to allocate" | ||
337 | " f19_0d_control_3_4.\n"); | ||
338 | error = -ENOMEM; | ||
339 | goto error_exit; | ||
340 | } | ||
341 | |||
342 | button_control->all_button_sensitivity_adj = | ||
343 | kzalloc(sizeof(struct f19_0d_control_5), GFP_KERNEL); | ||
344 | if (!button_control->all_button_sensitivity_adj) { | ||
345 | dev_err(&rmi_dev->dev, "Failed to allocate" | ||
346 | " f19_0d_control_5.\n"); | ||
347 | error = -ENOMEM; | ||
348 | goto error_exit; | ||
349 | } | ||
350 | |||
351 | button_control->all_button_hysteresis_threshold = | ||
352 | kzalloc(sizeof(struct f19_0d_control_6), GFP_KERNEL); | ||
353 | if (!button_control->all_button_hysteresis_threshold) { | ||
354 | dev_err(&rmi_dev->dev, "Failed to allocate" | ||
355 | " f19_0d_control_6.\n"); | ||
356 | error = -ENOMEM; | ||
357 | goto error_exit; | ||
358 | } | ||
359 | return rmi_f19_read_control_parameters(rmi_dev, button_control, | ||
360 | button_count, int_button_enabled_count, control_base_addr); | ||
361 | |||
362 | error_exit: | ||
363 | kfree(button_control->general_control); | ||
364 | kfree(button_control->button_int_enable); | ||
365 | kfree(button_control->single_button_participation); | ||
366 | kfree(button_control->sensor_map); | ||
367 | kfree(button_control->all_button_sensitivity_adj); | ||
368 | kfree(button_control->all_button_hysteresis_threshold); | ||
369 | return error; | ||
370 | } | ||
371 | |||
372 | static int rmi_f19_init(struct rmi_function_container *fc) | ||
373 | { | ||
374 | struct rmi_device *rmi_dev = fc->rmi_dev; | ||
375 | struct rmi_device_platform_data *pdata; | ||
376 | struct f19_data *f19; | ||
377 | struct input_dev *input_dev; | ||
378 | u8 query_base_addr; | ||
379 | int rc; | ||
380 | int i; | ||
381 | int attr_count = 0; | ||
382 | |||
383 | dev_info(&fc->dev, "Intializing F19 values."); | ||
384 | |||
385 | f19 = kzalloc(sizeof(struct f19_data), GFP_KERNEL); | ||
386 | if (!f19) { | ||
387 | dev_err(&fc->dev, "Failed to allocate function data.\n"); | ||
388 | return -ENOMEM; | ||
389 | } | ||
390 | pdata = to_rmi_platform_data(rmi_dev); | ||
391 | query_base_addr = fc->fd.query_base_addr; | ||
392 | |||
393 | /* initial all default values for f19 data here */ | ||
394 | rc = rmi_read(rmi_dev, fc->fd.command_base_addr, | ||
395 | (u8 *)&f19->button_rezero); | ||
396 | if (rc < 0) { | ||
397 | dev_err(&fc->dev, "Failed to read command register.\n"); | ||
398 | goto err_free_data; | ||
399 | } | ||
400 | |||
401 | f19->button_rezero = f19->button_rezero & 1; | ||
402 | |||
403 | rc = rmi_read_block(rmi_dev, query_base_addr, (u8 *)&f19->button_query, | ||
404 | sizeof(struct f19_0d_query)); | ||
405 | f19->button_count = f19->button_query.f19_0d_query1; | ||
406 | |||
407 | if (rc < 0) { | ||
408 | dev_err(&fc->dev, "Failed to read query register.\n"); | ||
409 | goto err_free_data; | ||
410 | } | ||
411 | |||
412 | |||
413 | /* Figure out just how much data we'll need to read. */ | ||
414 | f19->button_down = kcalloc(f19->button_count, | ||
415 | sizeof(bool), GFP_KERNEL); | ||
416 | if (!f19->button_down) { | ||
417 | dev_err(&fc->dev, "Failed to allocate button state buffer.\n"); | ||
418 | rc = -ENOMEM; | ||
419 | goto err_free_data; | ||
420 | } | ||
421 | |||
422 | f19->button_data_buffer_size = (f19->button_count + 7) / 8; | ||
423 | f19->button_data_buffer = | ||
424 | kcalloc(f19->button_data_buffer_size, | ||
425 | sizeof(unsigned char), GFP_KERNEL); | ||
426 | if (!f19->button_data_buffer) { | ||
427 | dev_err(&fc->dev, "Failed to allocate button data buffer.\n"); | ||
428 | rc = -ENOMEM; | ||
429 | goto err_free_data; | ||
430 | } | ||
431 | |||
432 | f19->button_map = kcalloc(f19->button_count, | ||
433 | sizeof(unsigned char), GFP_KERNEL); | ||
434 | if (!f19->button_map) { | ||
435 | dev_err(&fc->dev, "Failed to allocate button map.\n"); | ||
436 | rc = -ENOMEM; | ||
437 | goto err_free_data; | ||
438 | } | ||
439 | |||
440 | if (pdata) { | ||
441 | if (pdata->button_map->nbuttons != f19->button_count) { | ||
442 | dev_warn(&fc->dev, | ||
443 | "Platformdata button map size (%d) != number " | ||
444 | "of buttons on device (%d) - ignored.\n", | ||
445 | pdata->button_map->nbuttons, | ||
446 | f19->button_count); | ||
447 | } else if (!pdata->button_map->map) { | ||
448 | dev_warn(&fc->dev, | ||
449 | "Platformdata button map is missing!\n"); | ||
450 | } else { | ||
451 | for (i = 0; i < pdata->button_map->nbuttons; i++) | ||
452 | f19->button_map[i] = pdata->button_map->map[i]; | ||
453 | } | ||
454 | } | ||
455 | |||
456 | f19->button_control = kzalloc(sizeof(struct f19_0d_control), | ||
457 | GFP_KERNEL); | ||
458 | |||
459 | rc = rmi_f19_initialize_control_parameters(fc->rmi_dev, | ||
460 | f19->button_control, f19->button_count, | ||
461 | f19->button_data_buffer_size, fc->fd.control_base_addr); | ||
462 | if (rc < 0) { | ||
463 | dev_err(&fc->dev, | ||
464 | "Failed to initialize F19 control params.\n"); | ||
465 | goto err_free_data; | ||
466 | } | ||
467 | |||
468 | input_dev = input_allocate_device(); | ||
469 | if (!input_dev) { | ||
470 | dev_err(&fc->dev, "Failed to allocate input device.\n"); | ||
471 | rc = -ENOMEM; | ||
472 | goto err_free_data; | ||
473 | } | ||
474 | |||
475 | f19->input = input_dev; | ||
476 | snprintf(f19->input_name, MAX_LEN, "%sfn%02x", dev_name(&rmi_dev->dev), | ||
477 | fc->fd.function_number); | ||
478 | input_dev->name = f19->input_name; | ||
479 | snprintf(f19->input_phys, MAX_LEN, "%s/input0", input_dev->name); | ||
480 | input_dev->phys = f19->input_phys; | ||
481 | input_dev->dev.parent = &rmi_dev->dev; | ||
482 | input_set_drvdata(input_dev, f19); | ||
483 | |||
484 | /* Set up any input events. */ | ||
485 | set_bit(EV_SYN, input_dev->evbit); | ||
486 | set_bit(EV_KEY, input_dev->evbit); | ||
487 | /* set bits for each button... */ | ||
488 | for (i = 0; i < f19->button_count; i++) | ||
489 | set_bit(f19->button_map[i], input_dev->keybit); | ||
490 | rc = input_register_device(input_dev); | ||
491 | if (rc < 0) { | ||
492 | dev_err(&fc->dev, "Failed to register input device.\n"); | ||
493 | goto err_free_input; | ||
494 | } | ||
495 | |||
496 | dev_dbg(&fc->dev, "Creating sysfs files.\n"); | ||
497 | /* Set up sysfs device attributes. */ | ||
498 | for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { | ||
499 | if (sysfs_create_file | ||
500 | (&fc->dev.kobj, &attrs[attr_count].attr) < 0) { | ||
501 | dev_err(&fc->dev, | ||
502 | "Failed to create sysfs file for %s.", | ||
503 | attrs[attr_count].attr.name); | ||
504 | rc = -ENODEV; | ||
505 | goto err_free_data; | ||
506 | } | ||
507 | } | ||
508 | fc->data = f19; | ||
509 | return 0; | ||
510 | |||
511 | err_free_input: | ||
512 | input_free_device(f19->input); | ||
513 | |||
514 | err_free_data: | ||
515 | if (f19) { | ||
516 | kfree(f19->button_down); | ||
517 | kfree(f19->button_data_buffer); | ||
518 | kfree(f19->button_map); | ||
519 | } | ||
520 | kfree(f19); | ||
521 | for (attr_count--; attr_count >= 0; attr_count--) | ||
522 | sysfs_remove_file(&fc->dev.kobj, | ||
523 | &attrs[attr_count].attr); | ||
524 | return rc; | ||
525 | } | ||
526 | |||
527 | int rmi_f19_attention(struct rmi_function_container *fc, u8 *irq_bits) | ||
528 | { | ||
529 | struct rmi_device *rmi_dev = fc->rmi_dev; | ||
530 | struct f19_data *f19 = fc->data; | ||
531 | u8 data_base_addr = fc->fd.data_base_addr; | ||
532 | int error; | ||
533 | int button; | ||
534 | |||
535 | /* Read the button data. */ | ||
536 | |||
537 | error = rmi_read_block(rmi_dev, data_base_addr, f19->button_data_buffer, | ||
538 | f19->button_data_buffer_size); | ||
539 | if (error < 0) { | ||
540 | dev_err(&fc->dev, "%s: Failed to read button data registers.\n", | ||
541 | __func__); | ||
542 | return error; | ||
543 | } | ||
544 | |||
545 | /* Generate events for buttons that change state. */ | ||
546 | for (button = 0; button < f19->button_count; | ||
547 | button++) { | ||
548 | int button_reg; | ||
549 | int button_shift; | ||
550 | bool button_status; | ||
551 | |||
552 | /* determine which data byte the button status is in */ | ||
553 | button_reg = button / 7; | ||
554 | /* bit shift to get button's status */ | ||
555 | button_shift = button % 8; | ||
556 | button_status = | ||
557 | ((f19->button_data_buffer[button_reg] >> button_shift) | ||
558 | & 0x01) != 0; | ||
559 | |||
560 | /* if the button state changed from the last time report it | ||
561 | * and store the new state */ | ||
562 | if (button_status != f19->button_down[button]) { | ||
563 | dev_dbg(&fc->dev, "%s: Button %d (code %d) -> %d.\n", | ||
564 | __func__, button, f19->button_map[button], | ||
565 | button_status); | ||
566 | /* Generate an event here. */ | ||
567 | input_report_key(f19->input, f19->button_map[button], | ||
568 | button_status); | ||
569 | f19->button_down[button] = button_status; | ||
570 | } | ||
571 | } | ||
572 | |||
573 | input_sync(f19->input); /* sync after groups of events */ | ||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | static void rmi_f19_remove(struct rmi_function_container *fc) | ||
578 | { | ||
579 | struct f19_data *data = fc->data; | ||
580 | if (data) { | ||
581 | kfree(data->button_down); | ||
582 | kfree(data->button_data_buffer); | ||
583 | kfree(data->button_map); | ||
584 | input_unregister_device(data->input); | ||
585 | if (data->button_control) { | ||
586 | kfree(data->button_control->general_control); | ||
587 | kfree(data->button_control->button_int_enable); | ||
588 | kfree(data->button_control-> | ||
589 | single_button_participation); | ||
590 | kfree(data->button_control->sensor_map); | ||
591 | kfree(data->button_control-> | ||
592 | all_button_sensitivity_adj); | ||
593 | kfree(data->button_control-> | ||
594 | all_button_hysteresis_threshold); | ||
595 | } | ||
596 | kfree(data->button_control); | ||
597 | } | ||
598 | kfree(fc->data); | ||
599 | } | ||
600 | |||
601 | static struct rmi_function_handler function_handler = { | ||
602 | .func = 0x19, | ||
603 | .init = rmi_f19_init, | ||
604 | .attention = rmi_f19_attention, | ||
605 | .remove = rmi_f19_remove | ||
606 | }; | ||
607 | |||
608 | static int __init rmi_f19_module_init(void) | ||
609 | { | ||
610 | int error; | ||
611 | |||
612 | error = rmi_register_function_driver(&function_handler); | ||
613 | if (error < 0) { | ||
614 | pr_err("%s: register failed!\n", __func__); | ||
615 | return error; | ||
616 | } | ||
617 | |||
618 | return 0; | ||
619 | } | ||
620 | |||
621 | static void rmi_f19_module_exit(void) | ||
622 | { | ||
623 | rmi_unregister_function_driver(&function_handler); | ||
624 | } | ||
625 | |||
626 | static ssize_t rmi_f19_filter_mode_show(struct device *dev, | ||
627 | struct device_attribute *attr, | ||
628 | char *buf) | ||
629 | { | ||
630 | struct rmi_function_container *fc; | ||
631 | struct f19_data *data; | ||
632 | |||
633 | fc = to_rmi_function_container(dev); | ||
634 | data = fc->data; | ||
635 | |||
636 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
637 | data->button_control->general_control->filter_mode); | ||
638 | |||
639 | } | ||
640 | |||
641 | static ssize_t rmi_f19_filter_mode_store(struct device *dev, | ||
642 | struct device_attribute *attr, | ||
643 | const char *buf, size_t count) | ||
644 | { | ||
645 | struct rmi_function_container *fc; | ||
646 | struct f19_data *data; | ||
647 | unsigned int new_value; | ||
648 | int result; | ||
649 | |||
650 | fc = to_rmi_function_container(dev); | ||
651 | data = fc->data; | ||
652 | if (sscanf(buf, "%u", &new_value) != 1) { | ||
653 | dev_err(dev, | ||
654 | "%s: Error - filter_mode_store has an " | ||
655 | "invalid len.\n", | ||
656 | __func__); | ||
657 | return -EINVAL; | ||
658 | } | ||
659 | |||
660 | if (new_value < 0 || new_value > 4) { | ||
661 | dev_err(dev, "%s: Error - filter_mode_store has an " | ||
662 | "invalid value %d.\n", | ||
663 | __func__, new_value); | ||
664 | return -EINVAL; | ||
665 | } | ||
666 | data->button_control->general_control->filter_mode = new_value; | ||
667 | result = rmi_write_block(fc->rmi_dev, fc->fd.control_base_addr, | ||
668 | (u8 *)data->button_control->general_control, | ||
669 | sizeof(struct f19_0d_control_0)); | ||
670 | if (result < 0) { | ||
671 | dev_err(dev, "%s : Could not write filter_mode_store to 0x%x\n", | ||
672 | __func__, fc->fd.control_base_addr); | ||
673 | return result; | ||
674 | } | ||
675 | |||
676 | return count; | ||
677 | } | ||
678 | |||
679 | static ssize_t rmi_f19_button_usage_show(struct device *dev, | ||
680 | struct device_attribute *attr, | ||
681 | char *buf) | ||
682 | { | ||
683 | struct rmi_function_container *fc; | ||
684 | struct f19_data *data; | ||
685 | |||
686 | fc = to_rmi_function_container(dev); | ||
687 | data = fc->data; | ||
688 | |||
689 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
690 | data->button_control->general_control->button_usage); | ||
691 | |||
692 | } | ||
693 | |||
694 | static ssize_t rmi_f19_button_usage_store(struct device *dev, | ||
695 | struct device_attribute *attr, | ||
696 | const char *buf, size_t count) | ||
697 | { | ||
698 | struct rmi_function_container *fc; | ||
699 | struct f19_data *data; | ||
700 | unsigned int new_value; | ||
701 | int result; | ||
702 | |||
703 | fc = to_rmi_function_container(dev); | ||
704 | data = fc->data; | ||
705 | if (sscanf(buf, "%u", &new_value) != 1) { | ||
706 | dev_err(dev, | ||
707 | "%s: Error - button_usage_store has an " | ||
708 | "invalid len.\n", | ||
709 | __func__); | ||
710 | return -EINVAL; | ||
711 | } | ||
712 | |||
713 | if (new_value < 0 || new_value > 4) { | ||
714 | dev_err(dev, "%s: Error - button_usage_store has an " | ||
715 | "invalid value %d.\n", | ||
716 | __func__, new_value); | ||
717 | return -EINVAL; | ||
718 | } | ||
719 | data->button_control->general_control->button_usage = new_value; | ||
720 | result = rmi_write_block(fc->rmi_dev, fc->fd.control_base_addr, | ||
721 | (u8 *)data->button_control->general_control, | ||
722 | sizeof(struct f19_0d_control_0)); | ||
723 | if (result < 0) { | ||
724 | dev_err(dev, "%s : Could not write button_usage_store to 0x%x\n", | ||
725 | __func__, fc->fd.control_base_addr); | ||
726 | return result; | ||
727 | } | ||
728 | |||
729 | return count; | ||
730 | |||
731 | } | ||
732 | |||
733 | static ssize_t rmi_f19_interrupt_enable_button_show(struct device *dev, | ||
734 | struct device_attribute *attr, | ||
735 | char *buf) | ||
736 | { | ||
737 | struct rmi_function_container *fc; | ||
738 | struct f19_data *data; | ||
739 | int i, len, total_len = 0; | ||
740 | char *current_buf = buf; | ||
741 | |||
742 | fc = to_rmi_function_container(dev); | ||
743 | data = fc->data; | ||
744 | /* loop through each button map value and copy its | ||
745 | * string representation into buf */ | ||
746 | for (i = 0; i < data->button_count; i++) { | ||
747 | int button_reg; | ||
748 | int button_shift; | ||
749 | int interrupt_button; | ||
750 | |||
751 | button_reg = i / 7; | ||
752 | button_shift = i % 8; | ||
753 | interrupt_button = | ||
754 | ((data->button_control-> | ||
755 | button_int_enable[button_reg].int_enabled_button >> | ||
756 | button_shift) & 0x01); | ||
757 | |||
758 | /* get next button mapping value and write it to buf */ | ||
759 | len = snprintf(current_buf, PAGE_SIZE - total_len, | ||
760 | "%u ", interrupt_button); | ||
761 | /* bump up ptr to next location in buf if the | ||
762 | * snprintf was valid. Otherwise issue an error | ||
763 | * and return. */ | ||
764 | if (len > 0) { | ||
765 | current_buf += len; | ||
766 | total_len += len; | ||
767 | } else { | ||
768 | dev_err(dev, "%s: Failed to build interrupt button" | ||
769 | " buffer, code = %d.\n", __func__, len); | ||
770 | return snprintf(buf, PAGE_SIZE, "unknown\n"); | ||
771 | } | ||
772 | } | ||
773 | len = snprintf(current_buf, PAGE_SIZE - total_len, "\n"); | ||
774 | if (len > 0) | ||
775 | total_len += len; | ||
776 | else | ||
777 | dev_warn(dev, "%s: Failed to append carriage return.\n", | ||
778 | __func__); | ||
779 | return total_len; | ||
780 | |||
781 | } | ||
782 | |||
783 | static ssize_t rmi_f19_interrupt_enable_button_store(struct device *dev, | ||
784 | struct device_attribute *attr, | ||
785 | const char *buf, size_t count) | ||
786 | { | ||
787 | struct rmi_function_container *fc; | ||
788 | struct f19_data *data; | ||
789 | int i; | ||
790 | int button_count = 0; | ||
791 | int retval = count; | ||
792 | int button_reg = 0; | ||
793 | int ctrl_bass_addr; | ||
794 | |||
795 | fc = to_rmi_function_container(dev); | ||
796 | data = fc->data; | ||
797 | for (i = 0; i < data->button_count && *buf != 0; | ||
798 | i++) { | ||
799 | int button_shift; | ||
800 | int button; | ||
801 | |||
802 | button_reg = i / 7; | ||
803 | button_shift = i % 8; | ||
804 | /* get next button mapping value and store and bump up to | ||
805 | * point to next item in buf */ | ||
806 | sscanf(buf, "%u", &button); | ||
807 | |||
808 | if (button != 0 && button != 1) { | ||
809 | dev_err(dev, | ||
810 | "%s: Error - interrupt enable button for" | ||
811 | " button %d is not a valid value 0x%x.\n", | ||
812 | __func__, i, button); | ||
813 | return -EINVAL; | ||
814 | } | ||
815 | |||
816 | if (button_shift == 0) | ||
817 | data->button_control->button_int_enable[button_reg]. | ||
818 | int_enabled_button = 0; | ||
819 | data->button_control->button_int_enable[button_reg]. | ||
820 | int_enabled_button |= (button << button_shift); | ||
821 | button_count++; | ||
822 | /* bump up buf to point to next item to read */ | ||
823 | while (*buf != 0) { | ||
824 | buf++; | ||
825 | if (*(buf - 1) == ' ') | ||
826 | break; | ||
827 | } | ||
828 | } | ||
829 | |||
830 | /* Make sure the button count matches */ | ||
831 | if (button_count != data->button_count) { | ||
832 | dev_err(dev, | ||
833 | "%s: Error - interrupt enable button count of %d" | ||
834 | " doesn't match device button count of %d.\n", | ||
835 | __func__, button_count, data->button_count); | ||
836 | return -EINVAL; | ||
837 | } | ||
838 | |||
839 | /* write back to the control register */ | ||
840 | ctrl_bass_addr = fc->fd.control_base_addr + | ||
841 | sizeof(struct f19_0d_control_0); | ||
842 | retval = rmi_write_block(fc->rmi_dev, ctrl_bass_addr, | ||
843 | (u8 *)data->button_control->button_int_enable, | ||
844 | sizeof(struct f19_0d_control_1)*(button_reg + 1)); | ||
845 | if (retval < 0) { | ||
846 | dev_err(dev, "%s : Could not write interrupt_enable_store" | ||
847 | " to 0x%x\n", __func__, ctrl_bass_addr); | ||
848 | return retval; | ||
849 | } | ||
850 | |||
851 | return count; | ||
852 | } | ||
853 | |||
854 | static ssize_t rmi_f19_single_button_show(struct device *dev, | ||
855 | struct device_attribute *attr, | ||
856 | char *buf) | ||
857 | { | ||
858 | struct rmi_function_container *fc; | ||
859 | struct f19_data *data; | ||
860 | int i, len, total_len = 0; | ||
861 | char *current_buf = buf; | ||
862 | |||
863 | fc = to_rmi_function_container(dev); | ||
864 | data = fc->data; | ||
865 | /* loop through each button map value and copy its | ||
866 | * string representation into buf */ | ||
867 | for (i = 0; i < data->button_count; i++) { | ||
868 | int button_reg; | ||
869 | int button_shift; | ||
870 | int single_button; | ||
871 | |||
872 | button_reg = i / 7; | ||
873 | button_shift = i % 8; | ||
874 | single_button = ((data->button_control-> | ||
875 | single_button_participation[button_reg].single_button | ||
876 | >> button_shift) & 0x01); | ||
877 | |||
878 | /* get next button mapping value and write it to buf */ | ||
879 | len = snprintf(current_buf, PAGE_SIZE - total_len, | ||
880 | "%u ", single_button); | ||
881 | /* bump up ptr to next location in buf if the | ||
882 | * snprintf was valid. Otherwise issue an error | ||
883 | * and return. */ | ||
884 | if (len > 0) { | ||
885 | current_buf += len; | ||
886 | total_len += len; | ||
887 | } else { | ||
888 | dev_err(dev, "%s: Failed to build signle button buffer" | ||
889 | ", code = %d.\n", __func__, len); | ||
890 | return snprintf(buf, PAGE_SIZE, "unknown\n"); | ||
891 | } | ||
892 | } | ||
893 | len = snprintf(current_buf, PAGE_SIZE - total_len, "\n"); | ||
894 | if (len > 0) | ||
895 | total_len += len; | ||
896 | else | ||
897 | dev_warn(dev, "%s: Failed to append carriage return.\n", | ||
898 | __func__); | ||
899 | |||
900 | return total_len; | ||
901 | |||
902 | } | ||
903 | |||
904 | static ssize_t rmi_f19_single_button_store(struct device *dev, | ||
905 | struct device_attribute *attr, | ||
906 | const char *buf, size_t count) | ||
907 | { | ||
908 | struct rmi_function_container *fc; | ||
909 | struct f19_data *data; | ||
910 | int i; | ||
911 | int button_count = 0; | ||
912 | int retval = count; | ||
913 | int ctrl_bass_addr; | ||
914 | int button_reg = 0; | ||
915 | |||
916 | fc = to_rmi_function_container(dev); | ||
917 | data = fc->data; | ||
918 | for (i = 0; i < data->button_count && *buf != 0; | ||
919 | i++) { | ||
920 | int button_shift; | ||
921 | int button; | ||
922 | |||
923 | button_reg = i / 7; | ||
924 | button_shift = i % 8; | ||
925 | /* get next button mapping value and store and bump up to | ||
926 | * point to next item in buf */ | ||
927 | sscanf(buf, "%u", &button); | ||
928 | |||
929 | if (button != 0 && button != 1) { | ||
930 | dev_err(dev, | ||
931 | "%s: Error - single button for button %d" | ||
932 | " is not a valid value 0x%x.\n", | ||
933 | __func__, i, button); | ||
934 | return -EINVAL; | ||
935 | } | ||
936 | if (button_shift == 0) | ||
937 | data->button_control-> | ||
938 | single_button_participation[button_reg]. | ||
939 | single_button = 0; | ||
940 | data->button_control->single_button_participation[button_reg]. | ||
941 | single_button |= (button << button_shift); | ||
942 | button_count++; | ||
943 | /* bump up buf to point to next item to read */ | ||
944 | while (*buf != 0) { | ||
945 | buf++; | ||
946 | if (*(buf - 1) == ' ') | ||
947 | break; | ||
948 | } | ||
949 | } | ||
950 | |||
951 | /* Make sure the button count matches */ | ||
952 | if (button_count != data->button_count) { | ||
953 | dev_err(dev, | ||
954 | "%s: Error - single button count of %d doesn't match" | ||
955 | " device button count of %d.\n", __func__, button_count, | ||
956 | data->button_count); | ||
957 | return -EINVAL; | ||
958 | } | ||
959 | /* write back to the control register */ | ||
960 | ctrl_bass_addr = fc->fd.control_base_addr + | ||
961 | sizeof(struct f19_0d_control_0) + | ||
962 | sizeof(struct f19_0d_control_2)*(button_reg + 1); | ||
963 | retval = rmi_write_block(fc->rmi_dev, ctrl_bass_addr, | ||
964 | (u8 *)data->button_control->single_button_participation, | ||
965 | sizeof(struct f19_0d_control_2)*(button_reg + 1)); | ||
966 | if (retval < 0) { | ||
967 | dev_err(dev, "%s : Could not write interrupt_enable_store to" | ||
968 | " 0x%x\n", __func__, ctrl_bass_addr); | ||
969 | return -EINVAL; | ||
970 | } | ||
971 | return count; | ||
972 | } | ||
973 | |||
974 | static ssize_t rmi_f19_sensor_map_show(struct device *dev, | ||
975 | struct device_attribute *attr, | ||
976 | char *buf) | ||
977 | { | ||
978 | struct rmi_function_container *fc; | ||
979 | struct f19_data *data; | ||
980 | int i, len, total_len = 0; | ||
981 | char *current_buf = buf; | ||
982 | |||
983 | fc = to_rmi_function_container(dev); | ||
984 | data = fc->data; | ||
985 | |||
986 | for (i = 0; i < data->button_count; i++) { | ||
987 | len = snprintf(current_buf, PAGE_SIZE - total_len, | ||
988 | "%u ", data->button_control->sensor_map[i]. | ||
989 | sensor_map_button); | ||
990 | /* bump up ptr to next location in buf if the | ||
991 | * snprintf was valid. Otherwise issue an error | ||
992 | * and return. */ | ||
993 | if (len > 0) { | ||
994 | current_buf += len; | ||
995 | total_len += len; | ||
996 | } else { | ||
997 | dev_err(dev, "%s: Failed to build sensor map buffer, " | ||
998 | "code = %d.\n", __func__, len); | ||
999 | return snprintf(buf, PAGE_SIZE, "unknown\n"); | ||
1000 | } | ||
1001 | } | ||
1002 | len = snprintf(current_buf, PAGE_SIZE - total_len, "\n"); | ||
1003 | if (len > 0) | ||
1004 | total_len += len; | ||
1005 | else | ||
1006 | dev_warn(dev, "%s: Failed to append carriage return.\n", | ||
1007 | __func__); | ||
1008 | return total_len; | ||
1009 | |||
1010 | |||
1011 | } | ||
1012 | |||
1013 | static ssize_t rmi_f19_sensor_map_store(struct device *dev, | ||
1014 | struct device_attribute *attr, | ||
1015 | const char *buf, size_t count) | ||
1016 | { | ||
1017 | struct rmi_function_container *fc; | ||
1018 | struct f19_data *data; | ||
1019 | int sensor_map; | ||
1020 | int i; | ||
1021 | int retval = count; | ||
1022 | int button_count = 0; | ||
1023 | int ctrl_bass_addr; | ||
1024 | int button_reg; | ||
1025 | fc = to_rmi_function_container(dev); | ||
1026 | data = fc->data; | ||
1027 | |||
1028 | if (data->button_query.configurable == 0) { | ||
1029 | dev_err(dev, | ||
1030 | "%s: Error - sensor map is not configuralbe at" | ||
1031 | " run-time", __func__); | ||
1032 | return -EINVAL; | ||
1033 | } | ||
1034 | |||
1035 | for (i = 0; i < data->button_count && *buf != 0; i++) { | ||
1036 | /* get next button mapping value and store and bump up to | ||
1037 | * point to next item in buf */ | ||
1038 | sscanf(buf, "%u", &sensor_map); | ||
1039 | |||
1040 | /* Make sure the key is a valid key */ | ||
1041 | if (sensor_map < 0 || sensor_map > 127) { | ||
1042 | dev_err(dev, | ||
1043 | "%s: Error - sensor map for button %d is" | ||
1044 | " not a valid value 0x%x.\n", | ||
1045 | __func__, i, sensor_map); | ||
1046 | return -EINVAL; | ||
1047 | } | ||
1048 | |||
1049 | data->button_control->sensor_map[i].sensor_map_button = | ||
1050 | sensor_map; | ||
1051 | button_count++; | ||
1052 | |||
1053 | /* bump up buf to point to next item to read */ | ||
1054 | while (*buf != 0) { | ||
1055 | buf++; | ||
1056 | if (*(buf - 1) == ' ') | ||
1057 | break; | ||
1058 | } | ||
1059 | } | ||
1060 | |||
1061 | if (button_count != data->button_count) { | ||
1062 | dev_err(dev, | ||
1063 | "%s: Error - button map count of %d doesn't match device " | ||
1064 | "button count of %d.\n", __func__, button_count, | ||
1065 | data->button_count); | ||
1066 | return -EINVAL; | ||
1067 | } | ||
1068 | |||
1069 | /* write back to the control register */ | ||
1070 | button_reg = (button_count / 7) + 1; | ||
1071 | ctrl_bass_addr = fc->fd.control_base_addr + | ||
1072 | sizeof(struct f19_0d_control_0) + | ||
1073 | sizeof(struct f19_0d_control_1)*button_reg + | ||
1074 | sizeof(struct f19_0d_control_2)*button_reg; | ||
1075 | retval = rmi_write_block(fc->rmi_dev, ctrl_bass_addr, | ||
1076 | (u8 *)data->button_control->sensor_map, | ||
1077 | sizeof(struct f19_0d_control_3_4)*button_count); | ||
1078 | if (retval < 0) { | ||
1079 | dev_err(dev, "%s : Could not sensor_map_store to 0x%x\n", | ||
1080 | __func__, ctrl_bass_addr); | ||
1081 | return -EINVAL; | ||
1082 | } | ||
1083 | return count; | ||
1084 | } | ||
1085 | |||
1086 | static ssize_t rmi_f19_sensitivity_adjust_show(struct device *dev, | ||
1087 | struct device_attribute *attr, | ||
1088 | char *buf) | ||
1089 | { | ||
1090 | struct rmi_function_container *fc; | ||
1091 | struct f19_data *data; | ||
1092 | |||
1093 | fc = to_rmi_function_container(dev); | ||
1094 | data = fc->data; | ||
1095 | |||
1096 | return snprintf(buf, PAGE_SIZE, "%u\n", data->button_control-> | ||
1097 | all_button_sensitivity_adj->sensitivity_adj); | ||
1098 | |||
1099 | } | ||
1100 | |||
1101 | static ssize_t rmi_f19_sensitivity_adjust_store(struct device *dev, | ||
1102 | struct device_attribute *attr, | ||
1103 | const char *buf, size_t count) | ||
1104 | { | ||
1105 | struct rmi_function_container *fc; | ||
1106 | struct f19_data *data; | ||
1107 | unsigned int new_value; | ||
1108 | int len; | ||
1109 | int ctrl_bass_addr; | ||
1110 | int button_reg; | ||
1111 | |||
1112 | fc = to_rmi_function_container(dev); | ||
1113 | |||
1114 | data = fc->data; | ||
1115 | |||
1116 | if (data->button_query.configurable == 0) { | ||
1117 | dev_err(dev, | ||
1118 | "%s: Error - sensitivity_adjust is not" | ||
1119 | " configuralbe at run-time", __func__); | ||
1120 | return -EINVAL; | ||
1121 | } | ||
1122 | |||
1123 | len = sscanf(buf, "%u", &new_value); | ||
1124 | if (new_value < 0 || new_value > 31) | ||
1125 | return -EINVAL; | ||
1126 | |||
1127 | data->button_control->all_button_sensitivity_adj->sensitivity_adj = | ||
1128 | new_value; | ||
1129 | /* write back to the control register */ | ||
1130 | button_reg = (data->button_count / 7) + 1; | ||
1131 | ctrl_bass_addr = fc->fd.control_base_addr + | ||
1132 | sizeof(struct f19_0d_control_0) + | ||
1133 | sizeof(struct f19_0d_control_1)*button_reg + | ||
1134 | sizeof(struct f19_0d_control_2)*button_reg + | ||
1135 | sizeof(struct f19_0d_control_3_4)*data->button_count; | ||
1136 | len = rmi_write_block(fc->rmi_dev, ctrl_bass_addr, | ||
1137 | (u8 *)data->button_control->all_button_sensitivity_adj, | ||
1138 | sizeof(struct f19_0d_control_5)); | ||
1139 | if (len < 0) { | ||
1140 | dev_err(dev, "%s : Could not sensitivity_adjust_store to" | ||
1141 | " 0x%x\n", __func__, ctrl_bass_addr); | ||
1142 | return len; | ||
1143 | } | ||
1144 | |||
1145 | return len; | ||
1146 | } | ||
1147 | |||
1148 | static ssize_t rmi_f19_hysteresis_threshold_show(struct device *dev, | ||
1149 | struct device_attribute *attr, | ||
1150 | char *buf) | ||
1151 | { | ||
1152 | struct rmi_function_container *fc; | ||
1153 | struct f19_data *data; | ||
1154 | |||
1155 | fc = to_rmi_function_container(dev); | ||
1156 | data = fc->data; | ||
1157 | |||
1158 | return snprintf(buf, PAGE_SIZE, "%u\n", data->button_control-> | ||
1159 | all_button_hysteresis_threshold->hysteresis_threshold); | ||
1160 | |||
1161 | } | ||
1162 | static ssize_t rmi_f19_hysteresis_threshold_store(struct device *dev, | ||
1163 | struct device_attribute *attr, | ||
1164 | const char *buf, size_t count) | ||
1165 | { | ||
1166 | struct rmi_function_container *fc; | ||
1167 | struct f19_data *data; | ||
1168 | unsigned int new_value; | ||
1169 | int len; | ||
1170 | int ctrl_bass_addr; | ||
1171 | int button_reg; | ||
1172 | |||
1173 | fc = to_rmi_function_container(dev); | ||
1174 | data = fc->data; | ||
1175 | len = sscanf(buf, "%u", &new_value); | ||
1176 | if (new_value < 0 || new_value > 15) { | ||
1177 | dev_err(dev, "%s: Error - hysteresis_threshold_store has an " | ||
1178 | "invalid value %d.\n", | ||
1179 | __func__, new_value); | ||
1180 | return -EINVAL; | ||
1181 | } | ||
1182 | data->button_control->all_button_hysteresis_threshold-> | ||
1183 | hysteresis_threshold = new_value; | ||
1184 | /* write back to the control register */ | ||
1185 | button_reg = (data->button_count / 7) + 1; | ||
1186 | ctrl_bass_addr = fc->fd.control_base_addr + | ||
1187 | sizeof(struct f19_0d_control_0) + | ||
1188 | sizeof(struct f19_0d_control_1)*button_reg + | ||
1189 | sizeof(struct f19_0d_control_2)*button_reg + | ||
1190 | sizeof(struct f19_0d_control_3_4)*data->button_count+ | ||
1191 | sizeof(struct f19_0d_control_5); | ||
1192 | len = rmi_write_block(fc->rmi_dev, ctrl_bass_addr, | ||
1193 | (u8 *)data->button_control->all_button_sensitivity_adj, | ||
1194 | sizeof(struct f19_0d_control_6)); | ||
1195 | if (len < 0) { | ||
1196 | dev_err(dev, "%s : Could not write all_button hysteresis " | ||
1197 | "threshold to 0x%x\n", __func__, ctrl_bass_addr); | ||
1198 | return -EINVAL; | ||
1199 | } | ||
1200 | |||
1201 | return count; | ||
1202 | } | ||
1203 | |||
1204 | static ssize_t rmi_f19_has_hysteresis_threshold_show(struct device *dev, | ||
1205 | struct device_attribute *attr, char *buf) | ||
1206 | { | ||
1207 | struct rmi_function_container *fc; | ||
1208 | struct f19_data *data; | ||
1209 | |||
1210 | fc = to_rmi_function_container(dev); | ||
1211 | data = fc->data; | ||
1212 | |||
1213 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1214 | data->button_query.has_hysteresis_threshold); | ||
1215 | } | ||
1216 | |||
1217 | static ssize_t rmi_f19_has_sensitivity_adjust_show(struct device *dev, | ||
1218 | struct device_attribute *attr, char *buf) | ||
1219 | { | ||
1220 | struct rmi_function_container *fc; | ||
1221 | struct f19_data *data; | ||
1222 | |||
1223 | fc = to_rmi_function_container(dev); | ||
1224 | data = fc->data; | ||
1225 | |||
1226 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1227 | data->button_query.has_sensitivity_adjust); | ||
1228 | } | ||
1229 | |||
1230 | static ssize_t rmi_f19_configurable_show(struct device *dev, | ||
1231 | struct device_attribute *attr, char *buf) | ||
1232 | { | ||
1233 | struct rmi_function_container *fc; | ||
1234 | struct f19_data *data; | ||
1235 | |||
1236 | fc = to_rmi_function_container(dev); | ||
1237 | data = fc->data; | ||
1238 | |||
1239 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1240 | data->button_query.configurable); | ||
1241 | } | ||
1242 | |||
1243 | static ssize_t rmi_f19_rezero_show(struct device *dev, | ||
1244 | struct device_attribute *attr, | ||
1245 | char *buf) | ||
1246 | { | ||
1247 | struct rmi_function_container *fc; | ||
1248 | struct f19_data *data; | ||
1249 | |||
1250 | fc = to_rmi_function_container(dev); | ||
1251 | data = fc->data; | ||
1252 | |||
1253 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1254 | data->button_rezero); | ||
1255 | |||
1256 | } | ||
1257 | |||
1258 | static ssize_t rmi_f19_rezero_store(struct device *dev, | ||
1259 | struct device_attribute *attr, | ||
1260 | const char *buf, | ||
1261 | size_t count) | ||
1262 | { | ||
1263 | struct rmi_function_container *fc; | ||
1264 | struct f19_data *data; | ||
1265 | unsigned int new_value; | ||
1266 | int len; | ||
1267 | |||
1268 | fc = to_rmi_function_container(dev); | ||
1269 | data = fc->data; | ||
1270 | len = sscanf(buf, "%u", &new_value); | ||
1271 | if (new_value != 0 && new_value != 1) { | ||
1272 | dev_err(dev, | ||
1273 | "%s: Error - rezero is not a " | ||
1274 | "valid value 0x%x.\n", | ||
1275 | __func__, new_value); | ||
1276 | return -EINVAL; | ||
1277 | } | ||
1278 | data->button_rezero = new_value & 1; | ||
1279 | len = rmi_write(fc->rmi_dev, fc->fd.command_base_addr, | ||
1280 | data->button_rezero); | ||
1281 | |||
1282 | if (len < 0) { | ||
1283 | dev_err(dev, "%s : Could not write rezero to 0x%x\n", | ||
1284 | __func__, fc->fd.command_base_addr); | ||
1285 | return -EINVAL; | ||
1286 | } | ||
1287 | return count; | ||
1288 | } | ||
1289 | |||
1290 | static ssize_t rmi_f19_button_count_show(struct device *dev, | ||
1291 | struct device_attribute *attr, | ||
1292 | char *buf) | ||
1293 | { | ||
1294 | struct rmi_function_container *fc; | ||
1295 | struct f19_data *data; | ||
1296 | |||
1297 | fc = to_rmi_function_container(dev); | ||
1298 | data = fc->data; | ||
1299 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1300 | data->button_count); | ||
1301 | } | ||
1302 | |||
1303 | static ssize_t rmi_f19_button_map_show(struct device *dev, | ||
1304 | struct device_attribute *attr, | ||
1305 | char *buf) | ||
1306 | { | ||
1307 | |||
1308 | struct rmi_function_container *fc; | ||
1309 | struct f19_data *data; | ||
1310 | int i, len, total_len = 0; | ||
1311 | char *current_buf = buf; | ||
1312 | |||
1313 | fc = to_rmi_function_container(dev); | ||
1314 | data = fc->data; | ||
1315 | /* loop through each button map value and copy its | ||
1316 | * string representation into buf */ | ||
1317 | for (i = 0; i < data->button_count; i++) { | ||
1318 | /* get next button mapping value and write it to buf */ | ||
1319 | len = snprintf(current_buf, PAGE_SIZE - total_len, | ||
1320 | "%u ", data->button_map[i]); | ||
1321 | /* bump up ptr to next location in buf if the | ||
1322 | * snprintf was valid. Otherwise issue an error | ||
1323 | * and return. */ | ||
1324 | if (len > 0) { | ||
1325 | current_buf += len; | ||
1326 | total_len += len; | ||
1327 | } else { | ||
1328 | dev_err(dev, "%s: Failed to build button map buffer, " | ||
1329 | "code = %d.\n", __func__, len); | ||
1330 | return snprintf(buf, PAGE_SIZE, "unknown\n"); | ||
1331 | } | ||
1332 | } | ||
1333 | len = snprintf(current_buf, PAGE_SIZE - total_len, "\n"); | ||
1334 | if (len > 0) | ||
1335 | total_len += len; | ||
1336 | else | ||
1337 | dev_warn(dev, "%s: Failed to append carriage return.\n", | ||
1338 | __func__); | ||
1339 | return total_len; | ||
1340 | } | ||
1341 | |||
1342 | static ssize_t rmi_f19_button_map_store(struct device *dev, | ||
1343 | struct device_attribute *attr, | ||
1344 | const char *buf, | ||
1345 | size_t count) | ||
1346 | { | ||
1347 | struct rmi_function_container *fc; | ||
1348 | struct f19_data *data; | ||
1349 | unsigned int button; | ||
1350 | int i; | ||
1351 | int retval = count; | ||
1352 | int button_count = 0; | ||
1353 | unsigned char temp_button_map[KEY_MAX]; | ||
1354 | |||
1355 | fc = to_rmi_function_container(dev); | ||
1356 | data = fc->data; | ||
1357 | |||
1358 | /* Do validation on the button map data passed in. Store button | ||
1359 | * mappings into a temp buffer and then verify button count and | ||
1360 | * data prior to clearing out old button mappings and storing the | ||
1361 | * new ones. */ | ||
1362 | for (i = 0; i < data->button_count && *buf != 0; | ||
1363 | i++) { | ||
1364 | /* get next button mapping value and store and bump up to | ||
1365 | * point to next item in buf */ | ||
1366 | sscanf(buf, "%u", &button); | ||
1367 | |||
1368 | /* Make sure the key is a valid key */ | ||
1369 | if (button > KEY_MAX) { | ||
1370 | dev_err(dev, | ||
1371 | "%s: Error - button map for button %d is not a" | ||
1372 | " valid value 0x%x.\n", __func__, i, button); | ||
1373 | retval = -EINVAL; | ||
1374 | goto err_ret; | ||
1375 | } | ||
1376 | |||
1377 | temp_button_map[i] = button; | ||
1378 | button_count++; | ||
1379 | |||
1380 | /* bump up buf to point to next item to read */ | ||
1381 | while (*buf != 0) { | ||
1382 | buf++; | ||
1383 | if (*(buf - 1) == ' ') | ||
1384 | break; | ||
1385 | } | ||
1386 | } | ||
1387 | |||
1388 | /* Make sure the button count matches */ | ||
1389 | if (button_count != data->button_count) { | ||
1390 | dev_err(dev, | ||
1391 | "%s: Error - button map count of %d doesn't match device " | ||
1392 | "button count of %d.\n", __func__, button_count, | ||
1393 | data->button_count); | ||
1394 | retval = -EINVAL; | ||
1395 | goto err_ret; | ||
1396 | } | ||
1397 | |||
1398 | /* Clear the key bits for the old button map. */ | ||
1399 | for (i = 0; i < button_count; i++) | ||
1400 | clear_bit(data->button_map[i], data->input->keybit); | ||
1401 | |||
1402 | /* Switch to the new map. */ | ||
1403 | memcpy(data->button_map, temp_button_map, | ||
1404 | data->button_count); | ||
1405 | |||
1406 | /* Loop through the key map and set the key bit for the new mapping. */ | ||
1407 | for (i = 0; i < button_count; i++) | ||
1408 | set_bit(data->button_map[i], data->input->keybit); | ||
1409 | |||
1410 | err_ret: | ||
1411 | return retval; | ||
1412 | } | ||
1413 | |||
1414 | module_init(rmi_f19_module_init); | ||
1415 | module_exit(rmi_f19_module_exit); | ||
1416 | |||
1417 | MODULE_AUTHOR("Vivian Ly <vly@synaptics.com>"); | ||
1418 | MODULE_DESCRIPTION("RMI F19 module"); | ||
1419 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/rmi4/rmi_f34.c b/drivers/input/touchscreen/rmi4/rmi_f34.c new file mode 100644 index 00000000000..33e84d2cfb2 --- /dev/null +++ b/drivers/input/touchscreen/rmi4/rmi_f34.c | |||
@@ -0,0 +1,821 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Synaptics Incorporated | ||
3 | * Copyright (c) 2011 Unixphere | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/rmi.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/version.h> | ||
23 | #include "rmi_driver.h" | ||
24 | |||
25 | /* define fn $34 commands */ | ||
26 | #define WRITE_FW_BLOCK 0x2 | ||
27 | #define ERASE_ALL 0x3 | ||
28 | #define READ_CONFIG_BLOCK 0x5 | ||
29 | #define WRITE_CONFIG_BLOCK 0x6 | ||
30 | #define ERASE_CONFIG 0x7 | ||
31 | #define ENABLE_FLASH_PROG 0xf | ||
32 | |||
33 | #define STATUS_IN_PROGRESS 0xff | ||
34 | #define STATUS_IDLE 0x80 | ||
35 | |||
36 | #define PDT_START_SCAN_LOCATION 0x00e9 | ||
37 | #define PDT_END_SCAN_LOCATION 0x0005 | ||
38 | |||
39 | #define BLK_SZ_OFF 3 | ||
40 | #define IMG_BLK_CNT_OFF 5 | ||
41 | #define CFG_BLK_CNT_OFF 7 | ||
42 | |||
43 | #define BLK_NUM_OFF 2 | ||
44 | |||
45 | #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 32) | ||
46 | #define KERNEL_VERSION_ABOVE_2_6_32 1 | ||
47 | #endif | ||
48 | |||
49 | /* data specific to fn $34 that needs to be kept around */ | ||
50 | struct rmi_fn_34_data { | ||
51 | unsigned char status; | ||
52 | unsigned char cmd; | ||
53 | unsigned short bootloaderid; | ||
54 | unsigned short blocksize; | ||
55 | unsigned short imageblockcount; | ||
56 | unsigned short configblockcount; | ||
57 | unsigned short blocknum; | ||
58 | bool inflashprogmode; | ||
59 | }; | ||
60 | |||
61 | static ssize_t rmi_fn_34_status_show(struct device *dev, | ||
62 | struct device_attribute *attr, char *buf); | ||
63 | |||
64 | static ssize_t rmi_fn_34_cmd_show(struct device *dev, | ||
65 | struct device_attribute *attr, char *buf); | ||
66 | |||
67 | static ssize_t rmi_fn_34_cmd_store(struct device *dev, | ||
68 | struct device_attribute *attr, | ||
69 | const char *buf, size_t count); | ||
70 | |||
71 | #ifdef KERNEL_VERSION_ABOVE_2_6_32 | ||
72 | static ssize_t rmi_fn_34_data_read(struct file *data_file, struct kobject *kobj, | ||
73 | struct bin_attribute *attributes, | ||
74 | char *buf, loff_t pos, size_t count); | ||
75 | |||
76 | static ssize_t rmi_fn_34_data_write(struct file *data_file, | ||
77 | struct kobject *kobj, | ||
78 | struct bin_attribute *attributes, char *buf, | ||
79 | loff_t pos, size_t count); | ||
80 | #else | ||
81 | static ssize_t rmi_fn_34_data_read(struct kobject *kobj, | ||
82 | struct bin_attribute *attributes, | ||
83 | char *buf, loff_t pos, size_t count); | ||
84 | |||
85 | static ssize_t rmi_fn_34_data_write(struct kobject *kobj, | ||
86 | struct bin_attribute *attributes, char *buf, | ||
87 | loff_t pos, size_t count); | ||
88 | #endif | ||
89 | |||
90 | static ssize_t rmi_fn_34_bootloaderid_show(struct device *dev, | ||
91 | struct device_attribute *attr, | ||
92 | char *buf); | ||
93 | |||
94 | static ssize_t rmi_fn_34_bootloaderid_store(struct device *dev, | ||
95 | struct device_attribute *attr, | ||
96 | const char *buf, size_t count); | ||
97 | |||
98 | static ssize_t rmi_fn_34_blocksize_show(struct device *dev, | ||
99 | struct device_attribute *attr, | ||
100 | char *buf); | ||
101 | |||
102 | static ssize_t rmi_fn_34_imageblockcount_show(struct device *dev, | ||
103 | struct device_attribute *attr, | ||
104 | char *buf); | ||
105 | |||
106 | static ssize_t rmi_fn_34_configblockcount_show(struct device *dev, | ||
107 | struct device_attribute *attr, | ||
108 | char *buf); | ||
109 | |||
110 | static ssize_t rmi_fn_34_blocknum_show(struct device *dev, | ||
111 | struct device_attribute *attr, | ||
112 | char *buf); | ||
113 | |||
114 | static ssize_t rmi_fn_34_blocknum_store(struct device *dev, | ||
115 | struct device_attribute *attr, | ||
116 | const char *buf, size_t count); | ||
117 | |||
118 | static ssize_t rmi_fn_34_rescanPDT_store(struct device *dev, | ||
119 | struct device_attribute *attr, | ||
120 | const char *buf, size_t count); | ||
121 | |||
122 | static struct device_attribute attrs[] = { | ||
123 | __ATTR(status, RMI_RO_ATTR, | ||
124 | rmi_fn_34_status_show, rmi_store_error), | ||
125 | /* Also, sysfs will need to have a file set up to distinguish | ||
126 | * between commands - like Config write/read, Image write/verify. */ | ||
127 | __ATTR(cmd, RMI_RW_ATTR, | ||
128 | rmi_fn_34_cmd_show, rmi_fn_34_cmd_store), | ||
129 | __ATTR(bootloaderid, RMI_RW_ATTR, | ||
130 | rmi_fn_34_bootloaderid_show, rmi_fn_34_bootloaderid_store), | ||
131 | __ATTR(blocksize, RMI_RO_ATTR, | ||
132 | rmi_fn_34_blocksize_show, rmi_store_error), | ||
133 | __ATTR(imageblockcount, RMI_RO_ATTR, | ||
134 | rmi_fn_34_imageblockcount_show, rmi_store_error), | ||
135 | __ATTR(configblockcount, RMI_RO_ATTR, | ||
136 | rmi_fn_34_configblockcount_show, rmi_store_error), | ||
137 | __ATTR(blocknum, RMI_RW_ATTR, | ||
138 | rmi_fn_34_blocknum_show, rmi_fn_34_blocknum_store), | ||
139 | __ATTR(rescanPDT, RMI_WO_ATTR, | ||
140 | rmi_show_error, rmi_fn_34_rescanPDT_store) | ||
141 | }; | ||
142 | |||
143 | struct bin_attribute dev_attr_data = { | ||
144 | .attr = { | ||
145 | .name = "data", | ||
146 | .mode = 0666}, | ||
147 | .size = 0, | ||
148 | .read = rmi_fn_34_data_read, | ||
149 | .write = rmi_fn_34_data_write, | ||
150 | }; | ||
151 | |||
152 | static int rmi_f34_init(struct rmi_function_container *fc) | ||
153 | { | ||
154 | int retval = 0; | ||
155 | int attr_count = 0; | ||
156 | struct rmi_fn_34_data *f34; | ||
157 | u16 query_base_addr; | ||
158 | u16 control_base_addr; | ||
159 | unsigned char buf[2]; | ||
160 | |||
161 | dev_info(&fc->dev, "Intializing f34 values."); | ||
162 | |||
163 | /* init instance data, fill in values and create any sysfs files */ | ||
164 | f34 = kzalloc(sizeof(struct rmi_fn_34_data), GFP_KERNEL); | ||
165 | if (!f34) { | ||
166 | dev_err(&fc->dev, "Failed to allocate rmi_fn_34_data.\n"); | ||
167 | return -ENOMEM; | ||
168 | } | ||
169 | |||
170 | fc->data = f34; | ||
171 | |||
172 | /* get the Bootloader ID and Block Size. */ | ||
173 | query_base_addr = fc->fd.query_base_addr; | ||
174 | control_base_addr = fc->fd.control_base_addr; | ||
175 | |||
176 | retval = rmi_read_block(fc->rmi_dev, query_base_addr, buf, | ||
177 | ARRAY_SIZE(buf)); | ||
178 | |||
179 | if (retval < 0) { | ||
180 | dev_err(&fc->dev, "Could not read bootloaderid from 0x%04x.\n", | ||
181 | query_base_addr); | ||
182 | goto exit_free_data; | ||
183 | } | ||
184 | batohs(&f34->bootloaderid, buf); | ||
185 | |||
186 | retval = rmi_read_block(fc->rmi_dev, query_base_addr + BLK_SZ_OFF, buf, | ||
187 | ARRAY_SIZE(buf)); | ||
188 | |||
189 | if (retval < 0) { | ||
190 | dev_err(&fc->dev, "Could not read block size from 0x%04x, " | ||
191 | "error=%d.\n", query_base_addr + BLK_SZ_OFF, retval); | ||
192 | goto exit_free_data; | ||
193 | } | ||
194 | batohs(&f34->blocksize, buf); | ||
195 | |||
196 | /* Get firmware image block count and store it in the instance data */ | ||
197 | retval = rmi_read_block(fc->rmi_dev, query_base_addr + IMG_BLK_CNT_OFF, | ||
198 | buf, ARRAY_SIZE(buf)); | ||
199 | |||
200 | if (retval < 0) { | ||
201 | dev_err(&fc->dev, "Couldn't read image block count from 0x%x, " | ||
202 | "error=%d.\n", query_base_addr + IMG_BLK_CNT_OFF, | ||
203 | retval); | ||
204 | goto exit_free_data; | ||
205 | } | ||
206 | batohs(&f34->imageblockcount, buf); | ||
207 | |||
208 | /* Get config block count and store it in the instance data */ | ||
209 | retval = rmi_read_block(fc->rmi_dev, query_base_addr + 7, buf, | ||
210 | ARRAY_SIZE(buf)); | ||
211 | |||
212 | if (retval < 0) { | ||
213 | dev_err(&fc->dev, "Couldn't read config block count from 0x%x, " | ||
214 | "error=%d.\n", query_base_addr + CFG_BLK_CNT_OFF, | ||
215 | retval); | ||
216 | goto exit_free_data; | ||
217 | } | ||
218 | batohs(&f34->configblockcount, buf); | ||
219 | |||
220 | /* We need a sysfs file for the image/config block to write or read. | ||
221 | * Set up sysfs bin file for binary data block. Since the image is | ||
222 | * already in our format there is no need to convert the data for | ||
223 | * endianess. */ | ||
224 | retval = sysfs_create_bin_file(&fc->dev.kobj, | ||
225 | &dev_attr_data); | ||
226 | if (retval < 0) { | ||
227 | dev_err(&fc->dev, "Failed to create sysfs file for F34 data " | ||
228 | "(error = %d).\n", retval); | ||
229 | retval = -ENODEV; | ||
230 | goto exit_free_data; | ||
231 | } | ||
232 | |||
233 | dev_dbg(&fc->dev, "Creating sysfs files.\n"); | ||
234 | for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { | ||
235 | if (sysfs_create_file | ||
236 | (&fc->dev.kobj, &attrs[attr_count].attr) < 0) { | ||
237 | dev_err(&fc->dev, "Failed to create sysfs file for %s.", | ||
238 | attrs[attr_count].attr.name); | ||
239 | retval = -ENODEV; | ||
240 | goto exit_free_attrs; | ||
241 | } | ||
242 | } | ||
243 | |||
244 | return retval; | ||
245 | |||
246 | exit_free_attrs: | ||
247 | for (attr_count--; attr_count >= 0; attr_count--) | ||
248 | sysfs_remove_file(&fc->dev.kobj, | ||
249 | &attrs[attr_count].attr); | ||
250 | exit_free_data: | ||
251 | kfree(f34); | ||
252 | return retval; | ||
253 | } | ||
254 | |||
255 | static int f34_read_status(struct rmi_function_container *fc) | ||
256 | { | ||
257 | struct rmi_fn_34_data *instance_data = fc->data; | ||
258 | u16 data_base_addr = fc->fd.data_base_addr; | ||
259 | u8 status; | ||
260 | int retval; | ||
261 | |||
262 | /* Read the Fn $34 status from F34_Flash_Data3 to see the previous | ||
263 | * commands status. F34_Flash_Data3 will be the address after the | ||
264 | * 2 block number registers plus blocksize Data registers. | ||
265 | * inform user space - through a sysfs param. */ | ||
266 | retval = rmi_read(fc->rmi_dev, | ||
267 | data_base_addr + instance_data->blocksize + | ||
268 | BLK_NUM_OFF, &status); | ||
269 | |||
270 | if (retval < 0) { | ||
271 | dev_err(&fc->dev, "Could not read status from 0x%x\n", | ||
272 | data_base_addr + instance_data->blocksize + BLK_NUM_OFF); | ||
273 | status = 0xff; /* failure */ | ||
274 | } | ||
275 | |||
276 | /* set a sysfs value that the user mode can read - only | ||
277 | * upper 4 bits are the status. successful is $80, anything | ||
278 | * else is failure */ | ||
279 | instance_data->status = status & 0xf0; | ||
280 | |||
281 | /* put mode into Flash Prog Mode when we successfully do | ||
282 | * an Enable Flash Prog cmd. */ | ||
283 | if ((instance_data->status == STATUS_IDLE) && | ||
284 | (instance_data->cmd == ENABLE_FLASH_PROG)) | ||
285 | instance_data->inflashprogmode = true; | ||
286 | |||
287 | return retval; | ||
288 | } | ||
289 | |||
290 | int rmi_f34_attention(struct rmi_function_container *fc, u8 *irq_bits) | ||
291 | { | ||
292 | return f34_read_status(fc); | ||
293 | } | ||
294 | |||
295 | static struct rmi_function_handler function_handler = { | ||
296 | .func = 0x34, | ||
297 | .init = rmi_f34_init, | ||
298 | .attention = rmi_f34_attention | ||
299 | }; | ||
300 | |||
301 | static ssize_t rmi_fn_34_bootloaderid_show(struct device *dev, | ||
302 | struct device_attribute *attr, | ||
303 | char *buf) | ||
304 | { | ||
305 | struct rmi_function_container *fc; | ||
306 | struct rmi_fn_34_data *instance_data; | ||
307 | |||
308 | fc = to_rmi_function_container(dev); | ||
309 | instance_data = fc->data; | ||
310 | |||
311 | return snprintf(buf, PAGE_SIZE, "%u\n", instance_data->bootloaderid); | ||
312 | } | ||
313 | |||
314 | static ssize_t rmi_fn_34_bootloaderid_store(struct device *dev, | ||
315 | struct device_attribute *attr, | ||
316 | const char *buf, | ||
317 | size_t count) | ||
318 | { | ||
319 | int error; | ||
320 | unsigned long val; | ||
321 | unsigned char data[2]; | ||
322 | struct rmi_function_container *fc; | ||
323 | struct rmi_fn_34_data *instance_data; | ||
324 | u16 data_base_addr; | ||
325 | |||
326 | fc = to_rmi_function_container(dev); | ||
327 | instance_data = fc->data; | ||
328 | |||
329 | /* need to convert the string data to an actual value */ | ||
330 | error = strict_strtoul(buf, 10, &val); | ||
331 | |||
332 | if (error) | ||
333 | return error; | ||
334 | |||
335 | instance_data->bootloaderid = val; | ||
336 | |||
337 | /* Write the Bootloader ID key data back to the first two Block | ||
338 | * Data registers (F34_Flash_Data2.0 and F34_Flash_Data2.1). */ | ||
339 | hstoba(data, (unsigned short)val); | ||
340 | data_base_addr = fc->fd.data_base_addr; | ||
341 | |||
342 | error = rmi_write_block(fc->rmi_dev, | ||
343 | data_base_addr + BLK_NUM_OFF, | ||
344 | data, | ||
345 | ARRAY_SIZE(data)); | ||
346 | |||
347 | if (error < 0) { | ||
348 | dev_err(dev, "%s : Could not write bootloader id to 0x%x\n", | ||
349 | __func__, data_base_addr + BLK_NUM_OFF); | ||
350 | return error; | ||
351 | } | ||
352 | |||
353 | return count; | ||
354 | } | ||
355 | |||
356 | static ssize_t rmi_fn_34_blocksize_show(struct device *dev, | ||
357 | struct device_attribute *attr, | ||
358 | char *buf) | ||
359 | { | ||
360 | struct rmi_function_container *fc; | ||
361 | struct rmi_fn_34_data *instance_data; | ||
362 | |||
363 | fc = to_rmi_function_container(dev); | ||
364 | instance_data = fc->data; | ||
365 | |||
366 | return snprintf(buf, PAGE_SIZE, "%u\n", instance_data->blocksize); | ||
367 | } | ||
368 | |||
369 | static ssize_t rmi_fn_34_imageblockcount_show(struct device *dev, | ||
370 | struct device_attribute *attr, | ||
371 | char *buf) | ||
372 | { | ||
373 | struct rmi_function_container *fc; | ||
374 | struct rmi_fn_34_data *instance_data; | ||
375 | |||
376 | fc = to_rmi_function_container(dev); | ||
377 | instance_data = fc->data; | ||
378 | |||
379 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
380 | instance_data->imageblockcount); | ||
381 | } | ||
382 | |||
383 | static ssize_t rmi_fn_34_configblockcount_show(struct device *dev, | ||
384 | struct device_attribute *attr, | ||
385 | char *buf) | ||
386 | { | ||
387 | struct rmi_function_container *fc; | ||
388 | struct rmi_fn_34_data *instance_data; | ||
389 | |||
390 | fc = to_rmi_function_container(dev); | ||
391 | instance_data = fc->data; | ||
392 | |||
393 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
394 | instance_data->configblockcount); | ||
395 | } | ||
396 | |||
397 | static ssize_t rmi_fn_34_status_show(struct device *dev, | ||
398 | struct device_attribute *attr, | ||
399 | char *buf) | ||
400 | { | ||
401 | struct rmi_function_container *fc; | ||
402 | struct rmi_fn_34_data *instance_data; | ||
403 | int retval; | ||
404 | |||
405 | fc = to_rmi_function_container(dev); | ||
406 | instance_data = fc->data; | ||
407 | |||
408 | retval = f34_read_status(fc); | ||
409 | |||
410 | return snprintf(buf, PAGE_SIZE, "%u\n", instance_data->status); | ||
411 | } | ||
412 | |||
413 | static ssize_t rmi_fn_34_cmd_show(struct device *dev, | ||
414 | struct device_attribute *attr, | ||
415 | char *buf) | ||
416 | { | ||
417 | struct rmi_function_container *fc; | ||
418 | struct rmi_fn_34_data *instance_data; | ||
419 | |||
420 | fc = to_rmi_function_container(dev); | ||
421 | instance_data = fc->data; | ||
422 | |||
423 | return snprintf(buf, PAGE_SIZE, "%u\n", instance_data->cmd); | ||
424 | } | ||
425 | |||
426 | static ssize_t rmi_fn_34_cmd_store(struct device *dev, | ||
427 | struct device_attribute *attr, | ||
428 | const char *buf, | ||
429 | size_t count) | ||
430 | { | ||
431 | struct rmi_function_container *fc; | ||
432 | struct rmi_fn_34_data *instance_data; | ||
433 | unsigned long val; | ||
434 | u16 data_base_addr; | ||
435 | int error; | ||
436 | |||
437 | fc = to_rmi_function_container(dev); | ||
438 | instance_data = fc->data; | ||
439 | data_base_addr = fc->fd.data_base_addr; | ||
440 | |||
441 | /* need to convert the string data to an actual value */ | ||
442 | error = strict_strtoul(buf, 10, &val); | ||
443 | if (error) | ||
444 | return error; | ||
445 | |||
446 | /* make sure we are in Flash Prog mode for all cmds except the | ||
447 | * Enable Flash Programming cmd - otherwise we are in error */ | ||
448 | if ((val != ENABLE_FLASH_PROG) && !instance_data->inflashprogmode) { | ||
449 | dev_err(dev, "%s: CANNOT SEND CMD %d TO SENSOR - " | ||
450 | "NOT IN FLASH PROG MODE\n" | ||
451 | , __func__, data_base_addr); | ||
452 | return -EINVAL; | ||
453 | } | ||
454 | |||
455 | instance_data->cmd = val; | ||
456 | |||
457 | /* Validate command value and (if necessary) write it to the command | ||
458 | * register. | ||
459 | */ | ||
460 | switch (instance_data->cmd) { | ||
461 | case ENABLE_FLASH_PROG: | ||
462 | case ERASE_ALL: | ||
463 | case ERASE_CONFIG: | ||
464 | case WRITE_FW_BLOCK: | ||
465 | case READ_CONFIG_BLOCK: | ||
466 | case WRITE_CONFIG_BLOCK: | ||
467 | /* Reset the status to indicate we are in progress on a cmd. */ | ||
468 | /* The status will change when the ATTN interrupt happens | ||
469 | and the status of the cmd that was issued is read from | ||
470 | the F34_Flash_Data3 register - result should be 0x80 for | ||
471 | success - any other value indicates an error */ | ||
472 | |||
473 | /* Issue the command to the device. */ | ||
474 | error = rmi_write(fc->rmi_dev, | ||
475 | data_base_addr + instance_data->blocksize + | ||
476 | BLK_NUM_OFF, instance_data->cmd); | ||
477 | |||
478 | if (error < 0) { | ||
479 | dev_err(dev, "%s: Could not write command 0x%02x " | ||
480 | "to 0x%04x\n", __func__, instance_data->cmd, | ||
481 | data_base_addr + instance_data->blocksize + | ||
482 | BLK_NUM_OFF); | ||
483 | return error; | ||
484 | } | ||
485 | |||
486 | if (instance_data->cmd == ENABLE_FLASH_PROG) | ||
487 | instance_data->inflashprogmode = true; | ||
488 | |||
489 | /* set status to indicate we are in progress */ | ||
490 | instance_data->status = STATUS_IN_PROGRESS; | ||
491 | break; | ||
492 | default: | ||
493 | dev_dbg(dev, "%s: RMI4 function $34 - " | ||
494 | "unknown command 0x%02lx.\n", __func__, val); | ||
495 | count = -EINVAL; | ||
496 | break; | ||
497 | } | ||
498 | |||
499 | return count; | ||
500 | } | ||
501 | |||
502 | static ssize_t rmi_fn_34_blocknum_show(struct device *dev, | ||
503 | struct device_attribute *attr, | ||
504 | char *buf) | ||
505 | { | ||
506 | struct rmi_function_container *fc; | ||
507 | struct rmi_fn_34_data *instance_data; | ||
508 | |||
509 | fc = to_rmi_function_container(dev); | ||
510 | instance_data = fc->data; | ||
511 | |||
512 | return snprintf(buf, PAGE_SIZE, "%u\n", instance_data->blocknum); | ||
513 | } | ||
514 | |||
515 | static ssize_t rmi_fn_34_blocknum_store(struct device *dev, | ||
516 | struct device_attribute *attr, | ||
517 | const char *buf, | ||
518 | size_t count) | ||
519 | { | ||
520 | int error; | ||
521 | unsigned long val; | ||
522 | unsigned char data[2]; | ||
523 | struct rmi_function_container *fc; | ||
524 | struct rmi_fn_34_data *instance_data; | ||
525 | u16 data_base_addr; | ||
526 | |||
527 | fc = to_rmi_function_container(dev); | ||
528 | instance_data = fc->data; | ||
529 | data_base_addr = fc->fd.data_base_addr; | ||
530 | |||
531 | /* need to convert the string data to an actual value */ | ||
532 | error = strict_strtoul(buf, 10, &val); | ||
533 | |||
534 | if (error) | ||
535 | return error; | ||
536 | |||
537 | instance_data->blocknum = val; | ||
538 | |||
539 | /* Write the Block Number data back to the first two Block | ||
540 | * Data registers (F34_Flash_Data_0 and F34_Flash_Data_1). */ | ||
541 | hstoba(data, (unsigned short)val); | ||
542 | |||
543 | error = rmi_write_block(fc->rmi_dev, | ||
544 | data_base_addr, | ||
545 | data, | ||
546 | ARRAY_SIZE(data)); | ||
547 | |||
548 | if (error < 0) { | ||
549 | dev_err(dev, "%s : Could not write block number %u to 0x%x\n", | ||
550 | __func__, instance_data->blocknum, data_base_addr); | ||
551 | return error; | ||
552 | } | ||
553 | |||
554 | return count; | ||
555 | } | ||
556 | |||
557 | static ssize_t rmi_fn_34_rescanPDT_store(struct device *dev, | ||
558 | struct device_attribute *attr, | ||
559 | const char *buf, size_t count) | ||
560 | { | ||
561 | struct rmi_function_container *fc; | ||
562 | struct rmi_fn_34_data *instance_data; | ||
563 | struct rmi_device *rmi_dev; | ||
564 | struct rmi_driver_data *driver_data; | ||
565 | struct pdt_entry pdt_entry; | ||
566 | bool fn01found = false; | ||
567 | bool fn34found = false; | ||
568 | unsigned int rescan; | ||
569 | int irq_count = 0; | ||
570 | int retval = 0; | ||
571 | int i; | ||
572 | |||
573 | /* Rescan of the PDT is needed since issuing the Flash Enable cmd | ||
574 | * the device registers for Fn$01 and Fn$34 moving around because | ||
575 | * of the change from Bootloader mode to Flash Programming mode | ||
576 | * may change to a different PDT with only Fn$01 and Fn$34 that | ||
577 | * could have addresses for query, control, data, command registers | ||
578 | * that differ from the PDT scan done at device initialization. */ | ||
579 | |||
580 | fc = to_rmi_function_container(dev); | ||
581 | instance_data = fc->data; | ||
582 | rmi_dev = fc->rmi_dev; | ||
583 | driver_data = rmi_get_driverdata(rmi_dev); | ||
584 | |||
585 | /* Make sure we are only in Flash Programming mode - DON'T | ||
586 | * ALLOW THIS IN UI MODE. */ | ||
587 | if (instance_data->cmd != ENABLE_FLASH_PROG) { | ||
588 | dev_err(dev, "%s: NOT IN FLASH PROG MODE - CAN'T RESCAN PDT.\n" | ||
589 | , __func__); | ||
590 | return -EINVAL; | ||
591 | } | ||
592 | |||
593 | /* The only good value to write to this is 1, we allow 0, but with | ||
594 | * no effect (this is consistent with the way the command bit works. */ | ||
595 | if (sscanf(buf, "%u", &rescan) != 1) | ||
596 | return -EINVAL; | ||
597 | if (rescan < 0 || rescan > 1) | ||
598 | return -EINVAL; | ||
599 | |||
600 | /* 0 has no effect, so we skip it entirely. */ | ||
601 | if (rescan) { | ||
602 | /* rescan the PDT - filling in Fn01 and Fn34 addresses - | ||
603 | * this is only temporary - the device will need to be reset | ||
604 | * to return the PDT to the normal values. */ | ||
605 | |||
606 | /* mini-parse the PDT - we only have to get Fn$01 and Fn$34 and | ||
607 | since we are Flash Programming mode we only have page 0. */ | ||
608 | for (i = PDT_START_SCAN_LOCATION; i >= PDT_END_SCAN_LOCATION; | ||
609 | i -= sizeof(pdt_entry)) { | ||
610 | retval = rmi_read_block(rmi_dev, i, (u8 *)&pdt_entry, | ||
611 | sizeof(pdt_entry)); | ||
612 | if (retval != sizeof(pdt_entry)) { | ||
613 | dev_err(dev, "%s: err frm rmi_read_block pdt " | ||
614 | "entry data from PDT, " | ||
615 | "error = %d.", __func__, retval); | ||
616 | return retval; | ||
617 | } | ||
618 | |||
619 | if ((pdt_entry.function_number == 0x00) || | ||
620 | (pdt_entry.function_number == 0xff)) | ||
621 | break; | ||
622 | |||
623 | dev_dbg(dev, "%s: Found F%.2X\n", | ||
624 | __func__, pdt_entry.function_number); | ||
625 | |||
626 | /* f01 found - just fill in the new addresses in | ||
627 | * the existing fc. */ | ||
628 | if (pdt_entry.function_number == 0x01) { | ||
629 | struct rmi_function_container *f01_fc = | ||
630 | driver_data->f01_container; | ||
631 | fn01found = true; | ||
632 | f01_fc->fd.query_base_addr = | ||
633 | pdt_entry.query_base_addr; | ||
634 | f01_fc->fd.command_base_addr = | ||
635 | pdt_entry.command_base_addr; | ||
636 | f01_fc->fd.control_base_addr = | ||
637 | pdt_entry.control_base_addr; | ||
638 | f01_fc->fd.data_base_addr = | ||
639 | pdt_entry.data_base_addr; | ||
640 | f01_fc->fd.function_number = | ||
641 | pdt_entry.function_number; | ||
642 | f01_fc->fd.interrupt_source_count = | ||
643 | pdt_entry.interrupt_source_count; | ||
644 | f01_fc->num_of_irqs = | ||
645 | pdt_entry.interrupt_source_count; | ||
646 | f01_fc->irq_pos = irq_count; | ||
647 | |||
648 | irq_count += f01_fc->num_of_irqs; | ||
649 | |||
650 | if (fn34found) | ||
651 | break; | ||
652 | } | ||
653 | |||
654 | /* f34 found - just fill in the new addresses in | ||
655 | * the existing fc. */ | ||
656 | if (pdt_entry.function_number == 0x34) { | ||
657 | fn34found = true; | ||
658 | fc->fd.query_base_addr = | ||
659 | pdt_entry.query_base_addr; | ||
660 | fc->fd.command_base_addr = | ||
661 | pdt_entry.command_base_addr; | ||
662 | fc->fd.control_base_addr = | ||
663 | pdt_entry.control_base_addr; | ||
664 | fc->fd.data_base_addr = | ||
665 | pdt_entry.data_base_addr; | ||
666 | fc->fd.function_number = | ||
667 | pdt_entry.function_number; | ||
668 | fc->fd.interrupt_source_count = | ||
669 | pdt_entry.interrupt_source_count; | ||
670 | fc->num_of_irqs = | ||
671 | pdt_entry.interrupt_source_count; | ||
672 | fc->irq_pos = irq_count; | ||
673 | |||
674 | irq_count += fc->num_of_irqs; | ||
675 | |||
676 | if (fn01found) | ||
677 | break; | ||
678 | } | ||
679 | |||
680 | } | ||
681 | |||
682 | if (!fn01found || !fn34found) { | ||
683 | dev_err(dev, "%s: failed to find fn$01 or fn$34 trying " | ||
684 | "to do rescan PDT.\n" | ||
685 | , __func__); | ||
686 | return -EINVAL; | ||
687 | } | ||
688 | } | ||
689 | |||
690 | return count; | ||
691 | } | ||
692 | |||
693 | #ifdef KERNEL_VERSION_ABOVE_2_6_32 | ||
694 | static ssize_t rmi_fn_34_data_read(struct file *data_file, | ||
695 | struct kobject *kobj, | ||
696 | struct bin_attribute *attributes, | ||
697 | char *buf, | ||
698 | loff_t pos, | ||
699 | size_t count) | ||
700 | #else | ||
701 | static ssize_t rmi_fn_34_data_read(struct kobject *kobj, | ||
702 | struct bin_attribute *attributes, | ||
703 | char *buf, | ||
704 | loff_t pos, | ||
705 | size_t count) | ||
706 | #endif | ||
707 | { | ||
708 | struct device *dev = container_of(kobj, struct device, kobj); | ||
709 | struct rmi_function_container *fc; | ||
710 | struct rmi_fn_34_data *instance_data; | ||
711 | u16 data_base_addr; | ||
712 | int error; | ||
713 | |||
714 | fc = to_rmi_function_container(dev); | ||
715 | instance_data = fc->data; | ||
716 | |||
717 | data_base_addr = fc->fd.data_base_addr; | ||
718 | |||
719 | if (count != instance_data->blocksize) { | ||
720 | dev_err(dev, | ||
721 | "%s : Incorrect F34 block size %d. " | ||
722 | "Expected size %d.\n", | ||
723 | __func__, count, instance_data->blocksize); | ||
724 | return -EINVAL; | ||
725 | } | ||
726 | |||
727 | /* Read the data from flash into buf. The app layer will be blocked | ||
728 | * at reading from the sysfs file. When we return the count (or | ||
729 | * error if we fail) the app will resume. */ | ||
730 | error = rmi_read_block(fc->rmi_dev, data_base_addr + BLK_NUM_OFF, | ||
731 | (unsigned char *)buf, count); | ||
732 | |||
733 | if (error < 0) { | ||
734 | dev_err(dev, "%s : Could not read data from 0x%04x\n", | ||
735 | __func__, data_base_addr + BLK_NUM_OFF); | ||
736 | return error; | ||
737 | } | ||
738 | |||
739 | return count; | ||
740 | } | ||
741 | |||
742 | #ifdef KERNEL_VERSION_ABOVE_2_6_32 | ||
743 | static ssize_t rmi_fn_34_data_write(struct file *data_file, | ||
744 | struct kobject *kobj, | ||
745 | struct bin_attribute *attributes, | ||
746 | char *buf, | ||
747 | loff_t pos, | ||
748 | size_t count) | ||
749 | #else | ||
750 | static ssize_t rmi_fn_34_data_write(struct kobject *kobj, | ||
751 | struct bin_attribute *attributes, | ||
752 | char *buf, | ||
753 | loff_t pos, | ||
754 | size_t count) | ||
755 | #endif | ||
756 | { | ||
757 | struct device *dev = container_of(kobj, struct device, kobj); | ||
758 | struct rmi_function_container *fc; | ||
759 | struct rmi_fn_34_data *instance_data; | ||
760 | u16 data_base_addr; | ||
761 | int error; | ||
762 | |||
763 | fc = to_rmi_function_container(dev); | ||
764 | instance_data = fc->data; | ||
765 | |||
766 | data_base_addr = fc->fd.data_base_addr; | ||
767 | |||
768 | /* Write the data from buf to flash. The app layer will be | ||
769 | * blocked at writing to the sysfs file. When we return the | ||
770 | * count (or error if we fail) the app will resume. */ | ||
771 | |||
772 | if (count != instance_data->blocksize) { | ||
773 | dev_err(dev, | ||
774 | "%s : Incorrect F34 block size %d. " | ||
775 | "Expected size %d.\n", | ||
776 | __func__, count, instance_data->blocksize); | ||
777 | return -EINVAL; | ||
778 | } | ||
779 | |||
780 | /* Write the data block - only if the count is non-zero */ | ||
781 | if (count) { | ||
782 | error = rmi_write_block(fc->rmi_dev, | ||
783 | data_base_addr + BLK_NUM_OFF, | ||
784 | (unsigned char *)buf, | ||
785 | count); | ||
786 | |||
787 | if (error < 0) { | ||
788 | dev_err(dev, "%s : Could not write block data " | ||
789 | "to 0x%x\n", __func__, | ||
790 | data_base_addr + BLK_NUM_OFF); | ||
791 | return error; | ||
792 | } | ||
793 | } | ||
794 | |||
795 | return count; | ||
796 | } | ||
797 | |||
798 | static int __init rmi_f34_module_init(void) | ||
799 | { | ||
800 | int error; | ||
801 | |||
802 | error = rmi_register_function_driver(&function_handler); | ||
803 | if (error < 0) { | ||
804 | pr_err("%s : register failed !\n", __func__); | ||
805 | return error; | ||
806 | } | ||
807 | |||
808 | return 0; | ||
809 | } | ||
810 | |||
811 | static void rmi_f34_module_exit(void) | ||
812 | { | ||
813 | rmi_unregister_function_driver(&function_handler); | ||
814 | } | ||
815 | |||
816 | module_init(rmi_f34_module_init); | ||
817 | module_exit(rmi_f34_module_exit); | ||
818 | |||
819 | MODULE_AUTHOR("Eric Andersson <eric.andersson@unixphere.com>"); | ||
820 | MODULE_DESCRIPTION("RMI f34 module"); | ||
821 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/rmi4/rmi_f54.c b/drivers/input/touchscreen/rmi4/rmi_f54.c new file mode 100644 index 00000000000..11bb0b934be --- /dev/null +++ b/drivers/input/touchscreen/rmi4/rmi_f54.c | |||
@@ -0,0 +1,1347 @@ | |||
1 | |||
2 | /* | ||
3 | * Copyright (c) 2011 Synaptics Incorporated | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | #include <linux/hrtimer.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/rmi.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/version.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include "rmi_driver.h" | ||
26 | |||
27 | /* Set this to 1 for raw hex dump of returned data. */ | ||
28 | #define RAW_HEX 0 | ||
29 | /* Set this to 1 for human readable dump of returned data. */ | ||
30 | #define HUMAN_READABLE 0 | ||
31 | /* The watchdog timer can be useful when debugging certain firmware related | ||
32 | * issues. | ||
33 | */ | ||
34 | #define F54_WATCHDOG 1 | ||
35 | |||
36 | #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 32) | ||
37 | #define KERNEL_VERSION_ABOVE_2_6_32 1 | ||
38 | #endif | ||
39 | |||
40 | /* define fn $54 commands */ | ||
41 | #define GET_REPORT 1 | ||
42 | #define FORCE_CAL 2 | ||
43 | |||
44 | /* status */ | ||
45 | #define BUSY 1 | ||
46 | #define IDLE 0 | ||
47 | |||
48 | /* Offsets for data */ | ||
49 | #define RMI_F54_REPORT_DATA_OFFSET 3 | ||
50 | #define RMI_F54_FIFO_OFFSET 1 | ||
51 | #define RMI_F54_NUM_TX_OFFSET 1 | ||
52 | #define RMI_F54_NUM_RX_OFFSET 0 | ||
53 | |||
54 | /* Fixed sizes of reports */ | ||
55 | #define RMI_54_FULL_RAW_CAP_MIN_MAX_SIZE 4 | ||
56 | #define RMI_54_HIGH_RESISTANCE_SIZE 6 | ||
57 | |||
58 | /* definitions for F54 Query Registers in ultra-portable unionstruct form */ | ||
59 | struct f54_ad_query { | ||
60 | /* query 0 */ | ||
61 | u8 number_of_receiver_electrodes; | ||
62 | |||
63 | /* query 1 */ | ||
64 | u8 number_of_transmitter_electrodes; | ||
65 | |||
66 | union { | ||
67 | struct { | ||
68 | /* query2 */ | ||
69 | u8 f54_ad_query2_b0__1:2; | ||
70 | u8 has_baseline:1; | ||
71 | u8 has_image8:1; | ||
72 | u8 f54_ad_query2_b4__5:2; | ||
73 | u8 has_image16:1; | ||
74 | u8 f54_ad_query2_b7:1; | ||
75 | }; | ||
76 | u8 f54_ad_query2; | ||
77 | }; | ||
78 | |||
79 | /* query 3.0 and 3.1 */ | ||
80 | u16 clock_rate; | ||
81 | |||
82 | /* query 4 */ | ||
83 | u8 touch_controller_family; | ||
84 | |||
85 | /* query 5 */ | ||
86 | union { | ||
87 | struct { | ||
88 | u8 has_pixel_touch_threshold_adjustment:1; | ||
89 | u8 f54_ad_query5_b1__7:7; | ||
90 | }; | ||
91 | u8 f54_ad_query5; | ||
92 | }; | ||
93 | |||
94 | /* query 6 */ | ||
95 | union { | ||
96 | struct { | ||
97 | u8 has_sensor_assignment:1; | ||
98 | u8 has_interference_metric:1; | ||
99 | u8 has_sense_frequency_control:1; | ||
100 | u8 has_firmware_noise_mitigation:1; | ||
101 | u8 f54_ad_query6_b4:1; | ||
102 | u8 has_two_byte_report_rate:1; | ||
103 | u8 has_one_byte_report_rate:1; | ||
104 | u8 has_relaxation_control:1; | ||
105 | }; | ||
106 | u8 f54_ad_query6; | ||
107 | }; | ||
108 | |||
109 | /* query 7 */ | ||
110 | union { | ||
111 | struct { | ||
112 | u8 curve_compensation_mode:2; | ||
113 | u8 f54_ad_query7_b2__7:6; | ||
114 | }; | ||
115 | u8 f54_ad_query7; | ||
116 | }; | ||
117 | |||
118 | /* query 8 */ | ||
119 | union { | ||
120 | struct { | ||
121 | u8 f54_ad_query2_b0:1; | ||
122 | u8 has_iir_filter:1; | ||
123 | u8 has_cmn_removal:1; | ||
124 | u8 has_cmn_maximum:1; | ||
125 | u8 has_pixel_threshold_hysteresis:1; | ||
126 | u8 has_edge_compensation:1; | ||
127 | u8 has_perf_frequency_noisecontrol:1; | ||
128 | u8 f54_ad_query8_b7:1; | ||
129 | }; | ||
130 | u8 f54_ad_query8; | ||
131 | }; | ||
132 | |||
133 | u8 f54_ad_query9; | ||
134 | u8 f54_ad_query10; | ||
135 | u8 f54_ad_query11; | ||
136 | |||
137 | /* query 12 */ | ||
138 | union { | ||
139 | struct { | ||
140 | u8 number_of_sensing_frequencies:4; | ||
141 | u8 f54_ad_query12_b4__7:4; | ||
142 | }; | ||
143 | u8 f54_ad_query12; | ||
144 | }; | ||
145 | }; | ||
146 | |||
147 | /* define report types */ | ||
148 | enum f54_report_types { | ||
149 | /* The numbering should follow automatically, here for clarity */ | ||
150 | F54_8BIT_IMAGE = 1, | ||
151 | F54_16BIT_IMAGE = 2, | ||
152 | F54_RAW_16BIT_IMAGE = 3, | ||
153 | F54_HIGH_RESISTANCE = 4, | ||
154 | F54_TX_TO_TX_SHORT = 5, | ||
155 | F54_RX_TO_RX1 = 7, | ||
156 | F54_TRUE_BASELINE = 9, | ||
157 | F54_FULL_RAW_CAP_MIN_MAX = 13, | ||
158 | F54_RX_OPENS1 = 14, | ||
159 | F54_TX_OPEN = 15, | ||
160 | F54_TX_TO_GROUND = 16, | ||
161 | F54_RX_TO_RX2 = 17, | ||
162 | F54_RX_OPENS2 = 18, | ||
163 | F54_FULL_RAW_CAP = 19, | ||
164 | F54_FULL_RAW_CAP_RX_COUPLING_COMP = 20 | ||
165 | }; | ||
166 | |||
167 | /* data specific to fn $54 that needs to be kept around */ | ||
168 | struct rmi_fn_54_data { | ||
169 | struct f54_ad_query query; | ||
170 | u8 cmd; | ||
171 | enum f54_report_types report_type; | ||
172 | u16 fifoindex; | ||
173 | signed char status; | ||
174 | bool no_auto_cal; | ||
175 | /* | ||
176 | * May need to do something to make sure this reflects what is currently | ||
177 | * in data. | ||
178 | */ | ||
179 | unsigned int report_size; | ||
180 | unsigned char *report_data; | ||
181 | unsigned int bufsize; | ||
182 | struct mutex data_mutex; | ||
183 | struct lock_class_key data_key; | ||
184 | struct mutex status_mutex; | ||
185 | struct lock_class_key status_key; | ||
186 | #if F54_WATCHDOG | ||
187 | struct hrtimer watchdog; | ||
188 | #endif | ||
189 | struct rmi_function_container *fc; | ||
190 | struct work_struct work; | ||
191 | }; | ||
192 | |||
193 | /* sysfs functions */ | ||
194 | static ssize_t rmi_fn_54_report_type_show(struct device *dev, | ||
195 | struct device_attribute *attr, char *buf); | ||
196 | |||
197 | static ssize_t rmi_fn_54_report_type_store(struct device *dev, | ||
198 | struct device_attribute *attr, | ||
199 | const char *buf, size_t count); | ||
200 | |||
201 | static ssize_t rmi_fn_54_get_report_store(struct device *dev, | ||
202 | struct device_attribute *attr, | ||
203 | const char *buf, size_t count); | ||
204 | |||
205 | static ssize_t rmi_fn_54_force_cal_store(struct device *dev, | ||
206 | struct device_attribute *attr, | ||
207 | const char *buf, size_t count); | ||
208 | |||
209 | static ssize_t rmi_fn_54_status_show(struct device *dev, | ||
210 | struct device_attribute *attr, char *buf); | ||
211 | |||
212 | #ifdef KERNEL_VERSION_ABOVE_2_6_32 | ||
213 | static ssize_t rmi_fn_54_data_read(struct file *data_file, struct kobject *kobj, | ||
214 | #else | ||
215 | static ssize_t rmi_fn_54_data_read(struct kobject *kobj, | ||
216 | #endif | ||
217 | struct bin_attribute *attributes, | ||
218 | char *buf, loff_t pos, size_t count); | ||
219 | |||
220 | static ssize_t rmi_fn_54_num_rx_electrodes_show(struct device *dev, | ||
221 | struct device_attribute *attr, char *buf); | ||
222 | |||
223 | static ssize_t rmi_fn_54_num_tx_electrodes_show(struct device *dev, | ||
224 | struct device_attribute *attr, char *buf); | ||
225 | |||
226 | static ssize_t rmi_fn_54_has_image16_show(struct device *dev, | ||
227 | struct device_attribute *attr, char *buf); | ||
228 | |||
229 | static ssize_t rmi_fn_54_has_image8_show(struct device *dev, | ||
230 | struct device_attribute *attr, char *buf); | ||
231 | |||
232 | static ssize_t rmi_fn_54_has_baseline_show(struct device *dev, | ||
233 | struct device_attribute *attr, char *buf); | ||
234 | |||
235 | static ssize_t rmi_fn_54_clock_rate_show(struct device *dev, | ||
236 | struct device_attribute *attr, char *buf); | ||
237 | |||
238 | |||
239 | static ssize_t rmi_fn_54_touch_controller_family_show(struct device *dev, | ||
240 | struct device_attribute *attr, char *buf); | ||
241 | |||
242 | |||
243 | static ssize_t rmi_fn_54_has_pixel_touch_threshold_adjustment_show( | ||
244 | struct device *dev, struct device_attribute *attr, char *buf); | ||
245 | |||
246 | static ssize_t rmi_fn_54_has_sensor_assignment_show(struct device *dev, | ||
247 | struct device_attribute *attr, char *buf); | ||
248 | |||
249 | static ssize_t rmi_fn_54_has_interference_metric_show(struct device *dev, | ||
250 | struct device_attribute *attr, char *buf); | ||
251 | |||
252 | static ssize_t rmi_fn_54_has_sense_frequency_control_show(struct device *dev, | ||
253 | struct device_attribute *attr, char *buf); | ||
254 | |||
255 | static ssize_t rmi_fn_54_has_firmware_noise_mitigation_show(struct device *dev, | ||
256 | struct device_attribute *attr, char *buf); | ||
257 | |||
258 | static ssize_t rmi_fn_54_has_two_byte_report_rate_show(struct device *dev, | ||
259 | struct device_attribute *attr, char *buf); | ||
260 | |||
261 | static ssize_t rmi_fn_54_has_one_byte_report_rate_show(struct device *dev, | ||
262 | struct device_attribute *attr, char *buf); | ||
263 | |||
264 | static ssize_t rmi_fn_54_has_relaxation_control_show(struct device *dev, | ||
265 | struct device_attribute *attr, char *buf); | ||
266 | |||
267 | static ssize_t rmi_fn_54_curve_compensation_mode_show(struct device *dev, | ||
268 | struct device_attribute *attr, char *buf); | ||
269 | |||
270 | static ssize_t rmi_fn_54_has_iir_filter_show(struct device *dev, | ||
271 | struct device_attribute *attr, char *buf); | ||
272 | |||
273 | static ssize_t rmi_fn_54_has_cmn_removal_show(struct device *dev, | ||
274 | struct device_attribute *attr, char *buf); | ||
275 | |||
276 | static ssize_t rmi_fn_54_has_cmn_maximum_show(struct device *dev, | ||
277 | struct device_attribute *attr, char *buf); | ||
278 | |||
279 | static ssize_t rmi_fn_54_has_pixel_threshold_hysteresis_show(struct device *dev, | ||
280 | struct device_attribute *attr, char *buf); | ||
281 | |||
282 | static ssize_t rmi_fn_54_has_edge_compensation_show(struct device *dev, | ||
283 | struct device_attribute *attr, char *buf); | ||
284 | |||
285 | static ssize_t rmi_fn_54_has_perf_frequency_noisecontrol_show( | ||
286 | struct device *dev, struct device_attribute *attr, char *buf); | ||
287 | |||
288 | static ssize_t rmi_fn_54_number_of_sensing_frequencies_show(struct device *dev, | ||
289 | struct device_attribute *attr, char *buf); | ||
290 | |||
291 | static ssize_t rmi_fn_54_no_auto_cal_show(struct device *dev, | ||
292 | struct device_attribute *attr, char *buf); | ||
293 | |||
294 | static ssize_t rmi_fn_54_no_auto_cal_store(struct device *dev, | ||
295 | struct device_attribute *attr, | ||
296 | const char *buf, size_t count); | ||
297 | |||
298 | static ssize_t rmi_fn_54_fifoindex_show(struct device *dev, | ||
299 | struct device_attribute *attr, char *buf); | ||
300 | |||
301 | static ssize_t rmi_fn_54_fifoindex_store(struct device *dev, | ||
302 | struct device_attribute *attr, | ||
303 | const char *buf, size_t count); | ||
304 | |||
305 | static struct device_attribute attrs[] = { | ||
306 | __ATTR(report_type, RMI_RW_ATTR, | ||
307 | rmi_fn_54_report_type_show, rmi_fn_54_report_type_store), | ||
308 | __ATTR(get_report, RMI_WO_ATTR, | ||
309 | rmi_show_error, rmi_fn_54_get_report_store), | ||
310 | __ATTR(force_cal, RMI_WO_ATTR, | ||
311 | rmi_show_error, rmi_fn_54_force_cal_store), | ||
312 | __ATTR(status, RMI_RO_ATTR, | ||
313 | rmi_fn_54_status_show, rmi_store_error), | ||
314 | __ATTR(num_rx_electrodes, RMI_RO_ATTR, | ||
315 | rmi_fn_54_num_rx_electrodes_show, rmi_store_error), | ||
316 | __ATTR(num_tx_electrodes, RMI_RO_ATTR, | ||
317 | rmi_fn_54_num_tx_electrodes_show, rmi_store_error), | ||
318 | __ATTR(has_image16, RMI_RO_ATTR, | ||
319 | rmi_fn_54_has_image16_show, rmi_store_error), | ||
320 | __ATTR(has_image8, RMI_RO_ATTR, | ||
321 | rmi_fn_54_has_image8_show, rmi_store_error), | ||
322 | __ATTR(has_baseline, RMI_RO_ATTR, | ||
323 | rmi_fn_54_has_baseline_show, rmi_store_error), | ||
324 | __ATTR(clock_rate, RMI_RO_ATTR, | ||
325 | rmi_fn_54_clock_rate_show, rmi_store_error), | ||
326 | __ATTR(touch_controller_family, RMI_RO_ATTR, | ||
327 | rmi_fn_54_touch_controller_family_show, rmi_store_error), | ||
328 | __ATTR(has_pixel_touch_threshold_adjustment, RMI_RO_ATTR, | ||
329 | rmi_fn_54_has_pixel_touch_threshold_adjustment_show | ||
330 | , rmi_store_error), | ||
331 | __ATTR(has_sensor_assignment, RMI_RO_ATTR, | ||
332 | rmi_fn_54_has_sensor_assignment_show, rmi_store_error), | ||
333 | __ATTR(has_interference_metric, RMI_RO_ATTR, | ||
334 | rmi_fn_54_has_interference_metric_show, rmi_store_error), | ||
335 | __ATTR(has_sense_frequency_control, RMI_RO_ATTR, | ||
336 | rmi_fn_54_has_sense_frequency_control_show, rmi_store_error), | ||
337 | __ATTR(has_firmware_noise_mitigation, RMI_RO_ATTR, | ||
338 | rmi_fn_54_has_firmware_noise_mitigation_show, rmi_store_error), | ||
339 | __ATTR(has_two_byte_report_rate, RMI_RO_ATTR, | ||
340 | rmi_fn_54_has_two_byte_report_rate_show, rmi_store_error), | ||
341 | __ATTR(has_one_byte_report_rate, RMI_RO_ATTR, | ||
342 | rmi_fn_54_has_one_byte_report_rate_show, rmi_store_error), | ||
343 | __ATTR(has_relaxation_control, RMI_RO_ATTR, | ||
344 | rmi_fn_54_has_relaxation_control_show, rmi_store_error), | ||
345 | __ATTR(curve_compensation_mode, RMI_RO_ATTR, | ||
346 | rmi_fn_54_curve_compensation_mode_show, rmi_store_error), | ||
347 | __ATTR(has_iir_filter, RMI_RO_ATTR, | ||
348 | rmi_fn_54_has_iir_filter_show, rmi_store_error), | ||
349 | __ATTR(has_cmn_removal, RMI_RO_ATTR, | ||
350 | rmi_fn_54_has_cmn_removal_show, rmi_store_error), | ||
351 | __ATTR(has_cmn_maximum, RMI_RO_ATTR, | ||
352 | rmi_fn_54_has_cmn_maximum_show, rmi_store_error), | ||
353 | __ATTR(has_pixel_threshold_hysteresis, RMI_RO_ATTR, | ||
354 | rmi_fn_54_has_pixel_threshold_hysteresis_show, rmi_store_error), | ||
355 | __ATTR(has_edge_compensation, RMI_RO_ATTR, | ||
356 | rmi_fn_54_has_edge_compensation_show, rmi_store_error), | ||
357 | __ATTR(has_perf_frequency_noisecontrol, RMI_RO_ATTR, | ||
358 | rmi_fn_54_has_perf_frequency_noisecontrol_show, rmi_store_error), | ||
359 | __ATTR(number_of_sensing_frequencies, RMI_RO_ATTR, | ||
360 | rmi_fn_54_number_of_sensing_frequencies_show, rmi_store_error), | ||
361 | __ATTR(no_auto_cal, RMI_RW_ATTR, | ||
362 | rmi_fn_54_no_auto_cal_show, rmi_fn_54_no_auto_cal_store), | ||
363 | __ATTR(fifoindex, RMI_RW_ATTR, | ||
364 | rmi_fn_54_fifoindex_show, rmi_fn_54_fifoindex_store), | ||
365 | }; | ||
366 | |||
367 | struct bin_attribute dev_rep_data = { | ||
368 | .attr = { | ||
369 | .name = "rep_data", | ||
370 | .mode = RMI_RO_ATTR}, | ||
371 | .size = 0, | ||
372 | .read = rmi_fn_54_data_read, | ||
373 | }; | ||
374 | |||
375 | #if F54_WATCHDOG | ||
376 | static enum hrtimer_restart clear_status(struct hrtimer *timer); | ||
377 | |||
378 | static void clear_status_worker(struct work_struct *work); | ||
379 | #endif | ||
380 | |||
381 | static int rmi_f54_init(struct rmi_function_container *fc) | ||
382 | { | ||
383 | struct rmi_fn_54_data *instance_data; | ||
384 | int retval = 0; | ||
385 | int attr_count = 0; | ||
386 | |||
387 | dev_info(&fc->dev, "Intializing F54."); | ||
388 | |||
389 | instance_data = kzalloc(sizeof(struct rmi_fn_54_data), GFP_KERNEL); | ||
390 | if (!instance_data) { | ||
391 | dev_err(&fc->dev, "Failed to allocate rmi_fn_54_data.\n"); | ||
392 | retval = -ENOMEM; | ||
393 | goto error_exit; | ||
394 | } | ||
395 | fc->data = instance_data; | ||
396 | instance_data->fc = fc; | ||
397 | |||
398 | #if F54_WATCHDOG | ||
399 | /* Set up watchdog timer to catch unanswered get_report commands */ | ||
400 | hrtimer_init(&instance_data->watchdog, CLOCK_MONOTONIC, | ||
401 | HRTIMER_MODE_REL); | ||
402 | instance_data->watchdog.function = clear_status; | ||
403 | |||
404 | /* work function to do unlocking */ | ||
405 | INIT_WORK(&instance_data->work, clear_status_worker); | ||
406 | #endif | ||
407 | |||
408 | /* Read F54 Query Data */ | ||
409 | retval = rmi_read_block(fc->rmi_dev, fc->fd.query_base_addr, | ||
410 | (u8 *)&instance_data->query, sizeof(instance_data->query)); | ||
411 | if (retval < 0) { | ||
412 | dev_err(&fc->dev, "Could not read query registers" | ||
413 | " from 0x%04x\n", fc->fd.query_base_addr); | ||
414 | goto error_exit; | ||
415 | } | ||
416 | |||
417 | __mutex_init(&instance_data->data_mutex, "data_mutex", | ||
418 | &instance_data->data_key); | ||
419 | |||
420 | __mutex_init(&instance_data->status_mutex, "status_mutex", | ||
421 | &instance_data->status_key); | ||
422 | |||
423 | dev_dbg(&fc->dev, "Creating sysfs files."); | ||
424 | /* Set up sysfs device attributes. */ | ||
425 | for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { | ||
426 | if (sysfs_create_file | ||
427 | (&fc->dev.kobj, &attrs[attr_count].attr) < 0) { | ||
428 | dev_err(&fc->dev, "Failed to create sysfs file for %s.", | ||
429 | attrs[attr_count].attr.name); | ||
430 | retval = -ENODEV; | ||
431 | goto error_exit; | ||
432 | } | ||
433 | } | ||
434 | /* Binary sysfs file to report the data back */ | ||
435 | retval = sysfs_create_bin_file(&fc->dev.kobj, &dev_rep_data); | ||
436 | if (retval < 0) { | ||
437 | dev_err(&fc->dev, "Failed to create sysfs file for F54 data " | ||
438 | "(error = %d).\n", retval); | ||
439 | retval = -ENODEV; | ||
440 | goto error_exit; | ||
441 | } | ||
442 | instance_data->status = IDLE; | ||
443 | return retval; | ||
444 | |||
445 | error_exit: | ||
446 | dev_err(&fc->dev, "An error occured in F54 init!\n"); | ||
447 | for (attr_count--; attr_count >= 0; attr_count--) | ||
448 | sysfs_remove_file(&fc->dev.kobj, | ||
449 | &attrs[attr_count].attr); | ||
450 | kfree(instance_data); | ||
451 | return retval; | ||
452 | } | ||
453 | |||
454 | static void set_report_size(struct rmi_fn_54_data *data) | ||
455 | { | ||
456 | u8 rx = data->query.number_of_receiver_electrodes; | ||
457 | u8 tx = data->query.number_of_transmitter_electrodes; | ||
458 | switch (data->report_type) { | ||
459 | case F54_8BIT_IMAGE: | ||
460 | data->report_size = rx * tx; | ||
461 | break; | ||
462 | case F54_16BIT_IMAGE: | ||
463 | case F54_RAW_16BIT_IMAGE: | ||
464 | case F54_TRUE_BASELINE: | ||
465 | case F54_FULL_RAW_CAP: | ||
466 | case F54_FULL_RAW_CAP_RX_COUPLING_COMP: | ||
467 | data->report_size = 2 * rx * tx; | ||
468 | break; | ||
469 | case F54_HIGH_RESISTANCE: | ||
470 | data->report_size = RMI_54_HIGH_RESISTANCE_SIZE; | ||
471 | break; | ||
472 | case F54_FULL_RAW_CAP_MIN_MAX: | ||
473 | data->report_size = RMI_54_FULL_RAW_CAP_MIN_MAX_SIZE; | ||
474 | break; | ||
475 | case F54_TX_TO_TX_SHORT: | ||
476 | case F54_TX_OPEN: | ||
477 | case F54_TX_TO_GROUND: | ||
478 | data->report_size = (tx + 7) / 8; | ||
479 | break; | ||
480 | case F54_RX_TO_RX1: | ||
481 | case F54_RX_OPENS1: | ||
482 | if (rx < tx) | ||
483 | data->report_size = 2 * rx * rx; | ||
484 | else | ||
485 | data->report_size = 2 * rx * tx; | ||
486 | break; | ||
487 | case F54_RX_TO_RX2: | ||
488 | case F54_RX_OPENS2: | ||
489 | if (rx <= tx) | ||
490 | data->report_size = 0; | ||
491 | else | ||
492 | data->report_size = 2 * rx * (rx - tx); | ||
493 | break; | ||
494 | default: | ||
495 | data->report_size = 0; | ||
496 | } | ||
497 | } | ||
498 | |||
499 | int rmi_f54_attention(struct rmi_function_container *fc, u8 *irq_bits) | ||
500 | { | ||
501 | struct rmi_driver *driver = fc->rmi_dev->driver; | ||
502 | char fifo[2]; | ||
503 | struct rmi_fn_54_data *data = fc->data; | ||
504 | int error = 0; | ||
505 | |||
506 | set_report_size(data); | ||
507 | if (data->report_size == 0) { | ||
508 | dev_err(&fc->dev, "Invalid report type set in %s. " | ||
509 | "This should never happen.\n", __func__); | ||
510 | error = -EINVAL; | ||
511 | goto error_exit; | ||
512 | } | ||
513 | /* | ||
514 | * We need to ensure the buffer is big enough. A Buffer size of 0 means | ||
515 | * that the buffer has not been allocated. | ||
516 | */ | ||
517 | if (data->bufsize < data->report_size) { | ||
518 | mutex_lock(&data->data_mutex); | ||
519 | if (data->bufsize > 0) | ||
520 | kfree(data->report_data); | ||
521 | data->report_data = kzalloc(data->report_size, GFP_KERNEL); | ||
522 | if (!data->report_data) { | ||
523 | dev_err(&fc->dev, "Failed to allocate report_data.\n"); | ||
524 | error = -ENOMEM; | ||
525 | data->bufsize = 0; | ||
526 | mutex_unlock(&data->data_mutex); | ||
527 | goto error_exit; | ||
528 | } | ||
529 | data->bufsize = data->report_size; | ||
530 | mutex_unlock(&data->data_mutex); | ||
531 | } | ||
532 | dev_vdbg(&fc->dev, "F54 Interrupt handler is running.\nSize: %d\n", | ||
533 | data->report_size); | ||
534 | /* | ||
535 | * Read report type, fifo high, and fifo low | ||
536 | * error = rmi_read_multiple(rmifninfo->sensor, | ||
537 | * rmifninfo->function_descriptor.data_base_addr , | ||
538 | * repfifo,3); | ||
539 | */ | ||
540 | /* Write 0 to fifohi and fifolo. */ | ||
541 | fifo[0] = 0; | ||
542 | fifo[1] = 0; | ||
543 | error = rmi_write_block(fc->rmi_dev, fc->fd.data_base_addr | ||
544 | + RMI_F54_FIFO_OFFSET, fifo, sizeof(fifo)); | ||
545 | if (error < 0) | ||
546 | dev_err(&fc->dev, "Failed to write fifo to zero!\n"); | ||
547 | else | ||
548 | error = rmi_read_block(fc->rmi_dev, | ||
549 | fc->fd.data_base_addr + RMI_F54_REPORT_DATA_OFFSET, | ||
550 | data->report_data, data->report_size); | ||
551 | if (error < 0) | ||
552 | dev_err(&fc->dev, "F54 data read failed. Code: %d.\n", error); | ||
553 | else if (error != data->report_size) { | ||
554 | error = -EINVAL; | ||
555 | goto error_exit; | ||
556 | } | ||
557 | #if RAW_HEX | ||
558 | int l; | ||
559 | /* Debugging: Print out the file in hex. */ | ||
560 | pr_info("Report data (raw hex):\n"); | ||
561 | for (l = 0; l < data->report_size; l += 2) { | ||
562 | pr_info("%03d: 0x%02x%02x\n", l/2, | ||
563 | data->report_data[l+1], data->report_data[l]); | ||
564 | } | ||
565 | #endif | ||
566 | #if HUMAN_READABLE | ||
567 | /* Debugging: Print out file in human understandable image */ | ||
568 | switch (data->report_type) { | ||
569 | case F54_16BIT_IMAGE: | ||
570 | case F54_RAW_16BIT_IMAGE: | ||
571 | case F54_TRUE_BASELINE: | ||
572 | case F54_FULL_RAW_CAP: | ||
573 | case F54_FULL_RAW_CAP_RX_COUPLING_COMP: | ||
574 | pr_info("Report data (Image):\n"); | ||
575 | int i, j, k; | ||
576 | char c[2]; | ||
577 | short s; | ||
578 | k = 0; | ||
579 | for (i = 0; i < data->query.number_of_transmitter_electrodes; | ||
580 | i++) { | ||
581 | for (j = 0; j < | ||
582 | data->query.number_of_receiver_electrodes; j++) { | ||
583 | c[0] = data->report_data[k]; | ||
584 | c[1] = data->report_data[k+1]; | ||
585 | memcpy(&s, &c, 2); | ||
586 | if (s < -64) | ||
587 | printk("."); | ||
588 | else if (s < 0) | ||
589 | printk("-"); | ||
590 | else if (s > 64) | ||
591 | printk("*"); | ||
592 | else if (s > 0) | ||
593 | printk("+"); | ||
594 | else | ||
595 | printk("0"); | ||
596 | k += 2; | ||
597 | } | ||
598 | pr_info("\n"); | ||
599 | } | ||
600 | pr_info("EOF\n"); | ||
601 | break; | ||
602 | default: | ||
603 | pr_info("Report type %d debug image not supported", | ||
604 | data->report_type); | ||
605 | } | ||
606 | #endif | ||
607 | error = IDLE; | ||
608 | error_exit: | ||
609 | mutex_lock(&data->status_mutex); | ||
610 | /* Turn back on other interupts, if it | ||
611 | * appears that we turned them off. */ | ||
612 | if (driver->restore_irq_mask) { | ||
613 | dev_dbg(&fc->dev, "Restoring interupts!\n"); | ||
614 | driver->restore_irq_mask(fc->rmi_dev); | ||
615 | } else { | ||
616 | dev_err(&fc->dev, "No way to restore interrupts!\n"); | ||
617 | } | ||
618 | data->status = error; | ||
619 | mutex_unlock(&data->status_mutex); | ||
620 | return data->status; | ||
621 | } | ||
622 | |||
623 | |||
624 | #if F54_WATCHDOG | ||
625 | static void clear_status_worker(struct work_struct *work) | ||
626 | { | ||
627 | struct rmi_fn_54_data *data = container_of(work, | ||
628 | struct rmi_fn_54_data, work); | ||
629 | struct rmi_function_container *fc = data->fc; | ||
630 | struct rmi_driver *driver = fc->rmi_dev->driver; | ||
631 | char command; | ||
632 | int result; | ||
633 | |||
634 | mutex_lock(&data->status_mutex); | ||
635 | if (data->status == BUSY) { | ||
636 | pr_info("F54 Timout Occured: Determining status.\n"); | ||
637 | result = rmi_read_block(fc->rmi_dev, fc->fd.command_base_addr, | ||
638 | &command, 1); | ||
639 | if (result < 0) { | ||
640 | dev_err(&fc->dev, "Could not read get_report register " | ||
641 | "from 0x%04x\n", fc->fd.command_base_addr); | ||
642 | data->status = -ETIMEDOUT; | ||
643 | } else { | ||
644 | if (command & GET_REPORT) { | ||
645 | dev_warn(&fc->dev, "Report type unsupported!"); | ||
646 | data->status = -EINVAL; | ||
647 | } else { | ||
648 | data->status = -ETIMEDOUT; | ||
649 | } | ||
650 | } | ||
651 | if (driver->restore_irq_mask) { | ||
652 | dev_dbg(&fc->dev, "Restoring interupts!\n"); | ||
653 | driver->restore_irq_mask(fc->rmi_dev); | ||
654 | } else { | ||
655 | dev_err(&fc->dev, "No way to restore interrupts!\n"); | ||
656 | } | ||
657 | } | ||
658 | mutex_unlock(&data->status_mutex); | ||
659 | } | ||
660 | |||
661 | static enum hrtimer_restart clear_status(struct hrtimer *timer) | ||
662 | { | ||
663 | struct rmi_fn_54_data *data = container_of(timer, | ||
664 | struct rmi_fn_54_data, watchdog); | ||
665 | schedule_work(&(data->work)); | ||
666 | return HRTIMER_NORESTART; | ||
667 | } | ||
668 | #endif | ||
669 | |||
670 | /* Check if report_type is valid */ | ||
671 | static bool is_report_type_valid(enum f54_report_types reptype) | ||
672 | { | ||
673 | /* Basic checks on report_type to ensure we write a valid type | ||
674 | * to the sensor. | ||
675 | * TODO: Check Query3 to see if some specific reports are | ||
676 | * available. This is currently listed as a reserved register. | ||
677 | */ | ||
678 | switch (reptype) { | ||
679 | case F54_8BIT_IMAGE: | ||
680 | case F54_16BIT_IMAGE: | ||
681 | case F54_RAW_16BIT_IMAGE: | ||
682 | case F54_HIGH_RESISTANCE: | ||
683 | case F54_TX_TO_TX_SHORT: | ||
684 | case F54_RX_TO_RX1: | ||
685 | case F54_TRUE_BASELINE: | ||
686 | case F54_FULL_RAW_CAP_MIN_MAX: | ||
687 | case F54_RX_OPENS1: | ||
688 | case F54_TX_OPEN: | ||
689 | case F54_TX_TO_GROUND: | ||
690 | case F54_RX_TO_RX2: | ||
691 | case F54_RX_OPENS2: | ||
692 | case F54_FULL_RAW_CAP: | ||
693 | case F54_FULL_RAW_CAP_RX_COUPLING_COMP: | ||
694 | return true; | ||
695 | break; | ||
696 | default: | ||
697 | return false; | ||
698 | } | ||
699 | } | ||
700 | |||
701 | /* SYSFS file show/store functions */ | ||
702 | static ssize_t rmi_fn_54_report_type_show(struct device *dev, | ||
703 | struct device_attribute *attr, char *buf) { | ||
704 | struct rmi_function_container *fc; | ||
705 | struct rmi_fn_54_data *instance_data; | ||
706 | |||
707 | fc = to_rmi_function_container(dev); | ||
708 | instance_data = fc->data; | ||
709 | |||
710 | return snprintf(buf, PAGE_SIZE, "%u\n", instance_data->report_type); | ||
711 | } | ||
712 | |||
713 | static ssize_t rmi_fn_54_report_type_store(struct device *dev, | ||
714 | struct device_attribute *attr, | ||
715 | const char *buf, size_t count) { | ||
716 | int result; | ||
717 | unsigned long val; | ||
718 | unsigned char data; | ||
719 | struct rmi_function_container *fc; | ||
720 | struct rmi_fn_54_data *instance_data; | ||
721 | fc = to_rmi_function_container(dev); | ||
722 | instance_data = fc->data; | ||
723 | |||
724 | /* need to convert the string data to an actual value */ | ||
725 | result = strict_strtoul(buf, 10, &val); | ||
726 | if (result) | ||
727 | return result; | ||
728 | if (!is_report_type_valid(val)) { | ||
729 | dev_err(dev, "%s : Report type %d is invalid.\n", | ||
730 | __func__, (u8) val); | ||
731 | return -EINVAL; | ||
732 | } | ||
733 | mutex_lock(&instance_data->status_mutex); | ||
734 | if (instance_data->status != BUSY) { | ||
735 | instance_data->report_type = (enum f54_report_types)val; | ||
736 | data = (char)val; | ||
737 | /* Write the Report Type back to the first Block | ||
738 | * Data registers (F54_AD_Data0). */ | ||
739 | result = | ||
740 | rmi_write_block(fc->rmi_dev, fc->fd.data_base_addr, | ||
741 | &data, 1); | ||
742 | mutex_unlock(&instance_data->status_mutex); | ||
743 | if (result < 0) { | ||
744 | dev_err(dev, "%s : Could not write report type to" | ||
745 | " 0x%x\n", __func__, fc->fd.data_base_addr); | ||
746 | return result; | ||
747 | } | ||
748 | return count; | ||
749 | } else { | ||
750 | dev_err(dev, "%s : Report type cannot be changed in the middle" | ||
751 | " of command.\n", __func__); | ||
752 | mutex_unlock(&instance_data->status_mutex); | ||
753 | return -EINVAL; | ||
754 | } | ||
755 | } | ||
756 | |||
757 | static ssize_t rmi_fn_54_get_report_store(struct device *dev, | ||
758 | struct device_attribute *attr, | ||
759 | const char *buf, size_t count) { | ||
760 | unsigned long val; | ||
761 | int error, result; | ||
762 | struct rmi_function_container *fc; | ||
763 | struct rmi_fn_54_data *instance_data; | ||
764 | struct rmi_driver *driver; | ||
765 | u8 command; | ||
766 | fc = to_rmi_function_container(dev); | ||
767 | instance_data = fc->data; | ||
768 | driver = fc->rmi_dev->driver; | ||
769 | |||
770 | /* need to convert the string data to an actual value */ | ||
771 | error = strict_strtoul(buf, 10, &val); | ||
772 | if (error) | ||
773 | return error; | ||
774 | /* Do nothing if not set to 1. This prevents accidental commands. */ | ||
775 | if (val != 1) | ||
776 | return count; | ||
777 | command = (unsigned char)GET_REPORT; | ||
778 | /* Basic checks on report_type to ensure we write a valid type | ||
779 | * to the sensor. | ||
780 | * TODO: Check Query3 to see if some specific reports are | ||
781 | * available. This is currently listed as a reserved register. | ||
782 | */ | ||
783 | if (!is_report_type_valid(instance_data->report_type)) { | ||
784 | dev_err(dev, "%s : Report type %d is invalid.\n", | ||
785 | __func__, instance_data->report_type); | ||
786 | return -EINVAL; | ||
787 | } | ||
788 | mutex_lock(&instance_data->status_mutex); | ||
789 | if (instance_data->status != IDLE) { | ||
790 | if (instance_data->status != BUSY) { | ||
791 | dev_err(dev, "F54 status is in an abnormal state: 0x%x", | ||
792 | instance_data->status); | ||
793 | } | ||
794 | mutex_unlock(&instance_data->status_mutex); | ||
795 | return count; | ||
796 | } | ||
797 | /* Store interrupts */ | ||
798 | /* Do not exit if we fail to turn off interupts. We are likely | ||
799 | * to still get useful data. The report data can, however, be | ||
800 | * corrupted, and there may be unexpected behavior. | ||
801 | */ | ||
802 | dev_dbg(dev, "Storing and overriding interupts\n"); | ||
803 | if (driver->store_irq_mask) | ||
804 | driver->store_irq_mask(fc->rmi_dev, | ||
805 | fc->irq_mask); | ||
806 | else | ||
807 | dev_err(dev, "No way to store interupts!\n"); | ||
808 | instance_data->status = BUSY; | ||
809 | |||
810 | /* small delay to avoid race condition in firmare. This value is a bit | ||
811 | * higher than absolutely necessary. Should be removed once issue is | ||
812 | * resolved in firmware. */ | ||
813 | |||
814 | mdelay(2); | ||
815 | |||
816 | /* Write the command to the command register */ | ||
817 | result = rmi_write_block(fc->rmi_dev, fc->fd.command_base_addr, | ||
818 | &command, 1); | ||
819 | mutex_unlock(&instance_data->status_mutex); | ||
820 | if (result < 0) { | ||
821 | dev_err(dev, "%s : Could not write command to 0x%x\n", | ||
822 | __func__, fc->fd.command_base_addr); | ||
823 | return result; | ||
824 | } | ||
825 | #if F54_WATCHDOG | ||
826 | /* start watchdog timer */ | ||
827 | hrtimer_start(&instance_data->watchdog, ktime_set(1, 0), | ||
828 | HRTIMER_MODE_REL); | ||
829 | #endif | ||
830 | return count; | ||
831 | } | ||
832 | |||
833 | static ssize_t rmi_fn_54_force_cal_store(struct device *dev, | ||
834 | struct device_attribute *attr, | ||
835 | const char *buf, size_t count) { | ||
836 | unsigned long val; | ||
837 | int error, result; | ||
838 | struct rmi_function_container *fc; | ||
839 | struct rmi_fn_54_data *instance_data; | ||
840 | struct rmi_driver *driver; | ||
841 | u8 command; | ||
842 | |||
843 | fc = to_rmi_function_container(dev); | ||
844 | instance_data = fc->data; | ||
845 | driver = fc->rmi_dev->driver; | ||
846 | |||
847 | /* need to convert the string data to an actual value */ | ||
848 | error = strict_strtoul(buf, 10, &val); | ||
849 | if (error) | ||
850 | return error; | ||
851 | /* Do nothing if not set to 1. This prevents accidental commands. */ | ||
852 | if (val != 1) | ||
853 | return count; | ||
854 | |||
855 | command = (unsigned char)FORCE_CAL; | ||
856 | |||
857 | if (instance_data->status == BUSY) | ||
858 | return -EBUSY; | ||
859 | /* Write the command to the command register */ | ||
860 | result = rmi_write_block(fc->rmi_dev, fc->fd.command_base_addr, | ||
861 | &command, 1); | ||
862 | if (result < 0) { | ||
863 | dev_err(dev, "%s : Could not write command to 0x%x\n", | ||
864 | __func__, fc->fd.command_base_addr); | ||
865 | return result; | ||
866 | } | ||
867 | return count; | ||
868 | } | ||
869 | |||
870 | static ssize_t rmi_fn_54_status_show(struct device *dev, | ||
871 | struct device_attribute *attr, char *buf) { | ||
872 | struct rmi_function_container *fc; | ||
873 | struct rmi_fn_54_data *instance_data; | ||
874 | |||
875 | fc = to_rmi_function_container(dev); | ||
876 | instance_data = fc->data; | ||
877 | |||
878 | return snprintf(buf, PAGE_SIZE, "%d\n", instance_data->status); | ||
879 | } | ||
880 | |||
881 | static ssize_t rmi_fn_54_num_rx_electrodes_show(struct device *dev, | ||
882 | struct device_attribute *attr, char *buf) { | ||
883 | struct rmi_function_container *fc; | ||
884 | struct rmi_fn_54_data *data; | ||
885 | |||
886 | fc = to_rmi_function_container(dev); | ||
887 | data = fc->data; | ||
888 | |||
889 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
890 | data->query.number_of_receiver_electrodes); | ||
891 | } | ||
892 | |||
893 | static ssize_t rmi_fn_54_num_tx_electrodes_show(struct device *dev, | ||
894 | struct device_attribute *attr, char *buf) { | ||
895 | struct rmi_function_container *fc; | ||
896 | struct rmi_fn_54_data *data; | ||
897 | |||
898 | fc = to_rmi_function_container(dev); | ||
899 | data = fc->data; | ||
900 | |||
901 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
902 | data->query.number_of_transmitter_electrodes); | ||
903 | } | ||
904 | |||
905 | static ssize_t rmi_fn_54_has_image16_show(struct device *dev, | ||
906 | struct device_attribute *attr, char *buf) { | ||
907 | struct rmi_function_container *fc; | ||
908 | struct rmi_fn_54_data *data; | ||
909 | |||
910 | fc = to_rmi_function_container(dev); | ||
911 | data = fc->data; | ||
912 | |||
913 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
914 | data->query.has_image16); | ||
915 | } | ||
916 | |||
917 | static ssize_t rmi_fn_54_has_image8_show(struct device *dev, | ||
918 | struct device_attribute *attr, char *buf) { | ||
919 | struct rmi_function_container *fc; | ||
920 | struct rmi_fn_54_data *data; | ||
921 | |||
922 | fc = to_rmi_function_container(dev); | ||
923 | data = fc->data; | ||
924 | |||
925 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
926 | data->query.has_image8); | ||
927 | } | ||
928 | |||
929 | static ssize_t rmi_fn_54_has_baseline_show(struct device *dev, | ||
930 | struct device_attribute *attr, char *buf) { | ||
931 | struct rmi_function_container *fc; | ||
932 | struct rmi_fn_54_data *data; | ||
933 | |||
934 | fc = to_rmi_function_container(dev); | ||
935 | data = fc->data; | ||
936 | |||
937 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
938 | data->query.has_baseline); | ||
939 | } | ||
940 | |||
941 | static ssize_t rmi_fn_54_clock_rate_show(struct device *dev, | ||
942 | struct device_attribute *attr, char *buf) { | ||
943 | struct rmi_function_container *fc; | ||
944 | struct rmi_fn_54_data *data; | ||
945 | |||
946 | fc = to_rmi_function_container(dev); | ||
947 | data = fc->data; | ||
948 | |||
949 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
950 | data->query.clock_rate); | ||
951 | } | ||
952 | |||
953 | |||
954 | static ssize_t rmi_fn_54_touch_controller_family_show(struct device *dev, | ||
955 | struct device_attribute *attr, char *buf) { | ||
956 | struct rmi_function_container *fc; | ||
957 | struct rmi_fn_54_data *data; | ||
958 | |||
959 | fc = to_rmi_function_container(dev); | ||
960 | data = fc->data; | ||
961 | |||
962 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
963 | data->query.touch_controller_family); | ||
964 | } | ||
965 | |||
966 | |||
967 | static ssize_t rmi_fn_54_has_pixel_touch_threshold_adjustment_show( | ||
968 | struct device *dev, struct device_attribute *attr, char *buf) { | ||
969 | struct rmi_function_container *fc; | ||
970 | struct rmi_fn_54_data *data; | ||
971 | |||
972 | fc = to_rmi_function_container(dev); | ||
973 | data = fc->data; | ||
974 | |||
975 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
976 | data->query.has_pixel_touch_threshold_adjustment); | ||
977 | } | ||
978 | |||
979 | static ssize_t rmi_fn_54_has_sensor_assignment_show(struct device *dev, | ||
980 | struct device_attribute *attr, char *buf) { | ||
981 | struct rmi_function_container *fc; | ||
982 | struct rmi_fn_54_data *data; | ||
983 | |||
984 | fc = to_rmi_function_container(dev); | ||
985 | data = fc->data; | ||
986 | |||
987 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
988 | data->query.has_sensor_assignment); | ||
989 | } | ||
990 | |||
991 | static ssize_t rmi_fn_54_has_interference_metric_show(struct device *dev, | ||
992 | struct device_attribute *attr, char *buf) { | ||
993 | struct rmi_function_container *fc; | ||
994 | struct rmi_fn_54_data *data; | ||
995 | |||
996 | fc = to_rmi_function_container(dev); | ||
997 | data = fc->data; | ||
998 | |||
999 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1000 | data->query.has_interference_metric); | ||
1001 | } | ||
1002 | |||
1003 | static ssize_t rmi_fn_54_has_sense_frequency_control_show(struct device *dev, | ||
1004 | struct device_attribute *attr, char *buf) { | ||
1005 | struct rmi_function_container *fc; | ||
1006 | struct rmi_fn_54_data *data; | ||
1007 | |||
1008 | fc = to_rmi_function_container(dev); | ||
1009 | data = fc->data; | ||
1010 | |||
1011 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1012 | data->query.has_sense_frequency_control); | ||
1013 | } | ||
1014 | |||
1015 | static ssize_t rmi_fn_54_has_firmware_noise_mitigation_show(struct device *dev, | ||
1016 | struct device_attribute *attr, char *buf) { | ||
1017 | struct rmi_function_container *fc; | ||
1018 | struct rmi_fn_54_data *data; | ||
1019 | |||
1020 | fc = to_rmi_function_container(dev); | ||
1021 | data = fc->data; | ||
1022 | |||
1023 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1024 | data->query.has_firmware_noise_mitigation); | ||
1025 | } | ||
1026 | |||
1027 | static ssize_t rmi_fn_54_has_two_byte_report_rate_show(struct device *dev, | ||
1028 | struct device_attribute *attr, char *buf) { | ||
1029 | struct rmi_function_container *fc; | ||
1030 | struct rmi_fn_54_data *data; | ||
1031 | |||
1032 | fc = to_rmi_function_container(dev); | ||
1033 | data = fc->data; | ||
1034 | |||
1035 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1036 | data->query.has_two_byte_report_rate); | ||
1037 | } | ||
1038 | |||
1039 | static ssize_t rmi_fn_54_has_one_byte_report_rate_show(struct device *dev, | ||
1040 | struct device_attribute *attr, char *buf) { | ||
1041 | struct rmi_function_container *fc; | ||
1042 | struct rmi_fn_54_data *data; | ||
1043 | |||
1044 | fc = to_rmi_function_container(dev); | ||
1045 | data = fc->data; | ||
1046 | |||
1047 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1048 | data->query.has_one_byte_report_rate); | ||
1049 | } | ||
1050 | |||
1051 | static ssize_t rmi_fn_54_has_relaxation_control_show(struct device *dev, | ||
1052 | struct device_attribute *attr, char *buf) { | ||
1053 | struct rmi_function_container *fc; | ||
1054 | struct rmi_fn_54_data *data; | ||
1055 | |||
1056 | fc = to_rmi_function_container(dev); | ||
1057 | data = fc->data; | ||
1058 | |||
1059 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1060 | data->query.has_relaxation_control); | ||
1061 | } | ||
1062 | |||
1063 | static ssize_t rmi_fn_54_curve_compensation_mode_show(struct device *dev, | ||
1064 | struct device_attribute *attr, char *buf) { | ||
1065 | struct rmi_function_container *fc; | ||
1066 | struct rmi_fn_54_data *data; | ||
1067 | |||
1068 | fc = to_rmi_function_container(dev); | ||
1069 | data = fc->data; | ||
1070 | |||
1071 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1072 | data->query.curve_compensation_mode); | ||
1073 | } | ||
1074 | |||
1075 | static ssize_t rmi_fn_54_has_iir_filter_show(struct device *dev, | ||
1076 | struct device_attribute *attr, char *buf) { | ||
1077 | struct rmi_function_container *fc; | ||
1078 | struct rmi_fn_54_data *data; | ||
1079 | |||
1080 | fc = to_rmi_function_container(dev); | ||
1081 | data = fc->data; | ||
1082 | |||
1083 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1084 | data->query.has_iir_filter); | ||
1085 | } | ||
1086 | |||
1087 | static ssize_t rmi_fn_54_has_cmn_removal_show(struct device *dev, | ||
1088 | struct device_attribute *attr, char *buf) { | ||
1089 | struct rmi_function_container *fc; | ||
1090 | struct rmi_fn_54_data *data; | ||
1091 | |||
1092 | fc = to_rmi_function_container(dev); | ||
1093 | data = fc->data; | ||
1094 | |||
1095 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1096 | data->query.has_cmn_removal); | ||
1097 | } | ||
1098 | |||
1099 | static ssize_t rmi_fn_54_has_cmn_maximum_show(struct device *dev, | ||
1100 | struct device_attribute *attr, char *buf) { | ||
1101 | struct rmi_function_container *fc; | ||
1102 | struct rmi_fn_54_data *data; | ||
1103 | |||
1104 | fc = to_rmi_function_container(dev); | ||
1105 | data = fc->data; | ||
1106 | |||
1107 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1108 | data->query.has_cmn_maximum); | ||
1109 | } | ||
1110 | |||
1111 | static ssize_t rmi_fn_54_has_pixel_threshold_hysteresis_show(struct device *dev, | ||
1112 | struct device_attribute *attr, char *buf) { | ||
1113 | struct rmi_function_container *fc; | ||
1114 | struct rmi_fn_54_data *data; | ||
1115 | |||
1116 | fc = to_rmi_function_container(dev); | ||
1117 | data = fc->data; | ||
1118 | |||
1119 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1120 | data->query.has_pixel_threshold_hysteresis); | ||
1121 | } | ||
1122 | |||
1123 | static ssize_t rmi_fn_54_has_edge_compensation_show(struct device *dev, | ||
1124 | struct device_attribute *attr, char *buf) { | ||
1125 | struct rmi_function_container *fc; | ||
1126 | struct rmi_fn_54_data *data; | ||
1127 | |||
1128 | fc = to_rmi_function_container(dev); | ||
1129 | data = fc->data; | ||
1130 | |||
1131 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1132 | data->query.has_edge_compensation); | ||
1133 | } | ||
1134 | |||
1135 | static ssize_t rmi_fn_54_has_perf_frequency_noisecontrol_show( | ||
1136 | struct device *dev, struct device_attribute *attr, char *buf) { | ||
1137 | struct rmi_function_container *fc; | ||
1138 | struct rmi_fn_54_data *data; | ||
1139 | |||
1140 | fc = to_rmi_function_container(dev); | ||
1141 | data = fc->data; | ||
1142 | |||
1143 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1144 | data->query.has_perf_frequency_noisecontrol); | ||
1145 | } | ||
1146 | |||
1147 | static ssize_t rmi_fn_54_number_of_sensing_frequencies_show(struct device *dev, | ||
1148 | struct device_attribute *attr, char *buf) { | ||
1149 | struct rmi_function_container *fc; | ||
1150 | struct rmi_fn_54_data *data; | ||
1151 | |||
1152 | fc = to_rmi_function_container(dev); | ||
1153 | data = fc->data; | ||
1154 | |||
1155 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1156 | data->query.number_of_sensing_frequencies); | ||
1157 | } | ||
1158 | |||
1159 | |||
1160 | static ssize_t rmi_fn_54_no_auto_cal_show(struct device *dev, | ||
1161 | struct device_attribute *attr, char *buf) { | ||
1162 | struct rmi_function_container *fc; | ||
1163 | struct rmi_fn_54_data *instance_data; | ||
1164 | |||
1165 | fc = to_rmi_function_container(dev); | ||
1166 | instance_data = fc->data; | ||
1167 | |||
1168 | return snprintf(buf, PAGE_SIZE, "%u\n", | ||
1169 | instance_data->no_auto_cal ? 1 : 0); | ||
1170 | } | ||
1171 | |||
1172 | static ssize_t rmi_fn_54_no_auto_cal_store(struct device *dev, | ||
1173 | struct device_attribute *attr, | ||
1174 | const char *buf, size_t count) { | ||
1175 | int result; | ||
1176 | unsigned long val; | ||
1177 | unsigned char data; | ||
1178 | struct rmi_function_container *fc; | ||
1179 | struct rmi_fn_54_data *instance_data; | ||
1180 | |||
1181 | fc = to_rmi_function_container(dev); | ||
1182 | instance_data = fc->data; | ||
1183 | |||
1184 | /* need to convert the string data to an actual value */ | ||
1185 | result = strict_strtoul(buf, 10, &val); | ||
1186 | |||
1187 | /* if an error occured, return it */ | ||
1188 | if (result) | ||
1189 | return result; | ||
1190 | /* Do nothing if not 0 or 1. This prevents accidental commands. */ | ||
1191 | if (val > 1) | ||
1192 | return count; | ||
1193 | /* Read current control values */ | ||
1194 | result = | ||
1195 | rmi_read_block(fc->rmi_dev, fc->fd.control_base_addr, &data, 1); | ||
1196 | |||
1197 | /* if the current control registers are already set as we want them, do | ||
1198 | * nothing to them */ | ||
1199 | if ((data & 1) == val) | ||
1200 | return count; | ||
1201 | /* Write the control back to the control register (F54_AD_Ctrl0) | ||
1202 | * Ignores everything but bit 0 */ | ||
1203 | data = (data & ~1) | (val & 0x01); /* bit mask for lowest bit */ | ||
1204 | result = | ||
1205 | rmi_write_block(fc->rmi_dev, fc->fd.control_base_addr, &data, 1); | ||
1206 | if (result < 0) { | ||
1207 | dev_err(dev, "%s : Could not write control to 0x%x\n", | ||
1208 | __func__, fc->fd.control_base_addr); | ||
1209 | return result; | ||
1210 | } | ||
1211 | /* update our internal representation iff the write succeeds */ | ||
1212 | instance_data->no_auto_cal = (val == 1); | ||
1213 | return count; | ||
1214 | } | ||
1215 | |||
1216 | static ssize_t rmi_fn_54_fifoindex_show(struct device *dev, | ||
1217 | struct device_attribute *attr, char *buf) { | ||
1218 | struct rmi_function_container *fc; | ||
1219 | struct rmi_fn_54_data *instance_data; | ||
1220 | struct rmi_driver *driver; | ||
1221 | unsigned char temp_buf[2]; | ||
1222 | int retval; | ||
1223 | |||
1224 | fc = to_rmi_function_container(dev); | ||
1225 | instance_data = fc->data; | ||
1226 | driver = fc->rmi_dev->driver; | ||
1227 | |||
1228 | /* Read fifoindex from device */ | ||
1229 | retval = rmi_read_block(fc->rmi_dev, | ||
1230 | fc->fd.data_base_addr + RMI_F54_FIFO_OFFSET, | ||
1231 | temp_buf, ARRAY_SIZE(temp_buf)); | ||
1232 | |||
1233 | if (retval < 0) { | ||
1234 | dev_err(dev, "Could not read fifoindex from 0x%04x\n", | ||
1235 | fc->fd.data_base_addr + RMI_F54_FIFO_OFFSET); | ||
1236 | return retval; | ||
1237 | } | ||
1238 | batohs(&instance_data->fifoindex, temp_buf); | ||
1239 | return snprintf(buf, PAGE_SIZE, "%u\n", instance_data->fifoindex); | ||
1240 | } | ||
1241 | static ssize_t rmi_fn_54_fifoindex_store(struct device *dev, | ||
1242 | struct device_attribute *attr, | ||
1243 | const char *buf, | ||
1244 | size_t count) | ||
1245 | { | ||
1246 | int error; | ||
1247 | unsigned long val; | ||
1248 | unsigned char data[2]; | ||
1249 | struct rmi_function_container *fc; | ||
1250 | struct rmi_fn_54_data *instance_data; | ||
1251 | |||
1252 | fc = to_rmi_function_container(dev); | ||
1253 | instance_data = fc->data; | ||
1254 | |||
1255 | /* need to convert the string data to an actual value */ | ||
1256 | error = strict_strtoul(buf, 10, &val); | ||
1257 | |||
1258 | if (error) | ||
1259 | return error; | ||
1260 | |||
1261 | instance_data->fifoindex = val; | ||
1262 | |||
1263 | /* Write the FifoIndex back to the first data registers. */ | ||
1264 | hstoba(data, (unsigned short)val); | ||
1265 | |||
1266 | error = rmi_write_block(fc->rmi_dev, | ||
1267 | fc->fd.data_base_addr + RMI_F54_FIFO_OFFSET, | ||
1268 | data, | ||
1269 | ARRAY_SIZE(data)); | ||
1270 | |||
1271 | if (error < 0) { | ||
1272 | dev_err(dev, "%s : Could not write fifoindex to 0x%x\n", | ||
1273 | __func__, fc->fd.data_base_addr + RMI_F54_FIFO_OFFSET); | ||
1274 | return error; | ||
1275 | } | ||
1276 | return count; | ||
1277 | } | ||
1278 | |||
1279 | /* Provide access to last report */ | ||
1280 | #ifdef KERNEL_VERSION_ABOVE_2_6_32 | ||
1281 | static ssize_t rmi_fn_54_data_read(struct file *data_file, struct kobject *kobj, | ||
1282 | #else | ||
1283 | static ssize_t rmi_fn_54_data_read(struct kobject *kobj, | ||
1284 | #endif | ||
1285 | struct bin_attribute *attributes, | ||
1286 | char *buf, loff_t pos, size_t count) | ||
1287 | { | ||
1288 | struct device *dev; | ||
1289 | struct rmi_function_container *fc; | ||
1290 | struct rmi_fn_54_data *instance_data; | ||
1291 | |||
1292 | dev = container_of(kobj, struct device, kobj); | ||
1293 | fc = to_rmi_function_container(dev); | ||
1294 | instance_data = fc->data; | ||
1295 | mutex_lock(&instance_data->data_mutex); | ||
1296 | if (count < instance_data->report_size) { | ||
1297 | dev_err(dev, | ||
1298 | "%s: F54 report size too large for buffer: %d." | ||
1299 | " Need at least: %d for Report type: %d.\n", | ||
1300 | __func__, count, instance_data->report_size, | ||
1301 | instance_data->report_type); | ||
1302 | mutex_unlock(&instance_data->data_mutex); | ||
1303 | return -EINVAL; | ||
1304 | } | ||
1305 | if (instance_data->report_data) { | ||
1306 | /* Copy data from instance_data to buffer */ | ||
1307 | memcpy(buf, instance_data->report_data, | ||
1308 | instance_data->report_size); | ||
1309 | mutex_unlock(&instance_data->data_mutex); | ||
1310 | dev_dbg(dev, "%s: Presumably successful.", __func__); | ||
1311 | return instance_data->report_size; | ||
1312 | } else { | ||
1313 | dev_err(dev, "%s: F54 report_data does not exist!\n", __func__); | ||
1314 | mutex_unlock(&instance_data->data_mutex); | ||
1315 | return -EINVAL; | ||
1316 | } | ||
1317 | } | ||
1318 | |||
1319 | static struct rmi_function_handler function_handler = { | ||
1320 | .func = 0x54, | ||
1321 | .init = rmi_f54_init, | ||
1322 | .attention = rmi_f54_attention | ||
1323 | }; | ||
1324 | |||
1325 | static int __init rmi_f54_module_init(void) | ||
1326 | { | ||
1327 | int error; | ||
1328 | |||
1329 | error = rmi_register_function_driver(&function_handler); | ||
1330 | if (error < 0) { | ||
1331 | pr_err("%s: register failed!\n", __func__); | ||
1332 | return error; | ||
1333 | } | ||
1334 | return 0; | ||
1335 | } | ||
1336 | |||
1337 | static void rmi_f54_module_exit(void) | ||
1338 | { | ||
1339 | rmi_unregister_function_driver(&function_handler); | ||
1340 | } | ||
1341 | |||
1342 | module_init(rmi_f54_module_init); | ||
1343 | module_exit(rmi_f54_module_exit); | ||
1344 | |||
1345 | MODULE_AUTHOR("Daniel Rosenberg <daniel.rosenberg@synaptics.com>"); | ||
1346 | MODULE_DESCRIPTION("RMI F54 module"); | ||
1347 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/rmi4/rmi_i2c.c b/drivers/input/touchscreen/rmi4/rmi_i2c.c new file mode 100644 index 00000000000..15624f9cf54 --- /dev/null +++ b/drivers/input/touchscreen/rmi4/rmi_i2c.c | |||
@@ -0,0 +1,421 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Synaptics Incorporated | ||
3 | * Copyright (c) 2011 Unixphere | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/lockdep.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/i2c.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/pm.h> | ||
27 | #include <linux/gpio.h> | ||
28 | #include <linux/rmi.h> | ||
29 | |||
30 | #define COMMS_DEBUG 0 | ||
31 | |||
32 | #define IRQ_DEBUG 0 | ||
33 | |||
34 | #define RMI_PAGE_SELECT_REGISTER 0xff | ||
35 | #define RMI_I2C_PAGE(addr) (((addr) >> 8) & 0xff) | ||
36 | |||
37 | static char *phys_proto_name = "i2c"; | ||
38 | |||
39 | struct rmi_i2c_data { | ||
40 | struct mutex page_mutex; | ||
41 | int page; | ||
42 | int enabled; | ||
43 | int irq; | ||
44 | int irq_flags; | ||
45 | struct rmi_phys_device *phys; | ||
46 | }; | ||
47 | |||
48 | static irqreturn_t rmi_i2c_irq_thread(int irq, void *p) | ||
49 | { | ||
50 | struct rmi_phys_device *phys = p; | ||
51 | struct rmi_device *rmi_dev = phys->rmi_dev; | ||
52 | struct rmi_driver *driver = rmi_dev->driver; | ||
53 | struct rmi_device_platform_data *pdata = phys->dev->platform_data; | ||
54 | |||
55 | #if IRQ_DEBUG | ||
56 | dev_dbg(phys->dev, "ATTN gpio, value: %d.\n", | ||
57 | gpio_get_value(irq_to_gpio(irq))); | ||
58 | #endif | ||
59 | if (gpio_get_value(irq_to_gpio(irq)) == pdata->irq_polarity) { | ||
60 | phys->info.attn_count++; | ||
61 | if (driver && driver->irq_handler && rmi_dev) | ||
62 | driver->irq_handler(rmi_dev, irq); | ||
63 | } | ||
64 | |||
65 | return IRQ_HANDLED; | ||
66 | } | ||
67 | |||
68 | /* | ||
69 | * rmi_set_page - Set RMI page | ||
70 | * @phys: The pointer to the rmi_phys_device struct | ||
71 | * @page: The new page address. | ||
72 | * | ||
73 | * RMI devices have 16-bit addressing, but some of the physical | ||
74 | * implementations (like SMBus) only have 8-bit addressing. So RMI implements | ||
75 | * a page address at 0xff of every page so we can reliable page addresses | ||
76 | * every 256 registers. | ||
77 | * | ||
78 | * The page_mutex lock must be held when this function is entered. | ||
79 | * | ||
80 | * Returns zero on success, non-zero on failure. | ||
81 | */ | ||
82 | static int rmi_set_page(struct rmi_phys_device *phys, unsigned int page) | ||
83 | { | ||
84 | struct i2c_client *client = to_i2c_client(phys->dev); | ||
85 | struct rmi_i2c_data *data = phys->data; | ||
86 | char txbuf[2] = {RMI_PAGE_SELECT_REGISTER, page}; | ||
87 | int retval; | ||
88 | |||
89 | #if COMMS_DEBUG | ||
90 | dev_dbg(&client->dev, "RMI4 I2C writes 3 bytes: %02x %02x\n", | ||
91 | txbuf[0], txbuf[1]); | ||
92 | #endif | ||
93 | phys->info.tx_count++; | ||
94 | phys->info.tx_bytes += sizeof(txbuf); | ||
95 | retval = i2c_master_send(client, txbuf, sizeof(txbuf)); | ||
96 | if (retval != sizeof(txbuf)) { | ||
97 | phys->info.tx_errs++; | ||
98 | dev_err(&client->dev, | ||
99 | "%s: set page failed: %d.", __func__, retval); | ||
100 | return (retval < 0) ? retval : -EIO; | ||
101 | } | ||
102 | data->page = page; | ||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | static int rmi_i2c_write_block(struct rmi_phys_device *phys, u16 addr, u8 *buf, | ||
107 | int len) | ||
108 | { | ||
109 | struct i2c_client *client = to_i2c_client(phys->dev); | ||
110 | struct rmi_i2c_data *data = phys->data; | ||
111 | u8 txbuf[len + 1]; | ||
112 | int retval; | ||
113 | #if COMMS_DEBUG | ||
114 | int i; | ||
115 | #endif | ||
116 | |||
117 | txbuf[0] = addr & 0xff; | ||
118 | memcpy(txbuf + 1, buf, len); | ||
119 | |||
120 | mutex_lock(&data->page_mutex); | ||
121 | |||
122 | if (RMI_I2C_PAGE(addr) != data->page) { | ||
123 | retval = rmi_set_page(phys, RMI_I2C_PAGE(addr)); | ||
124 | if (retval < 0) | ||
125 | goto exit; | ||
126 | } | ||
127 | |||
128 | #if COMMS_DEBUG | ||
129 | dev_dbg(&client->dev, "RMI4 I2C writes %d bytes: ", sizeof(txbuf)); | ||
130 | for (i = 0; i < sizeof(txbuf); i++) | ||
131 | dev_dbg(&client->dev, "%02x ", txbuf[i]); | ||
132 | dev_dbg(&client->dev, "\n"); | ||
133 | #endif | ||
134 | |||
135 | phys->info.tx_count++; | ||
136 | phys->info.tx_bytes += sizeof(txbuf); | ||
137 | retval = i2c_master_send(client, txbuf, sizeof(txbuf)); | ||
138 | if (retval < 0) | ||
139 | phys->info.tx_errs++; | ||
140 | |||
141 | exit: | ||
142 | mutex_unlock(&data->page_mutex); | ||
143 | return retval; | ||
144 | } | ||
145 | |||
146 | static int rmi_i2c_write(struct rmi_phys_device *phys, u16 addr, u8 data) | ||
147 | { | ||
148 | int retval = rmi_i2c_write_block(phys, addr, &data, 1); | ||
149 | return (retval < 0) ? retval : 0; | ||
150 | } | ||
151 | |||
152 | static int rmi_i2c_read_block(struct rmi_phys_device *phys, u16 addr, u8 *buf, | ||
153 | int len) | ||
154 | { | ||
155 | struct i2c_client *client = to_i2c_client(phys->dev); | ||
156 | struct rmi_i2c_data *data = phys->data; | ||
157 | u8 txbuf[1] = {addr & 0xff}; | ||
158 | int retval; | ||
159 | #if COMMS_DEBUG | ||
160 | int i; | ||
161 | #endif | ||
162 | |||
163 | mutex_lock(&data->page_mutex); | ||
164 | |||
165 | if (RMI_I2C_PAGE(addr) != data->page) { | ||
166 | retval = rmi_set_page(phys, RMI_I2C_PAGE(addr)); | ||
167 | if (retval < 0) | ||
168 | goto exit; | ||
169 | } | ||
170 | |||
171 | #if COMMS_DEBUG | ||
172 | dev_dbg(&client->dev, "RMI4 I2C writes 1 bytes: %02x\n", txbuf[0]); | ||
173 | #endif | ||
174 | phys->info.tx_count++; | ||
175 | phys->info.tx_bytes += sizeof(txbuf); | ||
176 | retval = i2c_master_send(client, txbuf, sizeof(txbuf)); | ||
177 | if (retval != sizeof(txbuf)) { | ||
178 | phys->info.tx_errs++; | ||
179 | retval = (retval < 0) ? retval : -EIO; | ||
180 | goto exit; | ||
181 | } | ||
182 | |||
183 | retval = i2c_master_recv(client, buf, len); | ||
184 | |||
185 | phys->info.rx_count++; | ||
186 | phys->info.rx_bytes += len; | ||
187 | if (retval < 0) | ||
188 | phys->info.rx_errs++; | ||
189 | #if COMMS_DEBUG | ||
190 | else { | ||
191 | dev_dbg(&client->dev, "RMI4 I2C received %d bytes: ", len); | ||
192 | for (i = 0; i < len; i++) | ||
193 | dev_dbg(&client->dev, "%02x ", buf[i]); | ||
194 | dev_dbg(&client->dev, "\n"); | ||
195 | } | ||
196 | #endif | ||
197 | |||
198 | exit: | ||
199 | mutex_unlock(&data->page_mutex); | ||
200 | return retval; | ||
201 | } | ||
202 | |||
203 | static int rmi_i2c_read(struct rmi_phys_device *phys, u16 addr, u8 *buf) | ||
204 | { | ||
205 | int retval = rmi_i2c_read_block(phys, addr, buf, 1); | ||
206 | return (retval < 0) ? retval : 0; | ||
207 | } | ||
208 | |||
209 | |||
210 | static int acquire_attn_irq(struct rmi_i2c_data *data) | ||
211 | { | ||
212 | return request_threaded_irq(data->irq, NULL, rmi_i2c_irq_thread, | ||
213 | data->irq_flags, dev_name(data->phys->dev), data->phys); | ||
214 | } | ||
215 | |||
216 | static int enable_device(struct rmi_phys_device *phys) | ||
217 | { | ||
218 | int retval = 0; | ||
219 | |||
220 | struct rmi_i2c_data *data = phys->data; | ||
221 | |||
222 | if (data->enabled) | ||
223 | return 0; | ||
224 | |||
225 | retval = acquire_attn_irq(data); | ||
226 | if (retval) | ||
227 | goto error_exit; | ||
228 | |||
229 | data->enabled = true; | ||
230 | dev_dbg(phys->dev, "Physical device enabled.\n"); | ||
231 | return 0; | ||
232 | |||
233 | error_exit: | ||
234 | dev_err(phys->dev, "Failed to enable physical device. Code=%d.\n", | ||
235 | retval); | ||
236 | return retval; | ||
237 | } | ||
238 | |||
239 | |||
240 | static void disable_device(struct rmi_phys_device *phys) | ||
241 | { | ||
242 | struct rmi_i2c_data *data = phys->data; | ||
243 | |||
244 | if (!data->enabled) | ||
245 | return; | ||
246 | |||
247 | disable_irq(data->irq); | ||
248 | free_irq(data->irq, data->phys); | ||
249 | |||
250 | dev_dbg(phys->dev, "Physical device disabled.\n"); | ||
251 | data->enabled = false; | ||
252 | } | ||
253 | |||
254 | |||
255 | static int __devinit rmi_i2c_probe(struct i2c_client *client, | ||
256 | const struct i2c_device_id *id) | ||
257 | { | ||
258 | struct rmi_phys_device *rmi_phys; | ||
259 | struct rmi_i2c_data *data; | ||
260 | struct rmi_device_platform_data *pdata = client->dev.platform_data; | ||
261 | int error; | ||
262 | |||
263 | if (!pdata) { | ||
264 | dev_err(&client->dev, "no platform data\n"); | ||
265 | return -EINVAL; | ||
266 | } | ||
267 | |||
268 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | ||
269 | dev_err(&client->dev, "i2c_check_functionality error\n"); | ||
270 | return -EIO; | ||
271 | } | ||
272 | |||
273 | rmi_phys = kzalloc(sizeof(struct rmi_phys_device), GFP_KERNEL); | ||
274 | if (!rmi_phys) | ||
275 | return -ENOMEM; | ||
276 | |||
277 | data = kzalloc(sizeof(struct rmi_i2c_data), GFP_KERNEL); | ||
278 | if (!data) { | ||
279 | error = -ENOMEM; | ||
280 | goto err_phys; | ||
281 | } | ||
282 | |||
283 | data->enabled = true; /* We plan to come up enabled. */ | ||
284 | data->irq = gpio_to_irq(pdata->irq); | ||
285 | data->irq_flags = (pdata->irq_polarity == RMI_IRQ_ACTIVE_HIGH) ? | ||
286 | IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING; | ||
287 | data->phys = rmi_phys; | ||
288 | |||
289 | rmi_phys->data = data; | ||
290 | rmi_phys->dev = &client->dev; | ||
291 | |||
292 | rmi_phys->write = rmi_i2c_write; | ||
293 | rmi_phys->write_block = rmi_i2c_write_block; | ||
294 | rmi_phys->read = rmi_i2c_read; | ||
295 | rmi_phys->read_block = rmi_i2c_read_block; | ||
296 | rmi_phys->enable_device = enable_device; | ||
297 | rmi_phys->disable_device = disable_device; | ||
298 | |||
299 | rmi_phys->info.proto = phys_proto_name; | ||
300 | |||
301 | mutex_init(&data->page_mutex); | ||
302 | |||
303 | /* Setting the page to zero will (a) make sure the PSR is in a | ||
304 | * known state, and (b) make sure we can talk to the device. | ||
305 | */ | ||
306 | error = rmi_set_page(rmi_phys, 0); | ||
307 | if (error) { | ||
308 | dev_err(&client->dev, "Failed to set page select to 0.\n"); | ||
309 | goto err_data; | ||
310 | } | ||
311 | |||
312 | if (pdata->gpio_config) { | ||
313 | error = pdata->gpio_config(&client->dev, true); | ||
314 | if (error < 0) { | ||
315 | dev_err(&client->dev, "failed to setup irq %d\n", | ||
316 | pdata->irq); | ||
317 | goto err_data; | ||
318 | } | ||
319 | } | ||
320 | |||
321 | error = rmi_register_phys_device(rmi_phys); | ||
322 | if (error) { | ||
323 | dev_err(&client->dev, | ||
324 | "failed to register physical driver at 0x%.2X.\n", | ||
325 | client->addr); | ||
326 | goto err_data; | ||
327 | } | ||
328 | i2c_set_clientdata(client, rmi_phys); | ||
329 | |||
330 | if (pdata->irq > 0) { | ||
331 | error = acquire_attn_irq(data); | ||
332 | if (error < 0) { | ||
333 | dev_err(&client->dev, | ||
334 | "request_threaded_irq failed %d\n", | ||
335 | pdata->irq); | ||
336 | goto err_unregister; | ||
337 | } | ||
338 | } | ||
339 | |||
340 | #if defined(CONFIG_RMI4_DEV) | ||
341 | error = gpio_export(pdata->irq, false); | ||
342 | if (error) { | ||
343 | dev_warn(&client->dev, "%s: WARNING: Failed to " | ||
344 | "export ATTN gpio!\n", __func__); | ||
345 | error = 0; | ||
346 | } else { | ||
347 | error = gpio_export_link(&(rmi_phys->rmi_dev->dev), "attn", | ||
348 | pdata->irq); | ||
349 | if (error) { | ||
350 | dev_warn(&(rmi_phys->rmi_dev->dev), "%s: WARNING: " | ||
351 | "Failed to symlink ATTN gpio!\n", __func__); | ||
352 | error = 0; | ||
353 | } else { | ||
354 | dev_info(&(rmi_phys->rmi_dev->dev), | ||
355 | "%s: Exported GPIO %d.", __func__, pdata->irq); | ||
356 | } | ||
357 | } | ||
358 | #endif /* CONFIG_RMI4_DEV */ | ||
359 | |||
360 | dev_info(&client->dev, "registered rmi i2c driver at 0x%.2X.\n", | ||
361 | client->addr); | ||
362 | return 0; | ||
363 | |||
364 | err_unregister: | ||
365 | rmi_unregister_phys_device(rmi_phys); | ||
366 | err_data: | ||
367 | kfree(data); | ||
368 | err_phys: | ||
369 | kfree(rmi_phys); | ||
370 | return error; | ||
371 | } | ||
372 | |||
373 | static int __devexit rmi_i2c_remove(struct i2c_client *client) | ||
374 | { | ||
375 | struct rmi_phys_device *phys = i2c_get_clientdata(client); | ||
376 | struct rmi_device_platform_data *pd = client->dev.platform_data; | ||
377 | |||
378 | rmi_unregister_phys_device(phys); | ||
379 | kfree(phys->data); | ||
380 | kfree(phys); | ||
381 | |||
382 | if (pd->gpio_config) | ||
383 | pd->gpio_config(&client->dev, false); | ||
384 | |||
385 | return 0; | ||
386 | } | ||
387 | |||
388 | static const struct i2c_device_id rmi_id[] = { | ||
389 | { "rmi", 0 }, | ||
390 | { "rmi-i2c", 0 }, | ||
391 | { } | ||
392 | }; | ||
393 | MODULE_DEVICE_TABLE(i2c, rmi_id); | ||
394 | |||
395 | static struct i2c_driver rmi_i2c_driver = { | ||
396 | .driver = { | ||
397 | .owner = THIS_MODULE, | ||
398 | .name = "rmi-i2c" | ||
399 | }, | ||
400 | .id_table = rmi_id, | ||
401 | .probe = rmi_i2c_probe, | ||
402 | .remove = __devexit_p(rmi_i2c_remove), | ||
403 | }; | ||
404 | |||
405 | static int __init rmi_i2c_init(void) | ||
406 | { | ||
407 | return i2c_add_driver(&rmi_i2c_driver); | ||
408 | } | ||
409 | |||
410 | static void __exit rmi_i2c_exit(void) | ||
411 | { | ||
412 | i2c_del_driver(&rmi_i2c_driver); | ||
413 | } | ||
414 | |||
415 | MODULE_AUTHOR("Christopher Heiny <cheiny@synaptics.com>"); | ||
416 | MODULE_AUTHOR("Eric Andersson <eric.andersson@unixphere.com>"); | ||
417 | MODULE_DESCRIPTION("RMI i2c driver"); | ||
418 | MODULE_LICENSE("GPL"); | ||
419 | |||
420 | module_init(rmi_i2c_init); | ||
421 | module_exit(rmi_i2c_exit); | ||
diff --git a/drivers/input/touchscreen/rmi4/rmi_spi.c b/drivers/input/touchscreen/rmi4/rmi_spi.c new file mode 100644 index 00000000000..41f72657f82 --- /dev/null +++ b/drivers/input/touchscreen/rmi4/rmi_spi.c | |||
@@ -0,0 +1,869 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Synaptics Incorporated | ||
3 | * Copyright (c) 2011 Unixphere | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/spi/spi.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/completion.h> | ||
25 | #include <linux/sched.h> | ||
26 | #include <linux/gpio.h> | ||
27 | #include <linux/rmi.h> | ||
28 | |||
29 | #define COMMS_DEBUG 0 | ||
30 | |||
31 | #define RMI_PROTOCOL_VERSION_ADDRESS 0xa0fd | ||
32 | #define SPI_V2_UNIFIED_READ 0xc0 | ||
33 | #define SPI_V2_WRITE 0x40 | ||
34 | #define SPI_V2_PREPARE_SPLIT_READ 0xc8 | ||
35 | #define SPI_V2_EXECUTE_SPLIT_READ 0xca | ||
36 | |||
37 | #define RMI_SPI_BLOCK_DELAY_US 65 | ||
38 | #define RMI_SPI_BYTE_DELAY_US 65 | ||
39 | #define RMI_SPI_WRITE_DELAY_US 0 | ||
40 | |||
41 | #define RMI_V1_READ_FLAG 0x80 | ||
42 | |||
43 | #define RMI_PAGE_SELECT_REGISTER 0x00FF | ||
44 | #define RMI_SPI_PAGE(addr) (((addr) >> 8) & 0x80) | ||
45 | |||
46 | static char *spi_v1_proto_name = "spi"; | ||
47 | static char *spi_v2_proto_name = "spiv2"; | ||
48 | |||
49 | struct rmi_spi_data { | ||
50 | struct mutex page_mutex; | ||
51 | int page; | ||
52 | int (*set_page) (struct rmi_phys_device *phys, u8 page); | ||
53 | bool split_read_pending; | ||
54 | int enabled; | ||
55 | int irq; | ||
56 | int irq_flags; | ||
57 | struct rmi_phys_device *phys; | ||
58 | struct completion irq_comp; | ||
59 | }; | ||
60 | |||
61 | static irqreturn_t rmi_spi_hard_irq(int irq, void *p) | ||
62 | { | ||
63 | struct rmi_phys_device *phys = p; | ||
64 | struct rmi_spi_data *data = phys->data; | ||
65 | struct rmi_device_platform_data *pdata = phys->dev->platform_data; | ||
66 | |||
67 | if (data->split_read_pending && | ||
68 | gpio_get_value(irq_to_gpio(irq)) == pdata->irq_polarity) { | ||
69 | phys->info.attn_count++; | ||
70 | complete(&data->irq_comp); | ||
71 | return IRQ_HANDLED; | ||
72 | } | ||
73 | |||
74 | return IRQ_WAKE_THREAD; | ||
75 | } | ||
76 | |||
77 | static irqreturn_t rmi_spi_irq_thread(int irq, void *p) | ||
78 | { | ||
79 | struct rmi_phys_device *phys = p; | ||
80 | struct rmi_device *rmi_dev = phys->rmi_dev; | ||
81 | struct rmi_driver *driver = rmi_dev->driver; | ||
82 | struct rmi_device_platform_data *pdata = phys->dev->platform_data; | ||
83 | |||
84 | if (gpio_get_value(irq_to_gpio(irq)) == pdata->irq_polarity) { | ||
85 | phys->info.attn_count++; | ||
86 | if (driver && driver->irq_handler) | ||
87 | driver->irq_handler(rmi_dev, irq); | ||
88 | } | ||
89 | |||
90 | return IRQ_HANDLED; | ||
91 | } | ||
92 | |||
93 | static int rmi_spi_xfer(struct rmi_phys_device *phys, | ||
94 | const u8 *txbuf, unsigned n_tx, u8 *rxbuf, unsigned n_rx) | ||
95 | { | ||
96 | struct spi_device *client = to_spi_device(phys->dev); | ||
97 | struct rmi_spi_data *v2_data = phys->data; | ||
98 | struct rmi_device_platform_data *pdata = phys->dev->platform_data; | ||
99 | int status; | ||
100 | struct spi_message message; | ||
101 | struct spi_transfer *xfers; | ||
102 | int total_bytes = n_tx + n_rx; | ||
103 | u8 local_buf[total_bytes]; | ||
104 | int xfer_count = 0; | ||
105 | int xfer_index = 0; | ||
106 | int block_delay = n_rx > 0 ? pdata->spi_data.block_delay_us : 0; | ||
107 | int byte_delay = n_rx > 1 ? pdata->spi_data.read_delay_us : 0; | ||
108 | int write_delay = n_tx > 1 ? pdata->spi_data.write_delay_us : 0; | ||
109 | #if COMMS_DEBUG | ||
110 | int i; | ||
111 | #endif | ||
112 | // pr_info("in function ____%s____ \n", __func__); | ||
113 | |||
114 | if (v2_data->split_read_pending) { | ||
115 | block_delay = | ||
116 | n_rx > 0 ? pdata->spi_data.split_read_block_delay_us : 0; | ||
117 | byte_delay = | ||
118 | n_tx > 1 ? pdata->spi_data.split_read_byte_delay_us : 0; | ||
119 | write_delay = 0; | ||
120 | } | ||
121 | |||
122 | if (n_tx) { | ||
123 | phys->info.tx_count++; | ||
124 | phys->info.tx_bytes += n_tx; | ||
125 | if (write_delay) | ||
126 | xfer_count += n_tx; | ||
127 | else | ||
128 | xfer_count += 1; | ||
129 | } | ||
130 | |||
131 | if (n_rx) { | ||
132 | phys->info.rx_count++; | ||
133 | phys->info.rx_bytes += n_rx; | ||
134 | if (byte_delay) | ||
135 | xfer_count += n_rx; | ||
136 | else | ||
137 | xfer_count += 1; | ||
138 | } | ||
139 | |||
140 | xfers = kcalloc(xfer_count, | ||
141 | sizeof(struct spi_transfer), GFP_KERNEL); | ||
142 | if (!xfers) | ||
143 | return -ENOMEM; | ||
144 | |||
145 | spi_message_init(&message); | ||
146 | |||
147 | if (n_tx) { | ||
148 | if (write_delay) { | ||
149 | for (xfer_index = 0; xfer_index < n_tx; | ||
150 | xfer_index++) { | ||
151 | memset(&xfers[xfer_index], 0, | ||
152 | sizeof(struct spi_transfer)); | ||
153 | xfers[xfer_index].len = 1; | ||
154 | xfers[xfer_index].delay_usecs = write_delay; | ||
155 | xfers[xfer_index].cs_change = 1; | ||
156 | xfers[xfer_index].tx_buf = txbuf + xfer_index; | ||
157 | spi_message_add_tail(&xfers[xfer_index], | ||
158 | &message); | ||
159 | } | ||
160 | } else { | ||
161 | memset(&xfers[0], 0, sizeof(struct spi_transfer)); | ||
162 | xfers[0].len = n_tx; | ||
163 | spi_message_add_tail(&xfers[0], &message); | ||
164 | memcpy(local_buf, txbuf, n_tx); | ||
165 | xfers[0].tx_buf = local_buf; | ||
166 | xfer_index++; | ||
167 | } | ||
168 | if (block_delay){ | ||
169 | xfers[xfer_index-1].delay_usecs = block_delay; | ||
170 | xfers[xfer_index].cs_change = 1; | ||
171 | } | ||
172 | } | ||
173 | if (n_rx) { | ||
174 | if (byte_delay) { | ||
175 | int buffer_offset = n_tx; | ||
176 | for (; xfer_index < xfer_count; xfer_index++) { | ||
177 | memset(&xfers[xfer_index], 0, | ||
178 | sizeof(struct spi_transfer)); | ||
179 | xfers[xfer_index].len = 1; | ||
180 | xfers[xfer_index].delay_usecs = byte_delay; | ||
181 | xfers[xfer_index].cs_change = 1; | ||
182 | xfers[xfer_index].rx_buf = | ||
183 | local_buf + buffer_offset; | ||
184 | buffer_offset++; | ||
185 | spi_message_add_tail(&xfers[xfer_index], | ||
186 | &message); | ||
187 | } | ||
188 | } else { | ||
189 | memset(&xfers[xfer_index], 0, | ||
190 | sizeof(struct spi_transfer)); | ||
191 | xfers[xfer_index].len = n_rx; | ||
192 | xfers[xfer_index].rx_buf = local_buf + n_tx; | ||
193 | spi_message_add_tail(&xfers[xfer_index], &message); | ||
194 | xfer_index++; | ||
195 | } | ||
196 | } | ||
197 | |||
198 | #if COMMS_DEBUG | ||
199 | if (n_tx) { | ||
200 | dev_info(&client->dev, "SPI sends %d bytes: ", n_tx); | ||
201 | for (i = 0; i < n_tx; i++) | ||
202 | // dev_info(&client->dev, "%02X ", txbuf[i]); | ||
203 | pr_info(": %02X ", txbuf[i]); | ||
204 | // dev_info(&client->dev, "\n"); | ||
205 | pr_info("\n"); | ||
206 | } | ||
207 | #endif | ||
208 | |||
209 | /* do the i/o */ | ||
210 | if (pdata->spi_data.cs_assert) { | ||
211 | status = pdata->spi_data.cs_assert( | ||
212 | pdata->spi_data.cs_assert_data, true); | ||
213 | if (!status) { | ||
214 | dev_err(phys->dev, "Failed to assert CS."); | ||
215 | /* nonzero means error */ | ||
216 | status = -1; | ||
217 | goto error_exit; | ||
218 | } else | ||
219 | status = 0; | ||
220 | } | ||
221 | |||
222 | if (pdata->spi_data.pre_delay_us) | ||
223 | udelay(pdata->spi_data.pre_delay_us); | ||
224 | |||
225 | status = spi_sync(client, &message); | ||
226 | |||
227 | if (pdata->spi_data.post_delay_us) | ||
228 | udelay(pdata->spi_data.post_delay_us); | ||
229 | |||
230 | if (pdata->spi_data.cs_assert) { | ||
231 | status = pdata->spi_data.cs_assert( | ||
232 | pdata->spi_data.cs_assert_data, false); | ||
233 | if (!status) { | ||
234 | dev_err(phys->dev, "Failed to deassert CS."); | ||
235 | /* nonzero means error */ | ||
236 | status = -1; | ||
237 | goto error_exit; | ||
238 | } else | ||
239 | status = 0; | ||
240 | } | ||
241 | |||
242 | if (status == 0) { | ||
243 | memcpy(rxbuf, local_buf + n_tx, n_rx); | ||
244 | status = message.status; | ||
245 | } else { | ||
246 | phys->info.tx_errs++; | ||
247 | phys->info.rx_errs++; | ||
248 | dev_err(phys->dev, "spi_sync failed with error code %d.", | ||
249 | status); | ||
250 | } | ||
251 | |||
252 | #if COMMS_DEBUG | ||
253 | if (n_rx) { | ||
254 | dev_info(&client->dev, "SPI received %d bytes: ", n_rx); | ||
255 | for (i = 0; i < n_rx; i++) | ||
256 | // dev_info(&client->dev, "%02X ", rxbuf[i]); | ||
257 | pr_info(": %02X ", rxbuf[i]); | ||
258 | // dev_info(&client->dev, "\n"); | ||
259 | pr_info("\n"); | ||
260 | } | ||
261 | #endif | ||
262 | |||
263 | error_exit: | ||
264 | kfree(xfers); | ||
265 | return status; | ||
266 | } | ||
267 | |||
268 | static int rmi_spi_v2_write_block(struct rmi_phys_device *phys, u16 addr, | ||
269 | u8 *buf, int len) | ||
270 | { | ||
271 | struct rmi_spi_data *data = phys->data; | ||
272 | u8 txbuf[len + 4]; | ||
273 | int error; | ||
274 | // pr_info("in function ____%s____ \n", __func__); | ||
275 | |||
276 | txbuf[0] = SPI_V2_WRITE; | ||
277 | txbuf[1] = (addr >> 8) & 0x00FF; | ||
278 | txbuf[2] = addr & 0x00FF; | ||
279 | txbuf[3] = len; | ||
280 | |||
281 | memcpy(&txbuf[4], buf, len); | ||
282 | |||
283 | mutex_lock(&data->page_mutex); | ||
284 | |||
285 | if (RMI_SPI_PAGE(addr) != data->page) { | ||
286 | error = data->set_page(phys, RMI_SPI_PAGE(addr)); | ||
287 | if (error < 0) | ||
288 | goto exit; | ||
289 | } | ||
290 | |||
291 | error = rmi_spi_xfer(phys, buf, len + 4, NULL, 0); | ||
292 | if (error < 0) | ||
293 | goto exit; | ||
294 | error = len; | ||
295 | |||
296 | exit: | ||
297 | mutex_unlock(&data->page_mutex); | ||
298 | return error; | ||
299 | } | ||
300 | |||
301 | static int rmi_spi_v2_write(struct rmi_phys_device *phys, u16 addr, u8 data) | ||
302 | { | ||
303 | int error = rmi_spi_v2_write_block(phys, addr, &data, 1); | ||
304 | // pr_info("in function ____%s____ \n", __func__); | ||
305 | |||
306 | return (error == 1) ? 0 : error; | ||
307 | } | ||
308 | |||
309 | static int rmi_spi_v1_write_block(struct rmi_phys_device *phys, u16 addr, | ||
310 | u8 *buf, int len) | ||
311 | { | ||
312 | struct rmi_spi_data *data = phys->data; | ||
313 | unsigned char txbuf[len + 2]; | ||
314 | int error; | ||
315 | // pr_info("in function ____%s____ \n", __func__); | ||
316 | |||
317 | txbuf[0] = addr >> 8; | ||
318 | txbuf[1] = addr; | ||
319 | memcpy(txbuf+2, buf, len); | ||
320 | |||
321 | mutex_lock(&data->page_mutex); | ||
322 | |||
323 | if (RMI_SPI_PAGE(addr) != data->page) { | ||
324 | error = data->set_page(phys, RMI_SPI_PAGE(addr)); | ||
325 | if (error < 0) | ||
326 | goto exit; | ||
327 | } | ||
328 | |||
329 | error = rmi_spi_xfer(phys, txbuf, len + 2, NULL, 0); | ||
330 | if (error < 0) | ||
331 | goto exit; | ||
332 | error = len; | ||
333 | |||
334 | exit: | ||
335 | mutex_unlock(&data->page_mutex); | ||
336 | return error; | ||
337 | } | ||
338 | |||
339 | static int rmi_spi_v1_write(struct rmi_phys_device *phys, u16 addr, u8 data) | ||
340 | { | ||
341 | int error = rmi_spi_v1_write_block(phys, addr, &data, 1); | ||
342 | // pr_info("in function ____%s____ \n", __func__); | ||
343 | |||
344 | return (error == 1) ? 0 : error; | ||
345 | } | ||
346 | |||
347 | static int rmi_spi_v2_split_read_block(struct rmi_phys_device *phys, u16 addr, | ||
348 | u8 *buf, int len) | ||
349 | { | ||
350 | struct rmi_spi_data *data = phys->data; | ||
351 | u8 txbuf[4]; | ||
352 | u8 rxbuf[len + 1]; /* one extra byte for read length */ | ||
353 | int error; | ||
354 | // pr_info("in function ____%s____ \n", __func__); | ||
355 | |||
356 | txbuf[0] = SPI_V2_PREPARE_SPLIT_READ; | ||
357 | txbuf[1] = (addr >> 8) & 0x00FF; | ||
358 | txbuf[2] = addr & 0x00ff; | ||
359 | txbuf[3] = len; | ||
360 | |||
361 | mutex_lock(&data->page_mutex); | ||
362 | |||
363 | if (RMI_SPI_PAGE(addr) != data->page) { | ||
364 | error = data->set_page(phys, RMI_SPI_PAGE(addr)); | ||
365 | if (error < 0) | ||
366 | goto exit; | ||
367 | } | ||
368 | |||
369 | data->split_read_pending = true; | ||
370 | |||
371 | error = rmi_spi_xfer(phys, txbuf, 4, NULL, 0); | ||
372 | if (error < 0) { | ||
373 | data->split_read_pending = false; | ||
374 | goto exit; | ||
375 | } | ||
376 | |||
377 | wait_for_completion(&data->irq_comp); | ||
378 | |||
379 | txbuf[0] = SPI_V2_EXECUTE_SPLIT_READ; | ||
380 | txbuf[1] = 0; | ||
381 | |||
382 | error = rmi_spi_xfer(phys, txbuf, 2, rxbuf, len + 1); | ||
383 | data->split_read_pending = false; | ||
384 | if (error < 0) | ||
385 | goto exit; | ||
386 | |||
387 | /* first byte is length */ | ||
388 | if (rxbuf[0] != len) { | ||
389 | error = -EIO; | ||
390 | goto exit; | ||
391 | } | ||
392 | |||
393 | memcpy(buf, rxbuf + 1, len); | ||
394 | error = len; | ||
395 | |||
396 | exit: | ||
397 | mutex_unlock(&data->page_mutex); | ||
398 | return error; | ||
399 | } | ||
400 | |||
401 | static int rmi_spi_v2_read_block(struct rmi_phys_device *phys, u16 addr, | ||
402 | u8 *buf, int len) | ||
403 | { | ||
404 | struct rmi_spi_data *data = phys->data; | ||
405 | u8 txbuf[4]; | ||
406 | int error; | ||
407 | // pr_info("in function ____%s____ \n", __func__); | ||
408 | |||
409 | txbuf[0] = SPI_V2_UNIFIED_READ; | ||
410 | txbuf[1] = (addr >> 8) & 0x00FF; | ||
411 | txbuf[2] = addr & 0x00ff; | ||
412 | txbuf[3] = len; | ||
413 | |||
414 | mutex_lock(&data->page_mutex); | ||
415 | |||
416 | if (RMI_SPI_PAGE(addr) != data->page) { | ||
417 | error = data->set_page(phys, RMI_SPI_PAGE(addr)); | ||
418 | if (error < 0) | ||
419 | goto exit; | ||
420 | } | ||
421 | |||
422 | error = rmi_spi_xfer(phys, txbuf, 4, buf, len); | ||
423 | if (error < 0) | ||
424 | goto exit; | ||
425 | error = len; | ||
426 | |||
427 | exit: | ||
428 | mutex_unlock(&data->page_mutex); | ||
429 | return error; | ||
430 | } | ||
431 | |||
432 | static int rmi_spi_v2_read(struct rmi_phys_device *phys, u16 addr, u8 *buf) | ||
433 | { | ||
434 | int error = rmi_spi_v2_read_block(phys, addr, buf, 1); | ||
435 | |||
436 | return (error == 1) ? 0 : error; | ||
437 | } | ||
438 | |||
439 | static int rmi_spi_v1_read_block(struct rmi_phys_device *phys, u16 addr, | ||
440 | u8 *buf, int len) | ||
441 | { | ||
442 | struct rmi_spi_data *data = phys->data; | ||
443 | u8 txbuf[2]; | ||
444 | int error; | ||
445 | // pr_info("in function ____%s____ \n", __func__); | ||
446 | |||
447 | txbuf[0] = (addr >> 8) | RMI_V1_READ_FLAG; | ||
448 | txbuf[1] = addr; | ||
449 | |||
450 | mutex_lock(&data->page_mutex); | ||
451 | |||
452 | if (RMI_SPI_PAGE(addr) != data->page) { | ||
453 | error = data->set_page(phys, RMI_SPI_PAGE(addr)); | ||
454 | if (error < 0) | ||
455 | goto exit; | ||
456 | } | ||
457 | |||
458 | error = rmi_spi_xfer(phys, txbuf, 2, buf, len); | ||
459 | // pr_info(" back in function %s, rmi_spi_xfer returned %d\n", __func__, error); | ||
460 | |||
461 | if (error < 0) | ||
462 | goto exit; | ||
463 | error = len; | ||
464 | |||
465 | exit: | ||
466 | mutex_unlock(&data->page_mutex); | ||
467 | return error; | ||
468 | } | ||
469 | |||
470 | static int rmi_spi_v1_read(struct rmi_phys_device *phys, u16 addr, u8 *buf) | ||
471 | { | ||
472 | int error = rmi_spi_v1_read_block(phys, addr, buf, 1); | ||
473 | pr_info("in function ____%s____ \n", __func__); | ||
474 | |||
475 | return (error == 1) ? 0 : error; | ||
476 | } | ||
477 | |||
478 | #define RMI_SPI_PAGE_SELECT_WRITE_LENGTH 1 | ||
479 | |||
480 | static int rmi_spi_v1_set_page(struct rmi_phys_device *phys, u8 page) | ||
481 | { | ||
482 | struct rmi_spi_data *data = phys->data; | ||
483 | u8 txbuf[] = {RMI_PAGE_SELECT_REGISTER >> 8, | ||
484 | RMI_PAGE_SELECT_REGISTER & 0xFF, page}; | ||
485 | int error; | ||
486 | pr_info("in function ____%s____ \n", __func__); | ||
487 | |||
488 | error = rmi_spi_xfer(phys, txbuf, sizeof(txbuf), NULL, 0); | ||
489 | if (error < 0) { | ||
490 | dev_err(phys->dev, "Failed to set page select, code: %d.\n", | ||
491 | error); | ||
492 | return error; | ||
493 | } | ||
494 | |||
495 | data->page = page; | ||
496 | |||
497 | return RMI_SPI_PAGE_SELECT_WRITE_LENGTH; | ||
498 | } | ||
499 | |||
500 | static int rmi_spi_v2_set_page(struct rmi_phys_device *phys, u8 page) | ||
501 | { | ||
502 | struct rmi_spi_data *data = phys->data; | ||
503 | |||
504 | u8 txbuf[] = {SPI_V2_WRITE, RMI_PAGE_SELECT_REGISTER >> 8, | ||
505 | RMI_PAGE_SELECT_REGISTER & 0xFF, | ||
506 | RMI_SPI_PAGE_SELECT_WRITE_LENGTH, page}; | ||
507 | int error; | ||
508 | pr_info("in function ____%s____ \n", __func__); | ||
509 | |||
510 | error = rmi_spi_xfer(phys, txbuf, sizeof(txbuf), NULL, 0); | ||
511 | if (error < 0) { | ||
512 | dev_err(phys->dev, "Failed to set page select, code: %d.\n", | ||
513 | error); | ||
514 | return error; | ||
515 | } | ||
516 | |||
517 | data->page = page; | ||
518 | |||
519 | return RMI_SPI_PAGE_SELECT_WRITE_LENGTH; | ||
520 | } | ||
521 | |||
522 | |||
523 | static int acquire_attn_irq(struct rmi_spi_data *data) | ||
524 | { | ||
525 | int retval = 0; | ||
526 | pr_info("in function ____%s____ \n", __func__); | ||
527 | pr_info(" irq = %d\n", data->irq); | ||
528 | pr_info(" rmi_spi_hard_irq = 0x%8x\n", rmi_spi_hard_irq); | ||
529 | pr_info(" rmi_spi_irq_thread = 0x%8x\n", rmi_spi_irq_thread); | ||
530 | pr_info(" data->irq_flags = 0x%8x\n", data->irq_flags); | ||
531 | pr_info(" dev_name(data->phys->dev) = %s\n", dev_name(data->phys->dev)); | ||
532 | pr_info(" data->phys = 0x%8x\n", data->phys); | ||
533 | |||
534 | retval = request_threaded_irq(data->irq, rmi_spi_hard_irq, | ||
535 | rmi_spi_irq_thread, data->irq_flags, | ||
536 | dev_name(data->phys->dev), data->phys); | ||
537 | |||
538 | pr_info(" retval = = %d\n", retval); | ||
539 | return retval; | ||
540 | } | ||
541 | |||
542 | static int enable_device(struct rmi_phys_device *phys) | ||
543 | { | ||
544 | int retval = 0; | ||
545 | |||
546 | struct rmi_spi_data *data = phys->data; | ||
547 | |||
548 | if (data->enabled) { | ||
549 | dev_info(phys->dev, "Physical device already enabled.\n"); | ||
550 | return 0; | ||
551 | } | ||
552 | |||
553 | retval = acquire_attn_irq(data); | ||
554 | if (retval) | ||
555 | goto error_exit; | ||
556 | |||
557 | data->enabled = true; | ||
558 | dev_info(phys->dev, "Physical device enabled.\n"); | ||
559 | return 0; | ||
560 | |||
561 | error_exit: | ||
562 | dev_err(phys->dev, "Failed to enable physical device. Code=%d.\n", | ||
563 | retval); | ||
564 | return retval; | ||
565 | } | ||
566 | |||
567 | |||
568 | static void disable_device(struct rmi_phys_device *phys) | ||
569 | { | ||
570 | struct rmi_spi_data *data = phys->data; | ||
571 | |||
572 | pr_info("in function ____%s____ \n", __func__); | ||
573 | if (!data->enabled) { | ||
574 | dev_warn(phys->dev, "Physical device already disabled.\n"); | ||
575 | return; | ||
576 | } | ||
577 | disable_irq(data->irq); | ||
578 | free_irq(data->irq, data->phys); | ||
579 | |||
580 | dev_info(phys->dev, "Physical device disabled.\n"); | ||
581 | data->enabled = false; | ||
582 | } | ||
583 | |||
584 | |||
585 | |||
586 | #define DUMMY_READ_SLEEP_US 10 | ||
587 | |||
588 | static int rmi_spi_check_device(struct rmi_phys_device *rmi_phys) | ||
589 | { | ||
590 | u8 buf[6]; | ||
591 | int error; | ||
592 | int i; | ||
593 | |||
594 | pr_info("in function ____%s____ \n", __func__); | ||
595 | |||
596 | /* Some SPI subsystems return 0 for the very first read you do. So | ||
597 | * we use this dummy read to get that out of the way. | ||
598 | */ | ||
599 | error = rmi_spi_v1_read_block(rmi_phys, PDT_START_SCAN_LOCATION, | ||
600 | buf, sizeof(buf)); | ||
601 | if (error < 0) { | ||
602 | dev_err(rmi_phys->dev, "dummy read failed with %d.\n", error); | ||
603 | return error; | ||
604 | } | ||
605 | udelay(DUMMY_READ_SLEEP_US); | ||
606 | |||
607 | /* Force page select to 0. | ||
608 | */ | ||
609 | error = rmi_spi_v1_set_page(rmi_phys, 0x00); | ||
610 | if (error < 0) | ||
611 | return error; | ||
612 | |||
613 | /* Now read the first PDT entry. We know where this is, and if the | ||
614 | * RMI4 device is out there, these 6 bytes will be something other | ||
615 | * than all 0x00 or 0xFF. We need to check for 0x00 and 0xFF, | ||
616 | * because many (maybe all) SPI implementations will return all 0x00 | ||
617 | * or all 0xFF on read if the device is not connected. | ||
618 | */ | ||
619 | error = rmi_spi_v1_read_block(rmi_phys, PDT_START_SCAN_LOCATION, | ||
620 | buf, sizeof(buf)); | ||
621 | if (error < 0) { | ||
622 | dev_err(rmi_phys->dev, "probe read failed with %d.\n", error); | ||
623 | return error; | ||
624 | } | ||
625 | |||
626 | dev_info(rmi_phys->dev, "probe read succeeded with %d.\n", error); | ||
627 | for (i = 0; i < sizeof(buf); i++) { | ||
628 | if (buf[i] != 0x00 && buf[i] != 0xFF) | ||
629 | return error; | ||
630 | } | ||
631 | |||
632 | dev_err(rmi_phys->dev, "probe read returned invalid block.\n"); | ||
633 | return -ENODEV; | ||
634 | } | ||
635 | |||
636 | static int __devinit rmi_spi_probe(struct spi_device *spi) | ||
637 | { | ||
638 | struct rmi_phys_device *rmi_phys; | ||
639 | struct rmi_spi_data *data; | ||
640 | struct rmi_device_platform_data *pdata = spi->dev.platform_data; | ||
641 | u8 buf[2]; | ||
642 | int error; | ||
643 | |||
644 | pr_info("%s: probe for rmi_spi device\n", __func__); | ||
645 | |||
646 | if (!pdata) { | ||
647 | dev_err(&spi->dev, "no platform data\n"); | ||
648 | return -EINVAL; | ||
649 | } | ||
650 | |||
651 | if (spi->master->flags & SPI_MASTER_HALF_DUPLEX) | ||
652 | return -EINVAL; | ||
653 | |||
654 | spi->bits_per_word = 8; | ||
655 | spi->mode = SPI_MODE_3; | ||
656 | error = spi_setup(spi); | ||
657 | if (error < 0) { | ||
658 | dev_err(&spi->dev, "spi_setup failed!\n"); | ||
659 | return error; | ||
660 | } | ||
661 | |||
662 | rmi_phys = kzalloc(sizeof(struct rmi_phys_device), GFP_KERNEL); | ||
663 | if (!rmi_phys) | ||
664 | return -ENOMEM; | ||
665 | |||
666 | data = kzalloc(sizeof(struct rmi_spi_data), GFP_KERNEL); | ||
667 | if (!data) { | ||
668 | error = -ENOMEM; | ||
669 | goto err_phys; | ||
670 | } | ||
671 | data->enabled = true; /* We plan to come up enabled. */ | ||
672 | data->irq = gpio_to_irq(pdata->irq); | ||
673 | data->irq_flags = (pdata->irq_polarity == RMI_IRQ_ACTIVE_HIGH) ? | ||
674 | IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING; | ||
675 | data->phys = rmi_phys; | ||
676 | |||
677 | rmi_phys->data = data; | ||
678 | rmi_phys->dev = &spi->dev; | ||
679 | |||
680 | rmi_phys->write = rmi_spi_v1_write; | ||
681 | rmi_phys->write_block = rmi_spi_v1_write_block; | ||
682 | rmi_phys->read = rmi_spi_v1_read; | ||
683 | rmi_phys->read_block = rmi_spi_v1_read_block; | ||
684 | rmi_phys->enable_device = enable_device; | ||
685 | rmi_phys->disable_device = disable_device; | ||
686 | data->set_page = rmi_spi_v1_set_page; | ||
687 | |||
688 | rmi_phys->info.proto = spi_v1_proto_name; | ||
689 | |||
690 | mutex_init(&data->page_mutex); | ||
691 | |||
692 | pr_info("%s: setting the driverdata on the device\n", __func__); | ||
693 | |||
694 | dev_set_drvdata(&spi->dev, rmi_phys); | ||
695 | |||
696 | pr_info("%s: done setting driverdata %s\n", __func__, dev_name(&spi->dev)); | ||
697 | |||
698 | |||
699 | pdata->spi_data.block_delay_us = pdata->spi_data.block_delay_us ? | ||
700 | pdata->spi_data.block_delay_us : RMI_SPI_BLOCK_DELAY_US; | ||
701 | pdata->spi_data.read_delay_us = pdata->spi_data.read_delay_us ? | ||
702 | pdata->spi_data.read_delay_us : RMI_SPI_BYTE_DELAY_US; | ||
703 | pdata->spi_data.write_delay_us = pdata->spi_data.write_delay_us ? | ||
704 | pdata->spi_data.write_delay_us : RMI_SPI_BYTE_DELAY_US; | ||
705 | pdata->spi_data.split_read_block_delay_us = | ||
706 | pdata->spi_data.split_read_block_delay_us ? | ||
707 | pdata->spi_data.split_read_block_delay_us : | ||
708 | RMI_SPI_BLOCK_DELAY_US; | ||
709 | pdata->spi_data.split_read_byte_delay_us = | ||
710 | pdata->spi_data.split_read_byte_delay_us ? | ||
711 | pdata->spi_data.split_read_byte_delay_us : | ||
712 | RMI_SPI_BYTE_DELAY_US; | ||
713 | |||
714 | pr_info("%s configuring GPIOs\n", __func__); | ||
715 | |||
716 | if (pdata->gpio_config) { | ||
717 | error = pdata->gpio_config(&spi->dev, true); | ||
718 | if (error < 0) { | ||
719 | dev_err(&spi->dev, "Failed to setup GPIOs, code: %d.\n", | ||
720 | error); | ||
721 | goto err_data; | ||
722 | } | ||
723 | } | ||
724 | |||
725 | error = rmi_spi_check_device(rmi_phys); | ||
726 | if (error < 0) | ||
727 | goto err_data; | ||
728 | |||
729 | /* check if this is an SPI v2 device */ | ||
730 | dev_info(&spi->dev, "%s: checking SPI version on RMI device\n", __func__); | ||
731 | error = rmi_spi_v1_read_block(rmi_phys, RMI_PROTOCOL_VERSION_ADDRESS, | ||
732 | buf, 2); | ||
733 | |||
734 | if (error < 0) { | ||
735 | dev_info(&spi->dev, "failed to get SPI version number!\n"); | ||
736 | dev_err(&spi->dev, "failed to get SPI version number!\n"); | ||
737 | goto err_data; | ||
738 | } | ||
739 | |||
740 | dev_info(&spi->dev, "SPI version is %d", buf[0]); | ||
741 | |||
742 | if (buf[0] == 1) { | ||
743 | /* SPIv2 */ | ||
744 | rmi_phys->write = rmi_spi_v2_write; | ||
745 | rmi_phys->write_block = rmi_spi_v2_write_block; | ||
746 | rmi_phys->read = rmi_spi_v2_read; | ||
747 | data->set_page = rmi_spi_v2_set_page; | ||
748 | |||
749 | rmi_phys->info.proto = spi_v2_proto_name; | ||
750 | |||
751 | if (pdata->irq > 0) { | ||
752 | init_completion(&data->irq_comp); | ||
753 | rmi_phys->read_block = rmi_spi_v2_split_read_block; | ||
754 | } else { | ||
755 | rmi_phys->read_block = rmi_spi_v2_read_block; | ||
756 | } | ||
757 | } else if (buf[0] != 0) { | ||
758 | dev_err(&spi->dev, "Unrecognized SPI version %d.\n", buf[0]); | ||
759 | error = -ENODEV; | ||
760 | goto err_data; | ||
761 | } | ||
762 | |||
763 | error = rmi_register_phys_device(rmi_phys); | ||
764 | if (error) { | ||
765 | dev_err(&spi->dev, "failed to register physical driver\n"); | ||
766 | goto err_data; | ||
767 | } | ||
768 | |||
769 | if (pdata->irq > 0) { | ||
770 | error = acquire_attn_irq(data); | ||
771 | if (error < 0) { | ||
772 | dev_err(&spi->dev, "request_threaded_irq failed %d\n", | ||
773 | pdata->irq); | ||
774 | goto err_unregister; | ||
775 | } | ||
776 | } | ||
777 | |||
778 | #if defined(CONFIG_RMI4_DEV) | ||
779 | pr_info(" CONFIG_RMI4_DEV is defined\n"); | ||
780 | |||
781 | error = gpio_export(pdata->irq, false); | ||
782 | if (error) { | ||
783 | dev_warn(&spi->dev, "WARNING: Failed to export ATTN gpio!\n"); | ||
784 | error = 0; | ||
785 | } else { | ||
786 | error = gpio_export_link(&(rmi_phys->rmi_dev->dev), "attn", | ||
787 | pdata->irq); | ||
788 | if (error) { | ||
789 | dev_warn(&(rmi_phys->rmi_dev->dev), "WARNING: " | ||
790 | "Failed to symlink ATTN gpio!\n"); | ||
791 | error = 0; | ||
792 | } else { | ||
793 | dev_info(&(rmi_phys->rmi_dev->dev), | ||
794 | "%s: Exported GPIO %d.", __func__, pdata->irq); | ||
795 | } | ||
796 | } | ||
797 | #endif /* CONFIG_RMI4_DEV */ | ||
798 | |||
799 | dev_info(&spi->dev, "registered RMI SPI driver\n"); | ||
800 | return 0; | ||
801 | |||
802 | err_unregister: | ||
803 | rmi_unregister_phys_device(rmi_phys); | ||
804 | err_data: | ||
805 | kfree(data); | ||
806 | err_phys: | ||
807 | kfree(rmi_phys); | ||
808 | return error; | ||
809 | } | ||
810 | |||
811 | static int __devexit rmi_spi_remove(struct spi_device *spi) | ||
812 | { | ||
813 | struct rmi_phys_device *phys = dev_get_drvdata(&spi->dev); | ||
814 | struct rmi_device_platform_data *pd = spi->dev.platform_data; | ||
815 | pr_info("in function ____%s____ \n", __func__); | ||
816 | |||
817 | rmi_unregister_phys_device(phys); | ||
818 | kfree(phys->data); | ||
819 | kfree(phys); | ||
820 | |||
821 | if (pd->gpio_config) | ||
822 | pd->gpio_config(&spi->dev, false); | ||
823 | |||
824 | return 0; | ||
825 | } | ||
826 | |||
827 | static const struct spi_device_id rmi_id[] = { | ||
828 | { "rmi", 0 }, | ||
829 | { "rmi_spi", 0 }, | ||
830 | { } | ||
831 | }; | ||
832 | MODULE_DEVICE_TABLE(spi, rmi_id); | ||
833 | |||
834 | static struct spi_driver rmi_spi_driver = { | ||
835 | .driver = { | ||
836 | .owner = THIS_MODULE, | ||
837 | .name = "rmi_spi", | ||
838 | //.mod_name = "rmi_spi", | ||
839 | //.bus = &spi_bus_type, | ||
840 | }, | ||
841 | .id_table = rmi_id, | ||
842 | .probe = rmi_spi_probe, | ||
843 | .remove = __devexit_p(rmi_spi_remove), | ||
844 | }; | ||
845 | |||
846 | static int __init rmi_spi_init(void) | ||
847 | { | ||
848 | pr_info("%s: registering synaptics spi driver (ref=124)\n", __func__); | ||
849 | pr_info(" driver.owner = 0x%x\n", (unsigned int)rmi_spi_driver.driver.owner); | ||
850 | pr_info(" driver.name = %s\n", rmi_spi_driver.driver.name); | ||
851 | pr_info(" id_table[0].name = %s\n", rmi_spi_driver.id_table[0].name ); | ||
852 | pr_info(" id_table[1].name = %s\n", rmi_spi_driver.id_table[1].name ); | ||
853 | pr_info(" probe function ptr = 0x%x\n", (unsigned int)rmi_spi_driver.probe ); | ||
854 | |||
855 | |||
856 | return spi_register_driver(&rmi_spi_driver); | ||
857 | } | ||
858 | |||
859 | static void __exit rmi_spi_exit(void) | ||
860 | { | ||
861 | spi_unregister_driver(&rmi_spi_driver); | ||
862 | } | ||
863 | |||
864 | MODULE_AUTHOR("Christopher Heiny <cheiny@synaptics.com>"); | ||
865 | MODULE_DESCRIPTION("RMI SPI driver"); | ||
866 | MODULE_LICENSE("GPL"); | ||
867 | |||
868 | module_init(rmi_spi_init); | ||
869 | module_exit(rmi_spi_exit); | ||
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi.c b/drivers/input/touchscreen/synaptics_i2c_rmi.c new file mode 100644 index 00000000000..6f9b83af035 --- /dev/null +++ b/drivers/input/touchscreen/synaptics_i2c_rmi.c | |||
@@ -0,0 +1,699 @@ | |||
1 | /* drivers/input/keyboard/synaptics_i2c_rmi.c | ||
2 | * | ||
3 | * Copyright (C) 2007 Google, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/earlysuspend.h> | ||
19 | #include <linux/hrtimer.h> | ||
20 | #include <linux/i2c.h> | ||
21 | #include <linux/input.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/synaptics_i2c_rmi.h> | ||
27 | |||
28 | #define ABS_DIFF(a, b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a))) | ||
29 | |||
30 | static struct workqueue_struct *synaptics_wq; | ||
31 | |||
32 | struct synaptics_ts_data { | ||
33 | uint16_t addr; | ||
34 | struct i2c_client *client; | ||
35 | struct input_dev *input_dev; | ||
36 | int use_irq; | ||
37 | bool has_relative_report; | ||
38 | struct hrtimer timer; | ||
39 | struct work_struct work; | ||
40 | uint16_t max[2]; | ||
41 | int snap_state[2][2]; | ||
42 | int snap_down_on[2]; | ||
43 | int snap_down_off[2]; | ||
44 | int snap_up_on[2]; | ||
45 | int snap_up_off[2]; | ||
46 | int snap_down[2]; | ||
47 | int snap_up[2]; | ||
48 | uint32_t flags; | ||
49 | int reported_finger_count; | ||
50 | int last_pos[2][2]; | ||
51 | int8_t sensitivity_adjust; | ||
52 | int (*power)(int on); | ||
53 | struct early_suspend early_suspend; | ||
54 | }; | ||
55 | |||
56 | #ifdef CONFIG_HAS_EARLYSUSPEND | ||
57 | static void synaptics_ts_early_suspend(struct early_suspend *h); | ||
58 | static void synaptics_ts_late_resume(struct early_suspend *h); | ||
59 | #endif | ||
60 | |||
61 | static int synaptics_init_panel(struct synaptics_ts_data *ts) | ||
62 | { | ||
63 | int ret; | ||
64 | |||
65 | ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x10); /* page select = 0x10 */ | ||
66 | if (ret < 0) { | ||
67 | printk(KERN_ERR "i2c_smbus_write_byte_data failed for page select\n"); | ||
68 | goto err_page_select_failed; | ||
69 | } | ||
70 | ret = i2c_smbus_write_byte_data(ts->client, 0x41, 0x04); /* Set "No Clip Z" */ | ||
71 | if (ret < 0) | ||
72 | printk(KERN_ERR "i2c_smbus_write_byte_data failed for No Clip Z\n"); | ||
73 | |||
74 | ret = i2c_smbus_write_byte_data(ts->client, 0x44, | ||
75 | ts->sensitivity_adjust); | ||
76 | if (ret < 0) | ||
77 | pr_err("synaptics_ts: failed to set Sensitivity Adjust\n"); | ||
78 | |||
79 | err_page_select_failed: | ||
80 | ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x04); /* page select = 0x04 */ | ||
81 | if (ret < 0) | ||
82 | printk(KERN_ERR "i2c_smbus_write_byte_data failed for page select\n"); | ||
83 | ret = i2c_smbus_write_byte_data(ts->client, 0xf0, 0x81); /* normal operation, 80 reports per second */ | ||
84 | if (ret < 0) | ||
85 | printk(KERN_ERR "synaptics_ts_resume: i2c_smbus_write_byte_data failed\n"); | ||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | static void synaptics_ts_work_func(struct work_struct *work) | ||
90 | { | ||
91 | int i; | ||
92 | int ret; | ||
93 | int bad_data = 0; | ||
94 | struct i2c_msg msg[2]; | ||
95 | uint8_t start_reg; | ||
96 | uint8_t buf[15]; | ||
97 | struct synaptics_ts_data *ts = container_of(work, struct synaptics_ts_data, work); | ||
98 | int buf_len = ts->has_relative_report ? 15 : 13; | ||
99 | |||
100 | msg[0].addr = ts->client->addr; | ||
101 | msg[0].flags = 0; | ||
102 | msg[0].len = 1; | ||
103 | msg[0].buf = &start_reg; | ||
104 | start_reg = 0x00; | ||
105 | msg[1].addr = ts->client->addr; | ||
106 | msg[1].flags = I2C_M_RD; | ||
107 | msg[1].len = buf_len; | ||
108 | msg[1].buf = buf; | ||
109 | |||
110 | /* printk("synaptics_ts_work_func\n"); */ | ||
111 | for (i = 0; i < ((ts->use_irq && !bad_data) ? 1 : 10); i++) { | ||
112 | ret = i2c_transfer(ts->client->adapter, msg, 2); | ||
113 | if (ret < 0) { | ||
114 | printk(KERN_ERR "synaptics_ts_work_func: i2c_transfer failed\n"); | ||
115 | bad_data = 1; | ||
116 | } else { | ||
117 | /* printk("synaptics_ts_work_func: %x %x %x %x %x %x" */ | ||
118 | /* " %x %x %x %x %x %x %x %x %x, ret %d\n", */ | ||
119 | /* buf[0], buf[1], buf[2], buf[3], */ | ||
120 | /* buf[4], buf[5], buf[6], buf[7], */ | ||
121 | /* buf[8], buf[9], buf[10], buf[11], */ | ||
122 | /* buf[12], buf[13], buf[14], ret); */ | ||
123 | if ((buf[buf_len - 1] & 0xc0) != 0x40) { | ||
124 | printk(KERN_WARNING "synaptics_ts_work_func:" | ||
125 | " bad read %x %x %x %x %x %x %x %x %x" | ||
126 | " %x %x %x %x %x %x, ret %d\n", | ||
127 | buf[0], buf[1], buf[2], buf[3], | ||
128 | buf[4], buf[5], buf[6], buf[7], | ||
129 | buf[8], buf[9], buf[10], buf[11], | ||
130 | buf[12], buf[13], buf[14], ret); | ||
131 | if (bad_data) | ||
132 | synaptics_init_panel(ts); | ||
133 | bad_data = 1; | ||
134 | continue; | ||
135 | } | ||
136 | bad_data = 0; | ||
137 | if ((buf[buf_len - 1] & 1) == 0) { | ||
138 | /* printk("read %d coordinates\n", i); */ | ||
139 | break; | ||
140 | } else { | ||
141 | int pos[2][2]; | ||
142 | int rmpos_x, rmpos_y; | ||
143 | int f, a; | ||
144 | int base; | ||
145 | /* int x = buf[3] | (uint16_t)(buf[2] & 0x1f) << 8; */ | ||
146 | /* int y = buf[5] | (uint16_t)(buf[4] & 0x1f) << 8; */ | ||
147 | int z = buf[1]; | ||
148 | int w = buf[0] >> 4; | ||
149 | int finger = buf[0] & 7; | ||
150 | |||
151 | /* int x2 = buf[3+6] | (uint16_t)(buf[2+6] & 0x1f) << 8; */ | ||
152 | /* int y2 = buf[5+6] | (uint16_t)(buf[4+6] & 0x1f) << 8; */ | ||
153 | /* int z2 = buf[1+6]; */ | ||
154 | /* int w2 = buf[0+6] >> 4; */ | ||
155 | /* int finger2 = buf[0+6] & 7; */ | ||
156 | |||
157 | /* int dx = (int8_t)buf[12]; */ | ||
158 | /* int dy = (int8_t)buf[13]; */ | ||
159 | int finger2_pressed; | ||
160 | |||
161 | /* printk("x %4d, y %4d, z %3d, w %2d, F %d, 2nd: x %4d, y %4d, z %3d, w %2d, F %d, dx %4d, dy %4d\n", */ | ||
162 | /* x, y, z, w, finger, */ | ||
163 | /* x2, y2, z2, w2, finger2, */ | ||
164 | /* dx, dy); */ | ||
165 | |||
166 | base = 2; | ||
167 | for (f = 0; f < 2; f++) { | ||
168 | uint32_t flip_flag = SYNAPTICS_FLIP_X; | ||
169 | for (a = 0; a < 2; a++) { | ||
170 | int p = buf[base + 1]; | ||
171 | p |= (uint16_t)(buf[base] & 0x1f) << 8; | ||
172 | if (ts->flags & flip_flag) | ||
173 | p = ts->max[a] - p; | ||
174 | if (ts->flags & SYNAPTICS_SNAP_TO_INACTIVE_EDGE) { | ||
175 | if (ts->snap_state[f][a]) { | ||
176 | if (p <= ts->snap_down_off[a]) | ||
177 | p = ts->snap_down[a]; | ||
178 | else if (p >= ts->snap_up_off[a]) | ||
179 | p = ts->snap_up[a]; | ||
180 | else | ||
181 | ts->snap_state[f][a] = 0; | ||
182 | } else { | ||
183 | if (p <= ts->snap_down_on[a]) { | ||
184 | p = ts->snap_down[a]; | ||
185 | ts->snap_state[f][a] = 1; | ||
186 | } else if (p >= ts->snap_up_on[a]) { | ||
187 | p = ts->snap_up[a]; | ||
188 | ts->snap_state[f][a] = 1; | ||
189 | } | ||
190 | } | ||
191 | } | ||
192 | pos[f][a] = p; | ||
193 | base += 2; | ||
194 | flip_flag <<= 1; | ||
195 | } | ||
196 | base += 2; | ||
197 | if (ts->flags & SYNAPTICS_SWAP_XY) | ||
198 | swap(pos[f][0], pos[f][1]); | ||
199 | } | ||
200 | |||
201 | if (!finger) { | ||
202 | z = 0; | ||
203 | if (ts->reported_finger_count > 0) { | ||
204 | pos[0][0] = ts->last_pos[0][0]; | ||
205 | pos[0][1] = ts->last_pos[0][1]; | ||
206 | } | ||
207 | else | ||
208 | continue; /* skip touch noise */ | ||
209 | } | ||
210 | finger = (finger == 7) ? 1 : finger; /* correct wrong finger count */ | ||
211 | finger2_pressed = finger > 1; | ||
212 | |||
213 | input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, z); | ||
214 | input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w); | ||
215 | input_report_abs(ts->input_dev, ABS_MT_POSITION_X, pos[0][0]); | ||
216 | input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, pos[0][1]); | ||
217 | input_mt_sync(ts->input_dev); | ||
218 | if (finger2_pressed) { | ||
219 | input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, z); | ||
220 | input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w); | ||
221 | input_report_abs(ts->input_dev, ABS_MT_POSITION_X, pos[1][0]); | ||
222 | input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, pos[1][1]); | ||
223 | input_mt_sync(ts->input_dev); | ||
224 | ts->last_pos[1][0] = pos[1][0]; | ||
225 | ts->last_pos[1][1] = pos[1][1]; | ||
226 | } else if (ts->reported_finger_count > 1) { | ||
227 | /* check which point was removed */ | ||
228 | if ((ABS_DIFF(pos[0][0],ts->last_pos[0][0]) + | ||
229 | ABS_DIFF(pos[0][1],ts->last_pos[0][1])) < | ||
230 | (ABS_DIFF(pos[0][0],ts->last_pos[1][0]) + | ||
231 | ABS_DIFF(pos[0][1],ts->last_pos[1][1]))) { | ||
232 | rmpos_x = ts->last_pos[1][0]; | ||
233 | rmpos_y = ts->last_pos[1][1]; | ||
234 | } | ||
235 | else { | ||
236 | rmpos_x = ts->last_pos[0][0]; | ||
237 | rmpos_y = ts->last_pos[0][1]; | ||
238 | } | ||
239 | input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); | ||
240 | input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0); | ||
241 | input_report_abs(ts->input_dev, ABS_MT_POSITION_X, rmpos_x); | ||
242 | input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, rmpos_y); | ||
243 | input_mt_sync(ts->input_dev); | ||
244 | } | ||
245 | |||
246 | if (z) { | ||
247 | input_report_abs(ts->input_dev, ABS_X, pos[0][0]); | ||
248 | input_report_abs(ts->input_dev, ABS_Y, pos[0][1]); | ||
249 | ts->last_pos[0][0] = pos[0][0]; | ||
250 | ts->last_pos[0][1] = pos[0][1]; | ||
251 | } | ||
252 | input_report_abs(ts->input_dev, ABS_PRESSURE, z); | ||
253 | input_report_abs(ts->input_dev, ABS_TOOL_WIDTH, w); | ||
254 | input_report_key(ts->input_dev, BTN_TOUCH, finger); | ||
255 | ts->reported_finger_count = finger; | ||
256 | input_sync(ts->input_dev); | ||
257 | } | ||
258 | } | ||
259 | } | ||
260 | if (ts->use_irq) | ||
261 | enable_irq(ts->client->irq); | ||
262 | } | ||
263 | |||
264 | static enum hrtimer_restart synaptics_ts_timer_func(struct hrtimer *timer) | ||
265 | { | ||
266 | struct synaptics_ts_data *ts = container_of(timer, struct synaptics_ts_data, timer); | ||
267 | /* printk("synaptics_ts_timer_func\n"); */ | ||
268 | |||
269 | queue_work(synaptics_wq, &ts->work); | ||
270 | |||
271 | hrtimer_start(&ts->timer, ktime_set(0, 12500000), HRTIMER_MODE_REL); | ||
272 | return HRTIMER_NORESTART; | ||
273 | } | ||
274 | |||
275 | static irqreturn_t synaptics_ts_irq_handler(int irq, void *dev_id) | ||
276 | { | ||
277 | struct synaptics_ts_data *ts = dev_id; | ||
278 | |||
279 | /* printk("synaptics_ts_irq_handler\n"); */ | ||
280 | disable_irq_nosync(ts->client->irq); | ||
281 | queue_work(synaptics_wq, &ts->work); | ||
282 | return IRQ_HANDLED; | ||
283 | } | ||
284 | |||
285 | static int synaptics_ts_probe( | ||
286 | struct i2c_client *client, const struct i2c_device_id *id) | ||
287 | { | ||
288 | struct synaptics_ts_data *ts; | ||
289 | uint8_t buf0[4]; | ||
290 | uint8_t buf1[8]; | ||
291 | struct i2c_msg msg[2]; | ||
292 | int ret = 0; | ||
293 | uint16_t max_x, max_y; | ||
294 | int fuzz_x, fuzz_y, fuzz_p, fuzz_w; | ||
295 | struct synaptics_i2c_rmi_platform_data *pdata; | ||
296 | unsigned long irqflags; | ||
297 | int inactive_area_left; | ||
298 | int inactive_area_right; | ||
299 | int inactive_area_top; | ||
300 | int inactive_area_bottom; | ||
301 | int snap_left_on; | ||
302 | int snap_left_off; | ||
303 | int snap_right_on; | ||
304 | int snap_right_off; | ||
305 | int snap_top_on; | ||
306 | int snap_top_off; | ||
307 | int snap_bottom_on; | ||
308 | int snap_bottom_off; | ||
309 | uint32_t panel_version; | ||
310 | |||
311 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | ||
312 | printk(KERN_ERR "synaptics_ts_probe: need I2C_FUNC_I2C\n"); | ||
313 | ret = -ENODEV; | ||
314 | goto err_check_functionality_failed; | ||
315 | } | ||
316 | |||
317 | ts = kzalloc(sizeof(*ts), GFP_KERNEL); | ||
318 | if (ts == NULL) { | ||
319 | ret = -ENOMEM; | ||
320 | goto err_alloc_data_failed; | ||
321 | } | ||
322 | INIT_WORK(&ts->work, synaptics_ts_work_func); | ||
323 | ts->client = client; | ||
324 | i2c_set_clientdata(client, ts); | ||
325 | pdata = client->dev.platform_data; | ||
326 | if (pdata) | ||
327 | ts->power = pdata->power; | ||
328 | if (ts->power) { | ||
329 | ret = ts->power(1); | ||
330 | if (ret < 0) { | ||
331 | printk(KERN_ERR "synaptics_ts_probe power on failed\n"); | ||
332 | goto err_power_failed; | ||
333 | } | ||
334 | } | ||
335 | |||
336 | ret = i2c_smbus_write_byte_data(ts->client, 0xf4, 0x01); /* device command = reset */ | ||
337 | if (ret < 0) { | ||
338 | printk(KERN_ERR "i2c_smbus_write_byte_data failed\n"); | ||
339 | /* fail? */ | ||
340 | } | ||
341 | { | ||
342 | int retry = 10; | ||
343 | while (retry-- > 0) { | ||
344 | ret = i2c_smbus_read_byte_data(ts->client, 0xe4); | ||
345 | if (ret >= 0) | ||
346 | break; | ||
347 | msleep(100); | ||
348 | } | ||
349 | } | ||
350 | if (ret < 0) { | ||
351 | printk(KERN_ERR "i2c_smbus_read_byte_data failed\n"); | ||
352 | goto err_detect_failed; | ||
353 | } | ||
354 | printk(KERN_INFO "synaptics_ts_probe: Product Major Version %x\n", ret); | ||
355 | panel_version = ret << 8; | ||
356 | ret = i2c_smbus_read_byte_data(ts->client, 0xe5); | ||
357 | if (ret < 0) { | ||
358 | printk(KERN_ERR "i2c_smbus_read_byte_data failed\n"); | ||
359 | goto err_detect_failed; | ||
360 | } | ||
361 | printk(KERN_INFO "synaptics_ts_probe: Product Minor Version %x\n", ret); | ||
362 | panel_version |= ret; | ||
363 | |||
364 | ret = i2c_smbus_read_byte_data(ts->client, 0xe3); | ||
365 | if (ret < 0) { | ||
366 | printk(KERN_ERR "i2c_smbus_read_byte_data failed\n"); | ||
367 | goto err_detect_failed; | ||
368 | } | ||
369 | printk(KERN_INFO "synaptics_ts_probe: product property %x\n", ret); | ||
370 | |||
371 | if (pdata) { | ||
372 | while (pdata->version > panel_version) | ||
373 | pdata++; | ||
374 | ts->flags = pdata->flags; | ||
375 | ts->sensitivity_adjust = pdata->sensitivity_adjust; | ||
376 | irqflags = pdata->irqflags; | ||
377 | inactive_area_left = pdata->inactive_left; | ||
378 | inactive_area_right = pdata->inactive_right; | ||
379 | inactive_area_top = pdata->inactive_top; | ||
380 | inactive_area_bottom = pdata->inactive_bottom; | ||
381 | snap_left_on = pdata->snap_left_on; | ||
382 | snap_left_off = pdata->snap_left_off; | ||
383 | snap_right_on = pdata->snap_right_on; | ||
384 | snap_right_off = pdata->snap_right_off; | ||
385 | snap_top_on = pdata->snap_top_on; | ||
386 | snap_top_off = pdata->snap_top_off; | ||
387 | snap_bottom_on = pdata->snap_bottom_on; | ||
388 | snap_bottom_off = pdata->snap_bottom_off; | ||
389 | fuzz_x = pdata->fuzz_x; | ||
390 | fuzz_y = pdata->fuzz_y; | ||
391 | fuzz_p = pdata->fuzz_p; | ||
392 | fuzz_w = pdata->fuzz_w; | ||
393 | } else { | ||
394 | irqflags = 0; | ||
395 | inactive_area_left = 0; | ||
396 | inactive_area_right = 0; | ||
397 | inactive_area_top = 0; | ||
398 | inactive_area_bottom = 0; | ||
399 | snap_left_on = 0; | ||
400 | snap_left_off = 0; | ||
401 | snap_right_on = 0; | ||
402 | snap_right_off = 0; | ||
403 | snap_top_on = 0; | ||
404 | snap_top_off = 0; | ||
405 | snap_bottom_on = 0; | ||
406 | snap_bottom_off = 0; | ||
407 | fuzz_x = 0; | ||
408 | fuzz_y = 0; | ||
409 | fuzz_p = 0; | ||
410 | fuzz_w = 0; | ||
411 | } | ||
412 | |||
413 | ret = i2c_smbus_read_byte_data(ts->client, 0xf0); | ||
414 | if (ret < 0) { | ||
415 | printk(KERN_ERR "i2c_smbus_read_byte_data failed\n"); | ||
416 | goto err_detect_failed; | ||
417 | } | ||
418 | printk(KERN_INFO "synaptics_ts_probe: device control %x\n", ret); | ||
419 | |||
420 | ret = i2c_smbus_read_byte_data(ts->client, 0xf1); | ||
421 | if (ret < 0) { | ||
422 | printk(KERN_ERR "i2c_smbus_read_byte_data failed\n"); | ||
423 | goto err_detect_failed; | ||
424 | } | ||
425 | printk(KERN_INFO "synaptics_ts_probe: interrupt enable %x\n", ret); | ||
426 | |||
427 | ret = i2c_smbus_write_byte_data(ts->client, 0xf1, 0); /* disable interrupt */ | ||
428 | if (ret < 0) { | ||
429 | printk(KERN_ERR "i2c_smbus_write_byte_data failed\n"); | ||
430 | goto err_detect_failed; | ||
431 | } | ||
432 | |||
433 | msg[0].addr = ts->client->addr; | ||
434 | msg[0].flags = 0; | ||
435 | msg[0].len = 1; | ||
436 | msg[0].buf = buf0; | ||
437 | buf0[0] = 0xe0; | ||
438 | msg[1].addr = ts->client->addr; | ||
439 | msg[1].flags = I2C_M_RD; | ||
440 | msg[1].len = 8; | ||
441 | msg[1].buf = buf1; | ||
442 | ret = i2c_transfer(ts->client->adapter, msg, 2); | ||
443 | if (ret < 0) { | ||
444 | printk(KERN_ERR "i2c_transfer failed\n"); | ||
445 | goto err_detect_failed; | ||
446 | } | ||
447 | printk(KERN_INFO "synaptics_ts_probe: 0xe0: %x %x %x %x %x %x %x %x\n", | ||
448 | buf1[0], buf1[1], buf1[2], buf1[3], | ||
449 | buf1[4], buf1[5], buf1[6], buf1[7]); | ||
450 | |||
451 | ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x10); /* page select = 0x10 */ | ||
452 | if (ret < 0) { | ||
453 | printk(KERN_ERR "i2c_smbus_write_byte_data failed for page select\n"); | ||
454 | goto err_detect_failed; | ||
455 | } | ||
456 | ret = i2c_smbus_read_word_data(ts->client, 0x02); | ||
457 | if (ret < 0) { | ||
458 | printk(KERN_ERR "i2c_smbus_read_word_data failed\n"); | ||
459 | goto err_detect_failed; | ||
460 | } | ||
461 | ts->has_relative_report = !(ret & 0x100); | ||
462 | printk(KERN_INFO "synaptics_ts_probe: Sensor properties %x\n", ret); | ||
463 | ret = i2c_smbus_read_word_data(ts->client, 0x04); | ||
464 | if (ret < 0) { | ||
465 | printk(KERN_ERR "i2c_smbus_read_word_data failed\n"); | ||
466 | goto err_detect_failed; | ||
467 | } | ||
468 | ts->max[0] = max_x = (ret >> 8 & 0xff) | ((ret & 0x1f) << 8); | ||
469 | ret = i2c_smbus_read_word_data(ts->client, 0x06); | ||
470 | if (ret < 0) { | ||
471 | printk(KERN_ERR "i2c_smbus_read_word_data failed\n"); | ||
472 | goto err_detect_failed; | ||
473 | } | ||
474 | ts->max[1] = max_y = (ret >> 8 & 0xff) | ((ret & 0x1f) << 8); | ||
475 | if (ts->flags & SYNAPTICS_SWAP_XY) | ||
476 | swap(max_x, max_y); | ||
477 | |||
478 | ret = synaptics_init_panel(ts); /* will also switch back to page 0x04 */ | ||
479 | if (ret < 0) { | ||
480 | printk(KERN_ERR "synaptics_init_panel failed\n"); | ||
481 | goto err_detect_failed; | ||
482 | } | ||
483 | |||
484 | ts->input_dev = input_allocate_device(); | ||
485 | if (ts->input_dev == NULL) { | ||
486 | ret = -ENOMEM; | ||
487 | printk(KERN_ERR "synaptics_ts_probe: Failed to allocate input device\n"); | ||
488 | goto err_input_dev_alloc_failed; | ||
489 | } | ||
490 | ts->input_dev->name = "synaptics-rmi-touchscreen"; | ||
491 | set_bit(EV_SYN, ts->input_dev->evbit); | ||
492 | set_bit(EV_KEY, ts->input_dev->evbit); | ||
493 | set_bit(BTN_TOUCH, ts->input_dev->keybit); | ||
494 | set_bit(EV_ABS, ts->input_dev->evbit); | ||
495 | inactive_area_left = inactive_area_left * max_x / 0x10000; | ||
496 | inactive_area_right = inactive_area_right * max_x / 0x10000; | ||
497 | inactive_area_top = inactive_area_top * max_y / 0x10000; | ||
498 | inactive_area_bottom = inactive_area_bottom * max_y / 0x10000; | ||
499 | snap_left_on = snap_left_on * max_x / 0x10000; | ||
500 | snap_left_off = snap_left_off * max_x / 0x10000; | ||
501 | snap_right_on = snap_right_on * max_x / 0x10000; | ||
502 | snap_right_off = snap_right_off * max_x / 0x10000; | ||
503 | snap_top_on = snap_top_on * max_y / 0x10000; | ||
504 | snap_top_off = snap_top_off * max_y / 0x10000; | ||
505 | snap_bottom_on = snap_bottom_on * max_y / 0x10000; | ||
506 | snap_bottom_off = snap_bottom_off * max_y / 0x10000; | ||
507 | fuzz_x = fuzz_x * max_x / 0x10000; | ||
508 | fuzz_y = fuzz_y * max_y / 0x10000; | ||
509 | ts->snap_down[!!(ts->flags & SYNAPTICS_SWAP_XY)] = -inactive_area_left; | ||
510 | ts->snap_up[!!(ts->flags & SYNAPTICS_SWAP_XY)] = max_x + inactive_area_right; | ||
511 | ts->snap_down[!(ts->flags & SYNAPTICS_SWAP_XY)] = -inactive_area_top; | ||
512 | ts->snap_up[!(ts->flags & SYNAPTICS_SWAP_XY)] = max_y + inactive_area_bottom; | ||
513 | ts->snap_down_on[!!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_left_on; | ||
514 | ts->snap_down_off[!!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_left_off; | ||
515 | ts->snap_up_on[!!(ts->flags & SYNAPTICS_SWAP_XY)] = max_x - snap_right_on; | ||
516 | ts->snap_up_off[!!(ts->flags & SYNAPTICS_SWAP_XY)] = max_x - snap_right_off; | ||
517 | ts->snap_down_on[!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_top_on; | ||
518 | ts->snap_down_off[!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_top_off; | ||
519 | ts->snap_up_on[!(ts->flags & SYNAPTICS_SWAP_XY)] = max_y - snap_bottom_on; | ||
520 | ts->snap_up_off[!(ts->flags & SYNAPTICS_SWAP_XY)] = max_y - snap_bottom_off; | ||
521 | printk(KERN_INFO "synaptics_ts_probe: max_x %d, max_y %d\n", max_x, max_y); | ||
522 | printk(KERN_INFO "synaptics_ts_probe: inactive_x %d %d, inactive_y %d %d\n", | ||
523 | inactive_area_left, inactive_area_right, | ||
524 | inactive_area_top, inactive_area_bottom); | ||
525 | printk(KERN_INFO "synaptics_ts_probe: snap_x %d-%d %d-%d, snap_y %d-%d %d-%d\n", | ||
526 | snap_left_on, snap_left_off, snap_right_on, snap_right_off, | ||
527 | snap_top_on, snap_top_off, snap_bottom_on, snap_bottom_off); | ||
528 | input_set_abs_params(ts->input_dev, ABS_X, -inactive_area_left, max_x + inactive_area_right, fuzz_x, 0); | ||
529 | input_set_abs_params(ts->input_dev, ABS_Y, -inactive_area_top, max_y + inactive_area_bottom, fuzz_y, 0); | ||
530 | input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, fuzz_p, 0); | ||
531 | input_set_abs_params(ts->input_dev, ABS_TOOL_WIDTH, 0, 15, fuzz_w, 0); | ||
532 | input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, -inactive_area_left, max_x + inactive_area_right, fuzz_x, 0); | ||
533 | input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, -inactive_area_top, max_y + inactive_area_bottom, fuzz_y, 0); | ||
534 | input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, fuzz_p, 0); | ||
535 | input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 15, fuzz_w, 0); | ||
536 | /* ts->input_dev->name = ts->keypad_info->name; */ | ||
537 | ret = input_register_device(ts->input_dev); | ||
538 | if (ret) { | ||
539 | printk(KERN_ERR "synaptics_ts_probe: Unable to register %s input device\n", ts->input_dev->name); | ||
540 | goto err_input_register_device_failed; | ||
541 | } | ||
542 | if (client->irq) { | ||
543 | ret = request_irq(client->irq, synaptics_ts_irq_handler, irqflags, client->name, ts); | ||
544 | if (ret == 0) { | ||
545 | ret = i2c_smbus_write_byte_data(ts->client, 0xf1, 0x01); /* enable abs int */ | ||
546 | if (ret) | ||
547 | free_irq(client->irq, ts); | ||
548 | } | ||
549 | if (ret == 0) | ||
550 | ts->use_irq = 1; | ||
551 | else | ||
552 | dev_err(&client->dev, "request_irq failed\n"); | ||
553 | } | ||
554 | if (!ts->use_irq) { | ||
555 | hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
556 | ts->timer.function = synaptics_ts_timer_func; | ||
557 | hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); | ||
558 | } | ||
559 | #ifdef CONFIG_HAS_EARLYSUSPEND | ||
560 | ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; | ||
561 | ts->early_suspend.suspend = synaptics_ts_early_suspend; | ||
562 | ts->early_suspend.resume = synaptics_ts_late_resume; | ||
563 | register_early_suspend(&ts->early_suspend); | ||
564 | #endif | ||
565 | |||
566 | printk(KERN_INFO "synaptics_ts_probe: Start touchscreen %s in %s mode\n", ts->input_dev->name, ts->use_irq ? "interrupt" : "polling"); | ||
567 | |||
568 | return 0; | ||
569 | |||
570 | err_input_register_device_failed: | ||
571 | input_free_device(ts->input_dev); | ||
572 | |||
573 | err_input_dev_alloc_failed: | ||
574 | err_detect_failed: | ||
575 | err_power_failed: | ||
576 | kfree(ts); | ||
577 | err_alloc_data_failed: | ||
578 | err_check_functionality_failed: | ||
579 | return ret; | ||
580 | } | ||
581 | |||
582 | static int synaptics_ts_remove(struct i2c_client *client) | ||
583 | { | ||
584 | struct synaptics_ts_data *ts = i2c_get_clientdata(client); | ||
585 | unregister_early_suspend(&ts->early_suspend); | ||
586 | if (ts->use_irq) | ||
587 | free_irq(client->irq, ts); | ||
588 | else | ||
589 | hrtimer_cancel(&ts->timer); | ||
590 | input_unregister_device(ts->input_dev); | ||
591 | kfree(ts); | ||
592 | return 0; | ||
593 | } | ||
594 | |||
595 | static int synaptics_ts_suspend(struct i2c_client *client, pm_message_t mesg) | ||
596 | { | ||
597 | int ret; | ||
598 | struct synaptics_ts_data *ts = i2c_get_clientdata(client); | ||
599 | |||
600 | if (ts->use_irq) | ||
601 | disable_irq(client->irq); | ||
602 | else | ||
603 | hrtimer_cancel(&ts->timer); | ||
604 | ret = cancel_work_sync(&ts->work); | ||
605 | if (ret && ts->use_irq) /* if work was pending disable-count is now 2 */ | ||
606 | enable_irq(client->irq); | ||
607 | ret = i2c_smbus_write_byte_data(ts->client, 0xf1, 0); /* disable interrupt */ | ||
608 | if (ret < 0) | ||
609 | printk(KERN_ERR "synaptics_ts_suspend: i2c_smbus_write_byte_data failed\n"); | ||
610 | |||
611 | ret = i2c_smbus_write_byte_data(client, 0xf0, 0x86); /* deep sleep */ | ||
612 | if (ret < 0) | ||
613 | printk(KERN_ERR "synaptics_ts_suspend: i2c_smbus_write_byte_data failed\n"); | ||
614 | if (ts->power) { | ||
615 | ret = ts->power(0); | ||
616 | if (ret < 0) | ||
617 | printk(KERN_ERR "synaptics_ts_resume power off failed\n"); | ||
618 | } | ||
619 | return 0; | ||
620 | } | ||
621 | |||
622 | static int synaptics_ts_resume(struct i2c_client *client) | ||
623 | { | ||
624 | int ret; | ||
625 | struct synaptics_ts_data *ts = i2c_get_clientdata(client); | ||
626 | |||
627 | if (ts->power) { | ||
628 | ret = ts->power(1); | ||
629 | if (ret < 0) | ||
630 | printk(KERN_ERR "synaptics_ts_resume power on failed\n"); | ||
631 | } | ||
632 | |||
633 | synaptics_init_panel(ts); | ||
634 | |||
635 | if (ts->use_irq) | ||
636 | enable_irq(client->irq); | ||
637 | |||
638 | if (!ts->use_irq) | ||
639 | hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); | ||
640 | else | ||
641 | i2c_smbus_write_byte_data(ts->client, 0xf1, 0x01); /* enable abs int */ | ||
642 | |||
643 | return 0; | ||
644 | } | ||
645 | |||
646 | #ifdef CONFIG_HAS_EARLYSUSPEND | ||
647 | static void synaptics_ts_early_suspend(struct early_suspend *h) | ||
648 | { | ||
649 | struct synaptics_ts_data *ts; | ||
650 | ts = container_of(h, struct synaptics_ts_data, early_suspend); | ||
651 | synaptics_ts_suspend(ts->client, PMSG_SUSPEND); | ||
652 | } | ||
653 | |||
654 | static void synaptics_ts_late_resume(struct early_suspend *h) | ||
655 | { | ||
656 | struct synaptics_ts_data *ts; | ||
657 | ts = container_of(h, struct synaptics_ts_data, early_suspend); | ||
658 | synaptics_ts_resume(ts->client); | ||
659 | } | ||
660 | #endif | ||
661 | |||
662 | static const struct i2c_device_id synaptics_ts_id[] = { | ||
663 | { SYNAPTICS_I2C_RMI_NAME, 0 }, | ||
664 | { } | ||
665 | }; | ||
666 | |||
667 | static struct i2c_driver synaptics_ts_driver = { | ||
668 | .probe = synaptics_ts_probe, | ||
669 | .remove = synaptics_ts_remove, | ||
670 | #ifndef CONFIG_HAS_EARLYSUSPEND | ||
671 | .suspend = synaptics_ts_suspend, | ||
672 | .resume = synaptics_ts_resume, | ||
673 | #endif | ||
674 | .id_table = synaptics_ts_id, | ||
675 | .driver = { | ||
676 | .name = SYNAPTICS_I2C_RMI_NAME, | ||
677 | }, | ||
678 | }; | ||
679 | |||
680 | static int __devinit synaptics_ts_init(void) | ||
681 | { | ||
682 | synaptics_wq = create_singlethread_workqueue("synaptics_wq"); | ||
683 | if (!synaptics_wq) | ||
684 | return -ENOMEM; | ||
685 | return i2c_add_driver(&synaptics_ts_driver); | ||
686 | } | ||
687 | |||
688 | static void __exit synaptics_ts_exit(void) | ||
689 | { | ||
690 | i2c_del_driver(&synaptics_ts_driver); | ||
691 | if (synaptics_wq) | ||
692 | destroy_workqueue(synaptics_wq); | ||
693 | } | ||
694 | |||
695 | module_init(synaptics_ts_init); | ||
696 | module_exit(synaptics_ts_exit); | ||
697 | |||
698 | MODULE_DESCRIPTION("Synaptics Touchscreen Driver"); | ||
699 | MODULE_LICENSE("GPL"); | ||