Commit | Line | Data |
---|---|---|
6fa3eb70 S |
1 | /* |
2 | * Copyright (c) 2010-2011 Yamaha Corporation | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or | |
5 | * modify it under the terms of the GNU General Public License | |
6 | * as published by the Free Software Foundation; either version 2 | |
7 | * of the License, or (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., 51 Franklin Street, Fifth Floor, Boston, | |
17 | * MA 02110-1301, USA. | |
18 | */ | |
19 | ||
20 | #include <linux/delay.h> | |
21 | #include <linux/errno.h> | |
22 | #include <linux/init.h> | |
23 | #include <linux/input.h> | |
24 | #include <linux/kernel.h> | |
25 | #include <linux/module.h> | |
26 | #include <linux/mutex.h> | |
27 | #include <linux/types.h> | |
28 | #include <linux/platform_device.h> | |
29 | #include <linux/slab.h> | |
30 | #include <linux/version.h> | |
31 | ||
32 | #include <linux/platform_device.h> | |
33 | #include <linux/hwmsensor.h> | |
34 | #include <linux/hwmsen_dev.h> | |
35 | #include <linux/sensors_io.h> | |
36 | ||
37 | ||
38 | #define MEDIATEK_CODE | |
39 | ||
40 | #ifdef MEDIATEK_CODE | |
41 | #include <linux/miscdevice.h> | |
42 | #include <linux/uaccess.h> | |
43 | #define OSENSOR 0x85 | |
44 | #define OSENSOR_IOCTL_READ_POSTUREDATA _IO(OSENSOR, 0x01) | |
45 | #endif | |
46 | ||
47 | /* for debugging */ | |
48 | #define DEBUG 0 | |
49 | #define SENSOR_NAME "orientation" | |
50 | #define SENSOR_TYPE (3) | |
51 | #define SENSOR_DEFAULT_DELAY (200) /* 200 ms */ | |
52 | #define SENSOR_MAX_DELAY (2000) /* 2000 ms */ | |
53 | #define ABS_STATUS (ABS_BRAKE) | |
54 | #define ABS_WAKE (ABS_MISC) | |
55 | #define ABS_CONTROL_REPORT (ABS_THROTTLE) | |
56 | ||
57 | static int suspend(void); | |
58 | static int resume(void); | |
59 | ||
60 | struct sensor_data { | |
61 | struct mutex mutex; | |
62 | int enabled; | |
63 | int delay; | |
64 | #if DEBUG | |
65 | int suspend; | |
66 | #endif | |
67 | }; | |
68 | #if DEBUG | |
69 | static struct platform_device *sensor_pdev = NULL; | |
70 | #endif | |
71 | static struct input_dev *this_data = NULL; | |
72 | ||
73 | static int | |
74 | suspend(void) | |
75 | { | |
76 | /* implement suspend of the sensor */ | |
77 | printk("%s: suspend\n", SENSOR_NAME); | |
78 | ||
79 | if (strcmp(SENSOR_NAME, "gyroscope") == 0) { | |
80 | /* suspend gyroscope */ | |
81 | } | |
82 | else if (strcmp(SENSOR_NAME, "light") == 0) { | |
83 | /* suspend light */ | |
84 | } | |
85 | else if (strcmp(SENSOR_NAME, "pressure") == 0) { | |
86 | /* suspend pressure */ | |
87 | } | |
88 | else if (strcmp(SENSOR_NAME, "temperature") == 0) { | |
89 | /* suspend temperature */ | |
90 | } | |
91 | else if (strcmp(SENSOR_NAME, "proximity") == 0) { | |
92 | /* suspend proximity */ | |
93 | } | |
94 | ||
95 | return 0; | |
96 | } | |
97 | ||
98 | static int | |
99 | resume(void) | |
100 | { | |
101 | /* implement resume of the sensor */ | |
102 | printk("%s: resume\n", SENSOR_NAME); | |
103 | ||
104 | if (strcmp(SENSOR_NAME, "gyroscope") == 0) { | |
105 | /* resume gyroscope */ | |
106 | } | |
107 | else if (strcmp(SENSOR_NAME, "light") == 0) { | |
108 | /* resume light */ | |
109 | } | |
110 | else if (strcmp(SENSOR_NAME, "pressure") == 0) { | |
111 | /* resume pressure */ | |
112 | } | |
113 | else if (strcmp(SENSOR_NAME, "temperature") == 0) { | |
114 | /* resume temperature */ | |
115 | } | |
116 | else if (strcmp(SENSOR_NAME, "proximity") == 0) { | |
117 | /* resume proximity */ | |
118 | } | |
119 | ||
120 | #if DEBUG | |
121 | { | |
122 | struct sensor_data *data = input_get_drvdata(this_data); | |
123 | data->suspend = 0; | |
124 | } | |
125 | #endif /* DEBUG */ | |
126 | ||
127 | return 0; | |
128 | } | |
129 | ||
130 | ||
131 | /* Sysfs interface */ | |
132 | static ssize_t | |
133 | sensor_delay_show(struct device *dev, | |
134 | struct device_attribute *attr, | |
135 | char *buf) | |
136 | { | |
137 | struct input_dev *input_data = to_input_dev(dev); | |
138 | struct sensor_data *data = input_get_drvdata(input_data); | |
139 | int delay; | |
140 | ||
141 | mutex_lock(&data->mutex); | |
142 | ||
143 | delay = data->delay; | |
144 | ||
145 | mutex_unlock(&data->mutex); | |
146 | ||
147 | return sprintf(buf, "%d\n", delay); | |
148 | } | |
149 | ||
150 | static ssize_t | |
151 | sensor_delay_store(struct device *dev, | |
152 | struct device_attribute *attr, | |
153 | const char *buf, | |
154 | size_t count) | |
155 | { | |
156 | struct input_dev *input_data = to_input_dev(dev); | |
157 | struct sensor_data *data = input_get_drvdata(input_data); | |
158 | int value = simple_strtol(buf, NULL, 10); | |
159 | ||
160 | if (value < 0) { | |
161 | return count; | |
162 | } | |
163 | ||
164 | if (SENSOR_MAX_DELAY < value) { | |
165 | value = SENSOR_MAX_DELAY; | |
166 | } | |
167 | ||
168 | mutex_lock(&data->mutex); | |
169 | ||
170 | data->delay = value; | |
171 | ||
172 | input_report_abs(input_data, ABS_CONTROL_REPORT, (data->enabled<<16) | value); | |
173 | input_sync(input_data); | |
174 | ||
175 | mutex_unlock(&data->mutex); | |
176 | ||
177 | return count; | |
178 | } | |
179 | ||
180 | static ssize_t | |
181 | sensor_enable_show(struct device *dev, | |
182 | struct device_attribute *attr, | |
183 | char *buf) | |
184 | { | |
185 | struct input_dev *input_data = to_input_dev(dev); | |
186 | struct sensor_data *data = input_get_drvdata(input_data); | |
187 | int enabled; | |
188 | ||
189 | mutex_lock(&data->mutex); | |
190 | ||
191 | enabled = data->enabled; | |
192 | ||
193 | mutex_unlock(&data->mutex); | |
194 | ||
195 | return sprintf(buf, "%d\n", enabled); | |
196 | } | |
197 | ||
198 | static ssize_t | |
199 | sensor_enable_store(struct device *dev, | |
200 | struct device_attribute *attr, | |
201 | const char *buf, | |
202 | size_t count) | |
203 | { | |
204 | struct input_dev *input_data = to_input_dev(dev); | |
205 | struct sensor_data *data = input_get_drvdata(input_data); | |
206 | int value = simple_strtol(buf, NULL, 10); | |
207 | ||
208 | value = !!value; | |
209 | ||
210 | mutex_lock(&data->mutex); | |
211 | ||
212 | input_report_abs(input_data, ABS_CONTROL_REPORT, (value<<16) | data->delay); | |
213 | input_sync(input_data); | |
214 | ||
215 | if (data->enabled && !value) { | |
216 | suspend(); | |
217 | } | |
218 | if (!data->enabled && value) { | |
219 | resume(); | |
220 | } | |
221 | data->enabled = value; | |
222 | ||
223 | mutex_unlock(&data->mutex); | |
224 | ||
225 | return count; | |
226 | } | |
227 | ||
228 | static ssize_t | |
229 | sensor_wake_store(struct device *dev, | |
230 | struct device_attribute *attr, | |
231 | const char *buf, | |
232 | size_t count) | |
233 | { | |
234 | struct input_dev *input_data = to_input_dev(dev); | |
235 | static int cnt = 1; | |
236 | ||
237 | input_report_abs(input_data, ABS_WAKE, cnt++); | |
238 | input_sync(input_data); | |
239 | ||
240 | return count; | |
241 | } | |
242 | ||
243 | #if DEBUG | |
244 | ||
245 | static int sensor_suspend(struct platform_device *pdev, pm_message_t state); | |
246 | static int sensor_resume(struct platform_device *pdev); | |
247 | ||
248 | static ssize_t | |
249 | sensor_debug_suspend_show(struct device *dev, | |
250 | struct device_attribute *attr, char *buf) | |
251 | { | |
252 | struct input_dev *input = to_input_dev(dev); | |
253 | struct sensor_data *data = input_get_drvdata(input); | |
254 | ||
255 | return sprintf(buf, "%d\n", data->suspend); | |
256 | } | |
257 | ||
258 | static ssize_t | |
259 | sensor_debug_suspend_store(struct device *dev, | |
260 | struct device_attribute *attr, | |
261 | const char *buf, size_t count) | |
262 | { | |
263 | unsigned long suspend = simple_strtol(buf, NULL, 10); | |
264 | ||
265 | if (suspend) { | |
266 | pm_message_t msg; | |
267 | memset(&msg, 0, sizeof(msg)); | |
268 | sensor_suspend(sensor_pdev, msg); | |
269 | } else { | |
270 | sensor_resume(sensor_pdev); | |
271 | } | |
272 | ||
273 | return count; | |
274 | } | |
275 | ||
276 | #endif /* DEBUG */ | |
277 | ||
278 | static ssize_t | |
279 | sensor_data_show(struct device *dev, | |
280 | struct device_attribute *attr, | |
281 | char *buf) | |
282 | { | |
283 | struct input_dev *input_data = to_input_dev(dev); | |
284 | #if SENSOR_TYPE <= 4 | |
285 | int x, y, z; | |
286 | #else | |
287 | int x; | |
288 | #endif | |
289 | ||
290 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) | |
291 | unsigned long flags; | |
292 | ||
293 | spin_lock_irqsave(&input_data->event_lock, flags); | |
294 | ||
295 | x = input_data->abs[ABS_X]; | |
296 | #if SENSOR_TYPE <= 4 | |
297 | y = input_data->abs[ABS_Y]; | |
298 | z = input_data->abs[ABS_Z]; | |
299 | #endif | |
300 | spin_unlock_irqrestore(&input_data->event_lock, flags); | |
301 | #else | |
302 | x = input_abs_get_val(input_data, ABS_X); | |
303 | #if SENSOR_TYPE <= 4 | |
304 | y = input_abs_get_val(input_data, ABS_Y); | |
305 | z = input_abs_get_val(input_data, ABS_Z); | |
306 | #endif | |
307 | #endif | |
308 | ||
309 | ||
310 | #if SENSOR_TYPE <= 4 | |
311 | return sprintf(buf, "%d %d %d\n", x, y, z); | |
312 | #else | |
313 | return sprintf(buf, "%d\n", x); | |
314 | #endif | |
315 | } | |
316 | ||
317 | static ssize_t | |
318 | sensor_status_show(struct device *dev, | |
319 | struct device_attribute *attr, | |
320 | char *buf) | |
321 | { | |
322 | struct input_dev *input_data = to_input_dev(dev); | |
323 | int status; | |
324 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) | |
325 | unsigned long flags; | |
326 | ||
327 | spin_lock_irqsave(&input_data->event_lock, flags); | |
328 | ||
329 | status = input_data->abs[ABS_STATUS]; | |
330 | ||
331 | spin_unlock_irqrestore(&input_data->event_lock, flags); | |
332 | #else | |
333 | status = input_abs_get_val(input_data, ABS_STATUS); | |
334 | #endif | |
335 | ||
336 | return sprintf(buf, "%d\n", status); | |
337 | } | |
338 | ||
339 | static DEVICE_ATTR(delay, S_IRUGO|S_IWUSR|S_IWGRP, | |
340 | sensor_delay_show, sensor_delay_store); | |
341 | static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR|S_IWGRP, | |
342 | sensor_enable_show, sensor_enable_store); | |
343 | static DEVICE_ATTR(wake, S_IWUSR|S_IWGRP, | |
344 | NULL, sensor_wake_store); | |
345 | static DEVICE_ATTR(data, S_IRUGO, sensor_data_show, NULL); | |
346 | static DEVICE_ATTR(status, S_IRUGO, sensor_status_show, NULL); | |
347 | ||
348 | #if DEBUG | |
349 | static DEVICE_ATTR(debug_suspend, S_IRUGO|S_IWUSR, | |
350 | sensor_debug_suspend_show, sensor_debug_suspend_store); | |
351 | #endif /* DEBUG */ | |
352 | ||
353 | static struct attribute *sensor_attributes[] = { | |
354 | &dev_attr_delay.attr, | |
355 | &dev_attr_enable.attr, | |
356 | &dev_attr_wake.attr, | |
357 | &dev_attr_data.attr, | |
358 | &dev_attr_status.attr, | |
359 | #if DEBUG | |
360 | &dev_attr_debug_suspend.attr, | |
361 | #endif /* DEBUG */ | |
362 | NULL | |
363 | }; | |
364 | ||
365 | static struct attribute_group sensor_attribute_group = { | |
366 | .attrs = sensor_attributes | |
367 | }; | |
368 | ||
369 | static int | |
370 | sensor_suspend(struct platform_device *pdev, pm_message_t state) | |
371 | { | |
372 | struct sensor_data *data = input_get_drvdata(this_data); | |
373 | int rt = 0; | |
374 | ||
375 | mutex_lock(&data->mutex); | |
376 | ||
377 | if (data->enabled) { | |
378 | input_report_abs(this_data, ABS_CONTROL_REPORT, (0<<16) | data->delay); | |
379 | input_sync(this_data); | |
380 | rt = suspend(); | |
381 | } | |
382 | ||
383 | mutex_unlock(&data->mutex); | |
384 | ||
385 | return rt; | |
386 | } | |
387 | ||
388 | static int | |
389 | sensor_resume(struct platform_device *pdev) | |
390 | { | |
391 | struct sensor_data *data = input_get_drvdata(this_data); | |
392 | int rt = 0; | |
393 | ||
394 | mutex_lock(&data->mutex); | |
395 | ||
396 | if (data->enabled) { | |
397 | rt = resume(); | |
398 | input_report_abs(this_data, ABS_CONTROL_REPORT, (1<<16) | data->delay); | |
399 | input_sync(this_data); | |
400 | } | |
401 | ||
402 | mutex_unlock(&data->mutex); | |
403 | ||
404 | return rt; | |
405 | } | |
406 | ||
407 | #ifdef MEDIATEK_CODE | |
408 | ||
409 | #define OSENSOR 0x85 | |
410 | #define OSENSOR_IOCTL_READ_POSTUREDATA _IO(OSENSOR, 0x01) | |
411 | /* | |
412 | static int | |
413 | ioctl_read_sensordata(unsigned long args) | |
414 | { | |
415 | struct input_dev *input_data = this_data; | |
416 | int buf[4], *p; | |
417 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) | |
418 | unsigned long flags; | |
419 | ||
420 | spin_lock_irqsave(&input_data->event_lock, flags); | |
421 | ||
422 | buf[0] = input_data->abs[ABS_X] / 1000; | |
423 | buf[1] = input_data->abs[ABS_Y] / 1000; | |
424 | buf[2] = input_data->abs[ABS_Z] / 1000; | |
425 | buf[3] = input_data->abs[ABS_STATUS]; | |
426 | ||
427 | spin_unlock_irqrestore(&input_data->event_lock, flags); | |
428 | #else | |
429 | buf[0] = input_abs_get_val(input_data, ABS_X) / 1000; | |
430 | buf[1] = input_abs_get_val(input_data, ABS_Y) / 1000; | |
431 | buf[2] = input_abs_get_val(input_data, ABS_Z) / 1000; | |
432 | buf[3] = input_abs_get_val(input_data, ABS_STATUS); | |
433 | #endif | |
434 | ||
435 | p = (int*) args; | |
436 | if (copy_to_user(p, buf, sizeof(buf))) { | |
437 | return -EFAULT; | |
438 | } | |
439 | ||
440 | return 0; | |
441 | } | |
442 | ||
443 | */ | |
444 | int | |
445 | sensor_get_delay(void) | |
446 | { | |
447 | struct sensor_data *data = input_get_drvdata(this_data); | |
448 | int delay; | |
449 | ||
450 | mutex_lock(&data->mutex); | |
451 | ||
452 | delay = data->delay; | |
453 | ||
454 | mutex_unlock(&data->mutex); | |
455 | ||
456 | return delay; | |
457 | } | |
458 | EXPORT_SYMBOL(sensor_get_delay); | |
459 | ||
460 | int | |
461 | sensor_set_delay(int msec) | |
462 | { | |
463 | struct sensor_data *data = input_get_drvdata(this_data); | |
464 | ||
465 | if (msec < 0) { | |
466 | return -1; | |
467 | } | |
468 | if (SENSOR_MAX_DELAY < msec) { | |
469 | msec = SENSOR_MAX_DELAY; | |
470 | } | |
471 | ||
472 | mutex_lock(&data->mutex); | |
473 | ||
474 | data->delay = msec; | |
475 | input_report_abs(this_data, ABS_CONTROL_REPORT, (data->enabled<<16) | msec); | |
476 | input_sync(this_data); | |
477 | ||
478 | mutex_unlock(&data->mutex); | |
479 | ||
480 | return 0; | |
481 | } | |
482 | EXPORT_SYMBOL(sensor_set_delay); | |
483 | ||
484 | int | |
485 | sensor_get_enable(void) | |
486 | { | |
487 | struct sensor_data *data = input_get_drvdata(this_data); | |
488 | int enabled; | |
489 | ||
490 | mutex_lock(&data->mutex); | |
491 | ||
492 | enabled = data->enabled; | |
493 | ||
494 | mutex_unlock(&data->mutex); | |
495 | ||
496 | return enabled; | |
497 | } | |
498 | EXPORT_SYMBOL(sensor_get_enable); | |
499 | ||
500 | int | |
501 | sensor_set_enable(int enable) | |
502 | { | |
503 | struct sensor_data *data = input_get_drvdata(this_data); | |
504 | ||
505 | enable = !!enable; | |
506 | ||
507 | mutex_lock(&data->mutex); | |
508 | ||
509 | if (data->enabled && !enable) { | |
510 | suspend(); | |
511 | } | |
512 | if (!data->enabled && enable) { | |
513 | resume(); | |
514 | } | |
515 | data->enabled = enable; | |
516 | ||
517 | input_report_abs(this_data, ABS_CONTROL_REPORT, (enable<<16) | data->delay); | |
518 | input_sync(this_data); | |
519 | ||
520 | mutex_unlock(&data->mutex); | |
521 | ||
522 | return 0; | |
523 | } | |
524 | EXPORT_SYMBOL(sensor_set_enable); | |
525 | ||
526 | #endif | |
527 | /*----------------------------------------------------------------------------*/ | |
528 | //for data statable | |
529 | static int oldvalue[3]; | |
530 | ||
531 | /*----------------------------------------------------------------------------*/ | |
532 | int yamaha530_orientation_operate(void* self, uint32_t command, void* buff_in, int size_in, | |
533 | void* buff_out, int size_out, int* actualout) | |
534 | { | |
535 | int err = 0; | |
536 | int value, sample_delay; | |
537 | // int status; | |
538 | hwm_sensor_data* osensor_data; | |
539 | // unsigned long flags; | |
540 | struct input_dev *input_data = this_data; | |
541 | ||
542 | ||
543 | printk("yamaha530_orientation_operate!\n"); | |
544 | switch (command) | |
545 | { | |
546 | case SENSOR_DELAY: | |
547 | if((buff_in == NULL) || (size_in < sizeof(int))) | |
548 | { | |
549 | printk("Set delay parameter error!\n"); | |
550 | err = -EINVAL; | |
551 | } | |
552 | else | |
553 | { | |
554 | value = *(int *)buff_in; | |
555 | if(value <= 20) | |
556 | { | |
557 | sample_delay = 20; | |
558 | } | |
559 | ||
560 | ||
561 | sensor_set_delay(sample_delay); | |
562 | } | |
563 | break; | |
564 | ||
565 | case SENSOR_ENABLE: | |
566 | if((buff_in == NULL) || (size_in < sizeof(int))) | |
567 | { | |
568 | printk("Enable sensor parameter error!\n"); | |
569 | err = -EINVAL; | |
570 | } | |
571 | else | |
572 | { | |
573 | value = *(int *)buff_in; | |
574 | sensor_set_enable(value); | |
575 | // Do nothing | |
576 | } | |
577 | break; | |
578 | ||
579 | case SENSOR_GET_DATA: | |
580 | if((buff_out == NULL) || (size_out< sizeof(hwm_sensor_data))) | |
581 | { | |
582 | printk("get sensor data parameter error!\n"); | |
583 | err = -EINVAL; | |
584 | } | |
585 | else | |
586 | { | |
587 | osensor_data = (hwm_sensor_data *)buff_out; | |
588 | ||
589 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) | |
590 | spin_lock_irqsave(&input_data->event_lock, flags); | |
591 | ||
592 | osensor_data->values[0] = input_data->abs[ABS_X]; | |
593 | osensor_data->values[1] = input_data->abs[ABS_Y]; | |
594 | osensor_data->values[2] = input_data->abs[ABS_Z]; | |
595 | osensor_data->status = input_data->abs[ABS_STATUS]; | |
596 | ||
597 | spin_unlock_irqrestore(&input_data->event_lock, flags); | |
598 | #else | |
599 | ||
600 | osensor_data->values[0] = input_abs_get_val(input_data, ABS_X); | |
601 | osensor_data->values[1] = input_abs_get_val(input_data, ABS_Y); | |
602 | osensor_data->values[2] = input_abs_get_val(input_data, ABS_Z); | |
603 | ||
604 | ||
605 | if((abs(osensor_data->values[0] - oldvalue[0]))<=5000){ | |
606 | osensor_data->values[0] = oldvalue[0]; | |
607 | }else if((abs(osensor_data->values[1] - oldvalue[1]))<=5000){ | |
608 | osensor_data->values[1] = oldvalue[1]; | |
609 | }else if((abs(osensor_data->values[2] - oldvalue[2]))<=5000){ | |
610 | osensor_data->values[2] = oldvalue[2]; | |
611 | } | |
612 | ||
613 | oldvalue[0] = osensor_data->values[0]; | |
614 | oldvalue[1] = osensor_data->values[1]; | |
615 | oldvalue[2] = osensor_data->values[2]; | |
616 | ||
617 | //osensor_data->values[3] = input_abs_get_val(input_data, ABS_STATUS); | |
618 | osensor_data->status = input_abs_get_val(input_data, ABS_STATUS); | |
619 | //printk("yucong debug O sensor: %d,%d,%d\n",osensor_data->values[0],osensor_data->values[1],osensor_data->values[2]); | |
620 | #endif | |
621 | ||
622 | osensor_data->value_divide = 1000; | |
623 | } | |
624 | ||
625 | break; | |
626 | default: | |
627 | printk("orientation operate function no this parameter %d!\n", command); | |
628 | err = -1; | |
629 | break; | |
630 | } | |
631 | ||
632 | return err; | |
633 | ||
634 | } | |
635 | ||
636 | ||
637 | static int | |
638 | sensor_probe(struct platform_device *pdev) | |
639 | { | |
640 | struct sensor_data *data = NULL; | |
641 | struct input_dev *input_data = NULL; | |
642 | int input_registered = 0, sysfs_created = 0; | |
643 | int rt; | |
644 | ||
645 | struct hwmsen_object sobj; | |
646 | #ifdef MEDIATEK_CODE | |
647 | // int misc_registered = 0; | |
648 | #endif | |
649 | //printk("yucong debug tag orientation sensor probe!func"); | |
650 | data = kzalloc(sizeof(struct sensor_data), GFP_KERNEL); | |
651 | if (!data) { | |
652 | rt = -ENOMEM; | |
653 | goto err; | |
654 | } | |
655 | data->enabled = 0; | |
656 | data->delay = SENSOR_DEFAULT_DELAY; | |
657 | ||
658 | input_data = input_allocate_device(); | |
659 | if (!input_data) { | |
660 | rt = -ENOMEM; | |
661 | printk(KERN_ERR | |
662 | "sensor_probe: Failed to allocate input_data device\n"); | |
663 | goto err; | |
664 | } | |
665 | ||
666 | set_bit(EV_ABS, input_data->evbit); | |
667 | input_set_abs_params(input_data, ABS_X, 0x80000000, 0x7fffffff, 0, 0); | |
668 | #if SENSOR_TYPE <= 4 | |
669 | input_set_abs_params(input_data, ABS_Y, 0x80000000, 0x7fffffff, 0, 0); | |
670 | input_set_abs_params(input_data, ABS_Z, 0x80000000, 0x7fffffff, 0, 0); | |
671 | #endif | |
672 | input_set_abs_params(input_data, ABS_RUDDER, 0x80000000, 0x7fffffff, 0, 0); | |
673 | input_set_abs_params(input_data, ABS_STATUS, 0, 3, 0, 0); | |
674 | input_set_abs_params(input_data, ABS_WAKE, 0x80000000, 0x7fffffff, 0, 0); | |
675 | input_set_abs_params(input_data, ABS_CONTROL_REPORT, 0x80000000, 0x7fffffff, 0, 0); | |
676 | input_data->name = SENSOR_NAME; | |
677 | ||
678 | rt = input_register_device(input_data); | |
679 | if (rt) { | |
680 | printk(KERN_ERR | |
681 | "sensor_probe: Unable to register input_data device: %s\n", | |
682 | input_data->name); | |
683 | goto err; | |
684 | } | |
685 | input_set_drvdata(input_data, data); | |
686 | input_registered = 1; | |
687 | ||
688 | rt = sysfs_create_group(&input_data->dev.kobj, | |
689 | &sensor_attribute_group); | |
690 | if (rt) { | |
691 | printk(KERN_ERR | |
692 | "sensor_probe: sysfs_create_group failed[%s]\n", | |
693 | input_data->name); | |
694 | goto err; | |
695 | } | |
696 | sysfs_created = 1; | |
697 | mutex_init(&data->mutex); | |
698 | this_data = input_data; | |
699 | ||
700 | sobj.self = data; | |
701 | sobj.polling = 1; | |
702 | sobj.sensor_operate = yamaha530_orientation_operate; | |
703 | if((rt = hwmsen_attach(ID_ORIENTATION, &sobj))) | |
704 | { | |
705 | printk("attach fail = %d\n", rt); | |
706 | goto err; | |
707 | } | |
708 | ||
709 | mutex_init(&data->mutex); | |
710 | this_data = input_data; | |
711 | ||
712 | return 0; | |
713 | ||
714 | err: | |
715 | if (data != NULL) { | |
716 | if (input_data != NULL) { | |
717 | if (sysfs_created) { | |
718 | sysfs_remove_group(&input_data->dev.kobj, | |
719 | &sensor_attribute_group); | |
720 | } | |
721 | if (input_registered) { | |
722 | input_unregister_device(input_data); | |
723 | } | |
724 | else { | |
725 | input_free_device(input_data); | |
726 | } | |
727 | input_data = NULL; | |
728 | } | |
729 | kfree(data); | |
730 | } | |
731 | ||
732 | return rt; | |
733 | } | |
734 | ||
735 | static int | |
736 | sensor_remove(struct platform_device *pdev) | |
737 | { | |
738 | struct sensor_data *data; | |
739 | ||
740 | if (this_data != NULL) { | |
741 | data = input_get_drvdata(this_data); | |
742 | sysfs_remove_group(&this_data->dev.kobj, | |
743 | &sensor_attribute_group); | |
744 | input_unregister_device(this_data); | |
745 | if (data != NULL) { | |
746 | kfree(data); | |
747 | } | |
748 | } | |
749 | ||
750 | return 0; | |
751 | } | |
752 | ||
753 | ||
754 | /* | |
755 | * Module init and exit | |
756 | */ | |
757 | static struct platform_driver sensor_driver = { | |
758 | .probe = sensor_probe, | |
759 | .remove = sensor_remove, | |
760 | .suspend = sensor_suspend, | |
761 | .resume = sensor_resume, | |
762 | .driver = { | |
763 | .name = SENSOR_NAME, | |
764 | .owner = THIS_MODULE, | |
765 | }, | |
766 | }; | |
767 | ||
768 | static int __init sensor_init(void) | |
769 | { | |
770 | ||
771 | if(platform_driver_register(&sensor_driver)) | |
772 | { | |
773 | printk("failed to register driver"); | |
774 | return -ENODEV; | |
775 | } | |
776 | return 0; | |
777 | } | |
778 | module_init(sensor_init); | |
779 | ||
780 | static void __exit sensor_exit(void) | |
781 | { | |
782 | platform_driver_unregister(&sensor_driver); | |
783 | } | |
784 | ||
785 | module_exit(sensor_exit); | |
786 | ||
787 | ||
788 | MODULE_AUTHOR("Yamaha Corporation"); | |
789 | MODULE_LICENSE( "GPL" ); | |
790 | MODULE_VERSION("3.1.410"); | |
791 |