import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / magnetometer / yamaha530 / orientation.c
CommitLineData
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
57static int suspend(void);
58static int resume(void);
59
60struct sensor_data {
61 struct mutex mutex;
62 int enabled;
63 int delay;
64#if DEBUG
65 int suspend;
66#endif
67};
68#if DEBUG
69static struct platform_device *sensor_pdev = NULL;
70#endif
71static struct input_dev *this_data = NULL;
72
73static int
74suspend(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
98static int
99resume(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 */
132static ssize_t
133sensor_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
150static ssize_t
151sensor_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
180static ssize_t
181sensor_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
198static ssize_t
199sensor_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
228static ssize_t
229sensor_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
245static int sensor_suspend(struct platform_device *pdev, pm_message_t state);
246static int sensor_resume(struct platform_device *pdev);
247
248static ssize_t
249sensor_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
258static ssize_t
259sensor_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
278static ssize_t
279sensor_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
317static ssize_t
318sensor_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
339static DEVICE_ATTR(delay, S_IRUGO|S_IWUSR|S_IWGRP,
340 sensor_delay_show, sensor_delay_store);
341static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR|S_IWGRP,
342 sensor_enable_show, sensor_enable_store);
343static DEVICE_ATTR(wake, S_IWUSR|S_IWGRP,
344 NULL, sensor_wake_store);
345static DEVICE_ATTR(data, S_IRUGO, sensor_data_show, NULL);
346static DEVICE_ATTR(status, S_IRUGO, sensor_status_show, NULL);
347
348#if DEBUG
349static DEVICE_ATTR(debug_suspend, S_IRUGO|S_IWUSR,
350 sensor_debug_suspend_show, sensor_debug_suspend_store);
351#endif /* DEBUG */
352
353static 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
365static struct attribute_group sensor_attribute_group = {
366 .attrs = sensor_attributes
367};
368
369static int
370sensor_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
388static int
389sensor_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/*
412static int
413ioctl_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*/
444int
445sensor_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}
458EXPORT_SYMBOL(sensor_get_delay);
459
460int
461sensor_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}
482EXPORT_SYMBOL(sensor_set_delay);
483
484int
485sensor_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}
498EXPORT_SYMBOL(sensor_get_enable);
499
500int
501sensor_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}
524EXPORT_SYMBOL(sensor_set_enable);
525
526#endif
527/*----------------------------------------------------------------------------*/
528//for data statable
529static int oldvalue[3];
530
531/*----------------------------------------------------------------------------*/
532int 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
637static int
638sensor_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
714err:
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
735static int
736sensor_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 */
757static 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
768static 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}
778module_init(sensor_init);
779
780static void __exit sensor_exit(void)
781{
782 platform_driver_unregister(&sensor_driver);
783}
784
785module_exit(sensor_exit);
786
787
788MODULE_AUTHOR("Yamaha Corporation");
789MODULE_LICENSE( "GPL" );
790MODULE_VERSION("3.1.410");
791