1 #define pr_fmt(fmt) "["KBUILD_MODNAME"]" fmt
2 #include <linux/printk.h>
3 #include <linux/init.h>
4 #include <linux/module.h>
5 #include <linux/kernel.h>
6 #include <linux/input.h>
7 #include <linux/workqueue.h>
8 #include <linux/timer.h>
9 #include <linux/interrupt.h>
11 #include <linux/miscdevice.h>
12 #include <linux/platform_device.h>
13 #include <linux/earlysuspend.h>
14 #include <linux/slab.h>
16 #include <linux/device.h>
17 #include <linux/errno.h>
18 #include <asm/atomic.h>
19 #include <asm/uaccess.h>
20 #include <linux/input/mt.h>
21 #include <linux/version.h>
22 #include <linux/slab.h>
24 #define UIBC_TAG "UIBC:"
25 #define MAX_POINTERS 5
27 #define idVal(_x) (_x * 3 + 1)
28 #define xVal(_x) (_x * 3 + 2)
29 #define yVal(_x) (_x * 3 + 3)
31 extern unsigned int DISP_GetScreenHeight(void);
32 extern unsigned int DISP_GetScreenWidth(void);
34 static unsigned short uibc_keycode
[256] = {
53 static unsigned short uibc_keycode_chars
[256] = {
96 #define UIBC_KBD_NAME "uibc"
97 #define UIBC_KEY_PRESS 1
98 #define UIBC_KEY_RELEASE 0
99 #define UIBC_KEY_RESERVE 2
100 #define UIBC_POINTER_X 3
101 #define UIBC_POINTER_Y 4
102 #define UIBC_KEYBOARD 5
104 #define UIBC_TOUCH_DOWN 7
105 #define UIBC_TOUCH_UP 8
106 #define UIBC_TOUCH_MOVE 9
107 #define UIBC_KEYBOARD_MIRACAST 10
109 #define UIBC_MOUSE_INDEX 0
110 #define UIBC_GAMEPAD_INDEX 151
113 static struct input_dev
*uibc_input_dev
;
115 struct uibckeyboard
{
116 struct input_dev
*input
;
117 unsigned short keymap
[ARRAY_SIZE(uibc_keycode
)];
120 struct uibckeyboard
*uibckbd
;
121 int uibc_registered
= 0;
124 static long uibc_compat_kbd_dev_ioctl(struct file
*pfile
, unsigned int cmd
, unsigned long arg
) {
127 if (!pfile
->f_op
|| !pfile
->f_op
->unlocked_ioctl
) {
128 pr_debug("uibc_compat_kbd_dev_ioctl null pointer");
134 case UIBC_KEYBOARD_MIRACAST
:
136 case UIBC_KEY_RELEASE
:
139 case UIBC_TOUCH_DOWN
:
141 case UIBC_TOUCH_MOVE
: {
142 ret
= pfile
->f_op
->unlocked_ioctl(pfile
, cmd
, (unsigned long)compat_ptr(arg
));
152 static long uibc_kbd_dev_ioctl(struct file
* file
, unsigned int cmd
, unsigned long arg
) {
153 void __user
*uarg
= (void __user
*)arg
;
157 short touchPosition
[16];
160 pr_debug("uibc_kbd_dev_ioctl,cmd=%d\n", cmd
);
162 case UIBC_KEYBOARD
: {
163 uibc_input_dev
->keycodemax
= ARRAY_SIZE(uibc_keycode
);
164 for (i
= 0; i
< ARRAY_SIZE(uibckbd
->keymap
); i
++)
165 __set_bit(uibckbd
->keymap
[i
], uibc_input_dev
->keybit
);
166 err
= input_register_device(uibc_input_dev
);
168 pr_err("register input device failed (%d)\n", err
);
169 input_free_device(uibc_input_dev
);
175 case UIBC_KEYBOARD_MIRACAST
: {
176 uibc_input_dev
->keycodemax
= ARRAY_SIZE(uibc_keycode_chars
);
177 for (i
= 0; i
< ARRAY_SIZE(uibc_keycode_chars
); i
++)
178 __set_bit(uibc_keycode_chars
[i
], uibc_input_dev
->keybit
);
179 err
= input_register_device(uibc_input_dev
);
181 pr_err("register input device failed (%d)\n", err
);
182 input_free_device(uibc_input_dev
);
188 case UIBC_KEY_PRESS
: {
189 if (copy_from_user(&keycode
, uarg
, sizeof(keycode
)))
191 pr_debug("uibc keycode %d\n", keycode
);
192 input_report_key(uibc_input_dev
, keycode
, 1);
193 input_sync(uibc_input_dev
);
196 case UIBC_KEY_RELEASE
: {
197 if (copy_from_user(&keycode
, uarg
, sizeof(keycode
)))
199 input_report_key(uibc_input_dev
, keycode
, 0);
200 input_sync(uibc_input_dev
);
203 case UIBC_POINTER_X
: {
204 if (copy_from_user(&XValue
, uarg
, sizeof(XValue
)))
206 pr_debug("uibc pointer X %d\n", XValue
);
209 case UIBC_POINTER_Y
: {
210 if (copy_from_user(&YValue
, uarg
, sizeof(YValue
)))
212 pr_debug("uibc pointer Y %d\n", YValue
);
213 input_report_rel(uibc_input_dev
, REL_X
, XValue
);
214 input_report_rel(uibc_input_dev
, REL_Y
, YValue
);
215 input_sync(uibc_input_dev
);
220 case UIBC_TOUCH_DOWN
: {
221 if (copy_from_user(&touchPosition
, uarg
, sizeof(touchPosition
)))
223 pr_debug("uibc UIBC_TOUCH_DOWN id=%d,(%d,%d)\n",
224 touchPosition
[idVal(0)],
225 touchPosition
[xVal(0)], touchPosition
[yVal(0)]);
226 input_report_key(uibc_input_dev
, BTN_TOUCH
, 1);
227 input_report_abs(uibc_input_dev
,
228 ABS_MT_TRACKING_ID
, touchPosition
[idVal(0)]);
229 input_report_abs(uibc_input_dev
, ABS_MT_POSITION_X
, touchPosition
[xVal(0)]);
230 input_report_abs(uibc_input_dev
, ABS_MT_POSITION_Y
, touchPosition
[yVal(0)]);
231 input_mt_sync(uibc_input_dev
);
232 input_sync(uibc_input_dev
);
235 case UIBC_TOUCH_UP
: {
236 if (copy_from_user(&touchPosition
, uarg
, sizeof(touchPosition
)))
238 pr_debug("uibc UIBC_TOUCH_UP");
239 input_report_key(uibc_input_dev
, BTN_TOUCH
, 0);
240 input_sync(uibc_input_dev
);
243 case UIBC_TOUCH_MOVE
: {
244 if (copy_from_user(&touchPosition
, uarg
, sizeof(touchPosition
)))
246 for (i
= 0; i
< MAX_POINTERS
; i
++) {
247 if (touchPosition
[xVal(i
)] == 0 && touchPosition
[yVal(i
)] == 0)
249 input_report_abs(uibc_input_dev
,
250 ABS_MT_TRACKING_ID
, touchPosition
[idVal(i
)]);
251 input_report_abs(uibc_input_dev
,
252 ABS_MT_POSITION_X
, touchPosition
[xVal(i
)]);
253 input_report_abs(uibc_input_dev
,
254 ABS_MT_POSITION_Y
, touchPosition
[yVal(i
)]);
255 input_mt_sync(uibc_input_dev
);
257 input_sync(uibc_input_dev
);
266 static int uibc_kbd_dev_open(struct inode
* inode
, struct file
* file
) {
267 int TPD_RES_X
, TPD_RES_Y
;
269 pr_debug("*** uibckeyboard uibc_kbd_dev_open ***\n");
272 TPD_RES_Y
= DISP_GetScreenWidth();
273 TPD_RES_X
= DISP_GetScreenHeight();
275 TPD_RES_X
= DISP_GetScreenWidth();
276 TPD_RES_Y
= DISP_GetScreenHeight();
279 uibckbd
= kzalloc(sizeof(struct uibckeyboard
), GFP_KERNEL
);
280 uibc_input_dev
= input_allocate_device();
281 if (!uibckbd
|| !uibc_input_dev
)
284 memcpy(uibckbd
->keymap
, uibc_keycode
, sizeof(uibc_keycode
));
285 uibckbd
->input
= uibc_input_dev
;
287 set_bit(INPUT_PROP_DIRECT
, uibc_input_dev
->propbit
);
289 set_bit(EV_ABS
, uibc_input_dev
->evbit
);
290 set_bit(EV_KEY
, uibc_input_dev
->evbit
);
291 set_bit(EV_REL
, uibc_input_dev
->evbit
);
293 set_bit(REL_X
, uibc_input_dev
->relbit
);
294 set_bit(REL_Y
, uibc_input_dev
->relbit
);
296 set_bit(ABS_X
, uibc_input_dev
->absbit
);
297 set_bit(ABS_Y
, uibc_input_dev
->absbit
);
298 set_bit(ABS_MT_TRACKING_ID
, uibc_input_dev
->absbit
);
299 set_bit(ABS_MT_POSITION_X
, uibc_input_dev
->absbit
);
300 set_bit(ABS_MT_POSITION_Y
, uibc_input_dev
->absbit
);
302 input_set_abs_params(uibc_input_dev
, ABS_MT_POSITION_X
, 0, TPD_RES_X
, 0, 0);
303 input_set_abs_params(uibc_input_dev
, ABS_MT_POSITION_Y
, 0, TPD_RES_Y
, 0, 0);
304 input_set_abs_params(uibc_input_dev
, ABS_X
, 0, TPD_RES_X
, 0, 0);
305 input_set_abs_params(uibc_input_dev
, ABS_Y
, 0, TPD_RES_Y
, 0, 0);
307 input_abs_set_res(uibc_input_dev
, ABS_X
, TPD_RES_X
);
308 input_abs_set_res(uibc_input_dev
, ABS_Y
, TPD_RES_Y
);
310 uibc_input_dev
->name
= UIBC_KBD_NAME
;
311 uibc_input_dev
->keycode
= uibckbd
->keymap
;
312 uibc_input_dev
->keycodesize
= sizeof(unsigned short);
313 uibc_input_dev
->id
.bustype
= BUS_HOST
;
317 input_free_device(uibc_input_dev
);
323 static int uibc_kbd_dev_release(struct inode
* inode
, struct file
* file
) {
324 pr_debug("*** uibckeyboard uibc_kbd_dev_release ***\n");
325 if (uibc_registered
== 1) {
326 input_unregister_device(uibc_input_dev
);
333 static struct file_operations uibc_kbd_dev_fops
= {
334 .owner
= THIS_MODULE
,
335 .unlocked_ioctl
= uibc_kbd_dev_ioctl
,
337 .compat_ioctl
= uibc_compat_kbd_dev_ioctl
,
339 .open
= uibc_kbd_dev_open
,
340 .release
= uibc_kbd_dev_release
343 static struct miscdevice uibc_kbd_dev
= {
344 .minor
= MISC_DYNAMIC_MINOR
,
345 .name
= UIBC_KBD_NAME
,
346 .fops
= &uibc_kbd_dev_fops
,
350 static int uibc_keyboard_probe(struct platform_device
* pdev
) {
354 pr_debug("*** uibckeyboard probe ***\n");
356 uibckbd
= kzalloc(sizeof(struct uibckeyboard
), GFP_KERNEL
);
357 uibc_input_dev
= input_allocate_device();
358 if (!uibckbd
|| !uibc_input_dev
)
361 memcpy(uibckbd
->keymap
, uibc_keycode
, sizeof(uibc_keycode
));
362 uibckbd
->input
= uibc_input_dev
;
363 __set_bit(EV_KEY
, uibc_input_dev
->evbit
);
364 platform_set_drvdata(pdev
, uibckbd
);
366 uibc_input_dev
->name
= UIBC_KBD_NAME
;
367 uibc_input_dev
->keycode
= uibckbd
->keymap
;
368 uibc_input_dev
->keycodesize
= sizeof(unsigned short);
369 uibc_input_dev
->keycodemax
= ARRAY_SIZE(uibc_keycode
);
370 uibc_input_dev
->id
.bustype
= BUS_HOST
;
371 uibc_input_dev
->dev
.parent
= &pdev
->dev
;
374 for (i
= 0; i
< ARRAY_SIZE(uibckbd
->keymap
); i
++)
375 __set_bit(uibckbd
->keymap
[i
], uibc_input_dev
->keybit
);
377 input_set_capability(uibc_input_dev
, EV_MSC
, MSC_SCAN
);
379 uibc_kbd_dev
.parent
= &pdev
->dev
;
380 err
= misc_register(&uibc_kbd_dev
);
382 pr_err("register device failed (%d)\n", err
);
389 platform_set_drvdata(pdev
, NULL
);
390 input_free_device(uibc_input_dev
);
396 static const struct of_device_id uibc_of_ids
[] = {
397 { .compatible
= "mediatek,uibc", },
401 static struct platform_driver uibc_keyboard_driver
= {
402 .probe
= uibc_keyboard_probe
,
404 .name
= UIBC_KBD_NAME
,
405 .of_match_table
= uibc_of_ids
,
410 static int uibc_keyboard_init(void) {
411 pr_debug("uibc_keyboard_init OK\n");
413 return platform_driver_register(&uibc_keyboard_driver
);
417 static void __exit
uibc_keyboard_exit(void) {
419 module_init(uibc_keyboard_init
);
420 module_exit(uibc_keyboard_exit
);
422 MODULE_DESCRIPTION("uibc keyboard Device");
423 MODULE_LICENSE("GPL");