drm/prime: add return check for dma_buf_fd
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / sensors / sensors_core.c
1 /*
2  * Copyright (C) 2013 Samsung Electronics. All rights reserved.
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  * version 2 as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
16  * 02110-1301 USA
17  */
18
19 #include <linux/module.h>
20 #include <linux/types.h>
21 #include <linux/init.h>
22 #include <linux/device.h>
23 #include <linux/fs.h>
24 #include <linux/err.h>
25 #ifdef CONFIG_ADSP_FACTORY
26 #include <linux/kernel.h>
27 #endif
28
29 #ifdef CONFIG_SLEEP_MONITOR
30 #include <linux/power/sleep_monitor.h>
31 #include "sensors_core.h"
32 #endif
33
34 struct class *sensors_class;
35 struct class *sensors_event_class;
36 static struct device *symlink_dev;
37 static atomic_t sensor_count;
38
39 struct axis_remap {
40         int src_x:3;
41         int src_y:3;
42         int src_z:3;
43
44         int sign_x:2;
45         int sign_y:2;
46         int sign_z:2;
47 };
48
49 /*!
50  * @Description:
51  * definitions of placement of sensors
52  * P0 - P3: view from top of device
53  * P4 - P7: view from bottom of device
54  *
55  * P0 / P4:
56  * Y of device aligned with Y of OS (i.e: Android)
57  *                  y
58  *                  ^
59  *                  |
60  *                  |
61  *                  |
62  *                  o------> x
63  *
64  *
65  * P1 / P5:
66  * Y of device aligned with Y of OS (i.e.: Android)
67  * rotated by 90 degrees clockwise
68  *
69  *                  o------> y
70  *                  |
71  *                  |
72  *                  |
73  *                  v x
74  *
75  *
76  * P2 / P6:
77  * Y of device aligned with Y of OS (i.e.: Android)
78  * rotated by 180 degrees clockwise
79  *
80  *         x <------o
81  *                  |
82  *                  |
83  *                  |
84  *                  v
85  *                  y
86  *
87  *
88  * P3 / P7:
89  * Y of device aligned with Y of OS (i.e.: Android)
90  * rotated by 270 degrees clockwise
91  *
92  *                  x
93  *                  ^
94  *                  |
95  *                  |
96  *                  |
97  *         y <------o
98  *
99  */
100
101 #define MAX_AXIS_REMAP_TAB_SZ 8 /* P0~P7 */
102
103 static const struct axis_remap axis_table[MAX_AXIS_REMAP_TAB_SZ] = {
104         /* src_x src_y src_z  sign_x  sign_y  sign_z */
105         {  0,    1,    2,     1,      1,      1 }, /* P0 */
106         {  1,    0,    2,     1,     -1,      1 }, /* P1 */
107         {  0,    1,    2,    -1,     -1,      1 }, /* P2 */
108         {  1,    0,    2,    -1,      1,      1 }, /* P3 */
109         {  0,    1,    2,    -1,      1,     -1 }, /* P4 */
110         {  1,    0,    2,    -1,     -1,     -1 }, /* P5 */
111         {  0,    1,    2,     1,     -1,     -1 }, /* P6 */
112         {  1,    0,    2,     1,      1,     -1 }, /* P7 */
113 };
114
115 void remap_sensor_data(s16 *val, u32 idx)
116 {
117         s16 tmp[3];
118
119         if (idx < MAX_AXIS_REMAP_TAB_SZ) {
120                 tmp[0] = val[axis_table[idx].src_x] * axis_table[idx].sign_x;
121                 tmp[1] = val[axis_table[idx].src_y] * axis_table[idx].sign_y;
122                 tmp[2] = val[axis_table[idx].src_z] * axis_table[idx].sign_z;
123
124                 memcpy(val, &tmp, sizeof(tmp));
125         }
126 }
127
128 void remap_sensor_data_32(int *val, u32 idx)
129 {
130         int tmp[3];
131
132         if (idx < MAX_AXIS_REMAP_TAB_SZ) {
133                 tmp[0] = val[axis_table[idx].src_x] * axis_table[idx].sign_x;
134                 tmp[1] = val[axis_table[idx].src_y] * axis_table[idx].sign_y;
135                 tmp[2] = val[axis_table[idx].src_z] * axis_table[idx].sign_z;
136
137                 memcpy(val, &tmp, sizeof(tmp));
138         }
139 }
140
141 int sensors_create_symlink(struct kobject *target, const char *name)
142 {
143         int err = 0;
144
145         if (symlink_dev == NULL) {
146                 pr_err("%s, symlink_dev is NULL!!!\n", __func__);
147                 return err;
148         }
149
150         err = sysfs_create_link(&symlink_dev->kobj, target, name);
151         if (err < 0) {
152                 pr_err("%s, %s failed!(%d)\n", __func__, name, err);
153                 return err;
154         }
155
156         return err;
157 }
158
159 void sensors_remove_symlink(struct kobject *target, const char *name)
160 {
161         if (symlink_dev == NULL)
162                 pr_err("%s, symlink_dev is NULL!!!\n", __func__);
163         else
164                 sysfs_delete_link(&symlink_dev->kobj, target, name);
165 }
166
167 static void set_sensor_attr(struct device *dev,
168                 struct device_attribute *attributes[])
169 {
170         int i;
171
172         for (i = 0; attributes[i] != NULL; i++)
173                 if ((device_create_file(dev, attributes[i])) < 0)
174                         pr_err("[SENSOR CORE] fail device_create_file"\
175                                 "(dev, attributes[%d])\n", i);
176 }
177
178 int sensors_register(struct device *dev, void *drvdata,
179                 struct device_attribute *attributes[], char *name)
180 {
181         int ret = 0;
182
183         if (sensors_class == NULL) {
184                 sensors_class = class_create(THIS_MODULE, "sensors");
185                 if (IS_ERR(sensors_class))
186                         return PTR_ERR(sensors_class);
187         }
188
189         dev = device_create(sensors_class, NULL, 0, drvdata, "%s", name);
190         if (IS_ERR(dev)) {
191                 ret = PTR_ERR(dev);
192                 pr_err("[SENSORS CORE] device_create failed![%d]\n", ret);
193                 return ret;
194         }
195
196         set_sensor_attr(dev, attributes);
197         atomic_inc(&sensor_count);
198
199         return ret;
200 }
201
202 void sensors_unregister(struct device *dev,
203                 struct device_attribute *attributes[])
204 {
205         int i;
206
207         for (i = 0; attributes[i] != NULL; i++)
208                 device_remove_file(dev, attributes[i]);
209 }
210 #ifdef CONFIG_SLEEP_MONITOR
211 u8 sensors_enable_mask = 0;
212 void sensors_set_enable_mask(int enable, int offset_bit) {
213         if (enable)
214                 sensors_enable_mask = sensors_enable_mask | (enable << offset_bit);
215         else
216                 sensors_enable_mask = sensors_enable_mask & (~(0x01 << offset_bit));
217
218         pr_info("%s: enabled sensors mask = 0x%x", __func__, sensors_enable_mask);
219 }
220
221 static int sensors_get_sleep_monitor_cb(void *priv, unsigned int *raw_val, int check_level, int caller_type)
222 {
223         int ret = DEVICE_POWER_OFF;
224         * raw_val = sensors_enable_mask;
225
226         switch (check_level) {
227                 /* To Do*/
228                 case SLEEP_MONITOR_CHECK_SOFT:
229                 case SLEEP_MONITOR_CHECK_HARD:
230                 default:
231                         if (*raw_val == DEVICE_POWER_OFF_MASK)
232                                 ret = DEVICE_POWER_OFF;
233                         else if (*raw_val == DEVICE_ON_ACTIVE2_MASK)
234                                 ret = DEVICE_ON_ACTIVE2;
235                         else
236                                 ret = DEVICE_ON_ACTIVE2;
237                 break;
238         }
239         return ret;
240 }
241
242 static struct sleep_monitor_ops sensors_sleep_monitor_ops = {
243         .read_cb_func = sensors_get_sleep_monitor_cb,
244 };
245 #endif
246
247 void destroy_sensor_class(void)
248 {
249 #ifdef CONFIG_ADSP_FACTORY
250         if (sensors_class) {
251                 class_destroy(sensors_class);
252                 sensors_class = NULL;
253         }
254 #endif
255         if (sensors_event_class) {
256                 device_destroy(sensors_event_class, symlink_dev->devt);
257                 class_destroy(sensors_event_class);
258                 symlink_dev = NULL;
259                 sensors_event_class = NULL;
260         }
261 }
262
263 #ifdef CONFIG_ADSP_FACTORY
264
265 extern  struct class *get_adsp_sensor_class(void);
266 #endif
267
268 static int __init sensors_class_init(void)
269 {
270         pr_info("[SENSORS CORE] sensors_class_init\n");
271
272 #ifdef CONFIG_ADSP_FACTORY
273         sensors_class = get_adsp_sensor_class();
274 #else
275         sensors_class = class_create(THIS_MODULE, "sensors");
276         if (IS_ERR(sensors_class)) {
277                 pr_err("%s, create sensors_class is failed.(err=%ld)\n",
278                         __func__, IS_ERR(sensors_class));
279                 return PTR_ERR(sensors_class);
280         }
281 #endif
282         /* For symbolic link */
283         sensors_event_class = class_create(THIS_MODULE, "sensor_event");
284         if (IS_ERR(sensors_event_class)) {
285                 pr_err("%s, create sensors_class is failed.(err=%ld)\n",
286                         __func__, IS_ERR(sensors_event_class));
287                 class_destroy(sensors_class);
288                 return PTR_ERR(sensors_event_class);
289         }
290
291         symlink_dev = device_create(sensors_event_class, NULL, 0, NULL,
292                 "%s", "symlink");
293         if (IS_ERR(symlink_dev)) {
294                 pr_err("[SENSORS CORE] symlink_dev create failed![%ld]\n",
295                         IS_ERR(symlink_dev));
296
297                 class_destroy(sensors_class);
298                 class_destroy(sensors_event_class);
299                 return PTR_ERR(symlink_dev);
300         }
301
302         atomic_set(&sensor_count, 0);
303         sensors_class->dev_uevent = NULL;
304
305 #ifdef CONFIG_SLEEP_MONITOR
306         sleep_monitor_register_ops(NULL, &sensors_sleep_monitor_ops, SLEEP_MONITOR_SENSOR);
307 #endif
308         return 0;
309 }
310
311 static void __exit sensors_class_exit(void)
312 {
313         if (sensors_class || sensors_event_class) {
314                 class_destroy(sensors_class);
315                 sensors_class = NULL;
316                 class_destroy(sensors_event_class);
317                 sensors_event_class = NULL;
318         }
319 #ifdef CONFIG_SLEEP_MONITOR
320                 sleep_monitor_unregister_ops(SLEEP_MONITOR_SENSOR);
321 #endif
322 }
323
324 subsys_initcall(sensors_class_init);
325 module_exit(sensors_class_exit);
326
327 MODULE_DESCRIPTION("Universal sensors core class");
328 MODULE_AUTHOR("Samsung Electronics");
329 MODULE_LICENSE("GPL");