input: sensors: fromdos and remove trailing whitespace
[firefly-linux-kernel-4.4.55.git] / drivers / input / sensors / compass / ak09911.c
1 /* drivers/input/sensors/access/akm09911.c
2  *
3  * Copyright (C) 2012-2015 ROCKCHIP.
4  * Author: luowei <lw@rock-chips.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 #include <linux/interrupt.h>
17 #include <linux/i2c.h>
18 #include <linux/slab.h>
19 #include <linux/irq.h>
20 #include <linux/miscdevice.h>
21 #include <linux/gpio.h>
22 #include <asm/uaccess.h>
23 #include <asm/atomic.h>
24 #include <linux/delay.h>
25 #include <linux/input.h>
26 #include <linux/workqueue.h>
27 #include <linux/freezer.h>
28 #include <linux/of_gpio.h>
29 #ifdef CONFIG_HAS_EARLYSUSPEND
30 #include <linux/earlysuspend.h>
31 #endif
32 #include <linux/sensor-dev.h>
33
34
35
36 #define SENSOR_DATA_SIZE        9
37 #define YPR_DATA_SIZE           16
38 #define RWBUF_SIZE              16
39
40 #define ACC_DATA_FLAG           0
41 #define MAG_DATA_FLAG           1
42 #define ORI_DATA_FLAG           2
43 #define AKM_NUM_SENSORS         3
44
45 #define ACC_DATA_READY          (1<<(ACC_DATA_FLAG))
46 #define MAG_DATA_READY          (1<<(MAG_DATA_FLAG))
47 #define ORI_DATA_READY          (1<<(ORI_DATA_FLAG))
48
49 /*Constant definitions of the AK09911.*/
50 #define AK09911_MEASUREMENT_TIME_US     10000
51
52 #define AK09911_MODE_SNG_MEASURE        0x01
53 #define AK09911_MODE_SELF_TEST          0x10
54 #define AK09911_MODE_FUSE_ACCESS        0x1F
55 #define AK09911_MODE_POWERDOWN          0x00
56 #define AK09911_RESET_DATA              0x01
57
58
59 /* Device specific constant values */
60 #define AK09911_REG_WIA1                        0x00
61 #define AK09911_REG_WIA2                        0x01
62 #define AK09911_REG_INFO1                       0x02
63 #define AK09911_REG_INFO2                       0x03
64 #define AK09911_REG_ST1                         0x10
65 #define AK09911_REG_HXL                         0x11
66 #define AK09911_REG_HXH                         0x12
67 #define AK09911_REG_HYL                         0x13
68 #define AK09911_REG_HYH                         0x14
69 #define AK09911_REG_HZL                         0x15
70 #define AK09911_REG_HZH                         0x16
71 #define AK09911_REG_TMPS                        0x17
72 #define AK09911_REG_ST2                         0x18
73 #define AK09911_REG_CNTL1                       0x30
74 #define AK09911_REG_CNTL2                       0x31
75 #define AK09911_REG_CNTL3                       0x32
76
77
78 #define AK09911_FUSE_ASAX                       0x60
79 #define AK09911_FUSE_ASAY                       0x61
80 #define AK09911_FUSE_ASAZ                       0x62
81
82 #define AK09911_INFO_SIZE                       2
83 #define AK09911_CONF_SIZE                       3
84
85
86
87 #define COMPASS_IOCTL_MAGIC                   'c'
88
89 /* IOCTLs for AKM library */
90 #define ECS_IOCTL_WRITE                 _IOW(COMPASS_IOCTL_MAGIC, 0x01, char*)
91 #define ECS_IOCTL_READ                  _IOWR(COMPASS_IOCTL_MAGIC, 0x02, char*)
92 #define ECS_IOCTL_RESET                 _IO(COMPASS_IOCTL_MAGIC, 0x03) /* NOT used in AK8975 */
93 #define ECS_IOCTL_SET_MODE              _IOW(COMPASS_IOCTL_MAGIC, 0x04, short)
94 #define ECS_IOCTL_GETDATA               _IOR(COMPASS_IOCTL_MAGIC, 0x05, char[8])
95 #define ECS_IOCTL_SET_YPR               _IOW(COMPASS_IOCTL_MAGIC, 0x06, short[12])
96 #define ECS_IOCTL_GET_OPEN_STATUS       _IOR(COMPASS_IOCTL_MAGIC, 0x07, int)
97 #define ECS_IOCTL_GET_CLOSE_STATUS      _IOR(COMPASS_IOCTL_MAGIC, 0x08, int)
98 #define ECS_IOCTL_GET_LAYOUT            _IOR(COMPASS_IOCTL_MAGIC, 0x09, char)
99 #define ECS_IOCTL_GET_ACCEL             _IOR(COMPASS_IOCTL_MAGIC, 0x0A, short[3])
100 #define ECS_IOCTL_GET_OUTBIT            _IOR(COMPASS_IOCTL_MAGIC, 0x0B, char)
101 #define ECS_IOCTL_GET_INFO              _IOR(COMPASS_IOCTL_MAGIC, 0x0C, short)
102 #define ECS_IOCTL_GET_CONF              _IOR(COMPASS_IOCTL_MAGIC, 0x0D, short)
103 #define ECS_IOCTL_GET_PLATFORM_DATA     _IOR(COMPASS_IOCTL_MAGIC, 0x0E, struct akm_platform_data)
104 #define ECS_IOCTL_GET_DELAY             _IOR(COMPASS_IOCTL_MAGIC, 0x30, short)
105
106
107
108 #define AK09911_DEVICE_ID               0x05
109 static struct i2c_client *this_client;
110 static struct miscdevice compass_dev_device;
111
112 static short g_akm_rbuf[12];
113 static char g_sensor_info[AK09911_INFO_SIZE];
114 static char g_sensor_conf[AK09911_CONF_SIZE];
115
116
117 /****************operate according to sensor chip:start************/
118
119 static int sensor_active(struct i2c_client *client, int enable, int rate)
120 {
121         struct sensor_private_data *sensor =
122             (struct sensor_private_data *) i2c_get_clientdata(client);
123         int result = 0;
124
125         //sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
126
127         //register setting according to chip datasheet
128         if(enable)
129         {
130                 sensor->ops->ctrl_data = AK09911_MODE_SNG_MEASURE;
131         }
132         else
133         {
134                 sensor->ops->ctrl_data = AK09911_MODE_POWERDOWN;
135         }
136
137         DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);
138         result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
139         if(result)
140                 printk("%s:fail to active sensor\n",__func__);
141
142         return result;
143
144 }
145
146 static int sensor_init(struct i2c_client *client)
147 {
148         struct sensor_private_data *sensor =
149             (struct sensor_private_data *) i2c_get_clientdata(client);
150         int result = 0;
151
152         this_client = client;
153
154         result = sensor->ops->active(client,0,0);
155         if(result)
156         {
157                 printk("%s:line=%d,error\n",__func__,__LINE__);
158                 return result;
159         }
160
161         sensor->status_cur = SENSOR_OFF;
162
163         result = misc_register(&compass_dev_device);
164         if (result < 0) {
165                 printk("%s:fail to register misc device %s\n", __func__, compass_dev_device.name);
166                 result = -1;
167         }
168
169         g_sensor_info[0] = AK09911_REG_WIA1;
170         result = sensor_rx_data(client, g_sensor_info, AK09911_INFO_SIZE);
171         if(result)
172         {
173                 printk("%s:line=%d,error\n",__func__,__LINE__);
174                 return result;
175         }
176
177
178         g_sensor_conf[0] = AK09911_FUSE_ASAX;
179         result = sensor_rx_data(client, g_sensor_conf, AK09911_CONF_SIZE);
180         if(result)
181         {
182                 printk("%s:line=%d,error\n",__func__,__LINE__);
183                 return result;
184         }
185
186         DBG("%s:status_cur=%d\n",__func__, sensor->status_cur);
187         return result;
188 }
189
190 static int sensor_report_value(struct i2c_client *client)
191 {
192         struct sensor_private_data *sensor =
193                 (struct sensor_private_data *) i2c_get_clientdata(client);
194         char buffer[SENSOR_DATA_SIZE] = {0};
195         unsigned char *stat;
196         unsigned char *stat2;
197         int ret = 0;
198         char value = 0;
199         int i;
200
201         if(sensor->ops->read_len < SENSOR_DATA_SIZE)    //sensor->ops->read_len = 8
202         {
203                 printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
204                 return -1;
205         }
206
207         memset(buffer, 0, SENSOR_DATA_SIZE);
208
209         /* Data bytes from hardware xL, xH, yL, yH, zL, zH */
210         do {
211                 *buffer = sensor->ops->read_reg;
212                 ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
213                 if (ret < 0)
214                 return ret;
215         } while (0);
216
217         stat = &buffer[0];
218         stat2 = &buffer[7];
219
220         /*
221          * ST : data ready -
222          * Measurement has been completed and data is ready to be read.
223          */
224         if ((*stat & 0x01) != 0x01) {
225                 DBG(KERN_ERR "%s:ST is not set\n",__func__);
226                 return -1;
227         }
228 #if 0
229         /*
230          * ST2 : data error -
231          * occurs when data read is started outside of a readable period;
232          * data read would not be correct.
233          * Valid in continuous measurement mode only.
234          * In single measurement mode this error should not occour but we
235          * stil account for it and return an error, since the data would be
236          * corrupted.
237          * DERR bit is self-clearing when ST2 register is read.
238          */
239         if (*stat2 & 0x04)
240         {
241                 DBG(KERN_ERR "%s:compass data error\n",__func__);
242                 return -2;
243         }
244
245         /*
246          * ST2 : overflow -
247          * the sum of the absolute values of all axis |X|+|Y|+|Z| < 2400uT.
248          * This is likely to happen in presence of an external magnetic
249          * disturbance; it indicates, the sensor data is incorrect and should
250          * be ignored.
251          * An error is returned.
252          * HOFL bit clears when a new measurement starts.
253          */
254         if (*stat2 & 0x08)
255         {
256                 DBG(KERN_ERR "%s:compass data overflow\n",__func__);
257                 return -3;
258         }
259 #endif
260         /* »¥³âµØ»º´æÊý¾Ý. */
261         mutex_lock(&sensor->data_mutex);
262         memcpy(sensor->sensor_data, buffer, sensor->ops->read_len);
263         mutex_unlock(&sensor->data_mutex);
264         DBG("%s:",__func__);
265         for(i=0; i<sensor->ops->read_len; i++)
266                 DBG("0x%x,",buffer[i]);
267         DBG("\n");
268
269         if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0))    //read sensor intterupt status register
270         {
271
272                 value = sensor_read_reg(client, sensor->ops->int_status_reg);
273                 DBG("%s:sensor int status :0x%x\n",__func__,value);
274         }
275
276
277         //trigger next measurement
278         ret = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
279         if(ret)
280         {
281                 printk(KERN_ERR "%s:fail to set ctrl_data:0x%x\n",__func__,sensor->ops->ctrl_data);
282                 return ret;
283         }
284
285         return ret;
286 }
287
288 static void compass_set_YPR(int *rbuf)
289 {
290         struct sensor_private_data *sensor =
291             (struct sensor_private_data *) i2c_get_clientdata(this_client);
292
293         /* No events are reported */
294         if (!rbuf[0]) {
295                 printk("%s:Don't waste a time.",__func__);
296                 return;
297         }
298
299         DBG("%s:buf[0]=0x%x\n",__func__, rbuf[0]);
300
301         /* Report magnetic sensor information */
302         if (atomic_read(&sensor->flags.m_flag) && (rbuf[0] & ORI_DATA_READY)) {
303                 input_report_abs(sensor->input_dev, ABS_RX, rbuf[9]);
304                 input_report_abs(sensor->input_dev, ABS_RY, rbuf[10]);
305                 input_report_abs(sensor->input_dev, ABS_RZ, rbuf[11]);
306                 input_report_abs(sensor->input_dev, ABS_RUDDER, rbuf[4]);
307                 DBG("%s:m_flag:x=%d,y=%d,z=%d,RUDDER=%d\n",__func__,rbuf[9], rbuf[10], rbuf[11], rbuf[4]);
308         }
309
310         /* Report acceleration sensor information */
311         if (atomic_read(&sensor->flags.a_flag) && (rbuf[0] & ACC_DATA_READY)) {
312                 input_report_abs(sensor->input_dev, ABS_X, rbuf[1]);
313                 input_report_abs(sensor->input_dev, ABS_Y, rbuf[2]);
314                 input_report_abs(sensor->input_dev, ABS_Z, rbuf[3]);
315                 input_report_abs(sensor->input_dev, ABS_WHEEL, rbuf[4]);
316
317                 DBG("%s:a_flag:x=%d,y=%d,z=%d,WHEEL=%d\n",__func__,rbuf[1], rbuf[2], rbuf[3], rbuf[4]);
318         }
319
320         /* Report magnetic vector information */
321         if (atomic_read(&sensor->flags.mv_flag) && (rbuf[0] & MAG_DATA_READY)) {
322                 input_report_abs(sensor->input_dev, ABS_HAT0X, rbuf[5]);
323                 input_report_abs(sensor->input_dev, ABS_HAT0Y, rbuf[6]);
324                 input_report_abs(sensor->input_dev, ABS_BRAKE, rbuf[7]);
325                 input_report_abs(sensor->input_dev, ABS_HAT1X, rbuf[8]);
326
327                 DBG("%s:mv_flag:x=%d,y=%d,z=%d,status=%d\n",__func__,rbuf[5], rbuf[6], rbuf[7], rbuf[8]);
328         }
329
330         input_sync(sensor->input_dev);
331
332         memcpy(g_akm_rbuf, rbuf, 12);   //used for ECS_IOCTL_GET_ACCEL
333 }
334
335
336
337 static int compass_dev_open(struct inode *inode, struct file *file)
338 {
339         struct sensor_private_data* sensor =
340                 (struct sensor_private_data *)i2c_get_clientdata(this_client);
341         int result = 0;
342         DBG("%s\n",__func__);
343
344         return result;
345 }
346
347
348 static int compass_dev_release(struct inode *inode, struct file *file)
349 {
350         struct sensor_private_data* sensor =
351                 (struct sensor_private_data *)i2c_get_clientdata(this_client);
352         int result = 0;
353         DBG("%s\n",__func__);
354
355         return result;
356 }
357
358 static int compass_akm_set_mode(struct i2c_client *client, char mode)
359 {
360         struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
361         int result = 0;
362
363         switch(mode & 0x1f)
364         {
365                 case AK09911_MODE_SNG_MEASURE:
366                 case AK09911_MODE_SELF_TEST:
367                 case AK09911_MODE_FUSE_ACCESS:
368                         if(sensor->status_cur == SENSOR_OFF)
369                         {
370                                 if(sensor->pdata->irq_enable)
371                                 {
372                                         //DBG("%s:enable irq=%d\n",__func__,client->irq);
373                                         //enable_irq(client->irq);
374                                 }
375                                 else
376                                 {
377                                         schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));
378                                 }
379
380                                 sensor->status_cur = SENSOR_ON;
381                         }
382
383                         break;
384
385                 case AK09911_MODE_POWERDOWN:
386                         if(sensor->status_cur == SENSOR_ON)
387                         {
388                                 if(sensor->pdata->irq_enable)
389                                 {
390                                         //DBG("%s:disable irq=%d\n",__func__,client->irq);
391                                         //disable_irq_nosync(client->irq);//disable irq
392                                 }
393                                 else
394                                 cancel_delayed_work_sync(&sensor->delaywork);
395
396                                 sensor->status_cur = SENSOR_OFF;
397                         }
398                         break;
399
400         }
401
402         switch(mode & 0x1f)
403         {
404                 case AK09911_MODE_SNG_MEASURE:
405                         result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SNG_MEASURE);
406                         if(result)
407                         printk("%s:i2c error,mode=%d\n",__func__,mode);
408                         break;
409                 case AK09911_MODE_SELF_TEST:
410                         result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SELF_TEST);
411                         if(result)
412                         printk("%s:i2c error,mode=%d\n",__func__,mode);
413                         break;
414                 case AK09911_MODE_FUSE_ACCESS:
415                         result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_FUSE_ACCESS);
416                         if(result)
417                         printk("%s:i2c error,mode=%d\n",__func__,mode);
418                         break;
419                 case AK09911_MODE_POWERDOWN:
420                         /* Set powerdown mode */
421                         result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_POWERDOWN);
422                         if(result)
423                         printk("%s:i2c error,mode=%d\n",__func__,mode);
424                         udelay(100);
425                         break;
426                 default:
427                         printk("%s: Unknown mode(%d)", __func__, mode);
428                         result = -EINVAL;
429                         break;
430         }
431         DBG("%s:mode=0x%x\n",__func__,mode);
432         return result;
433
434 }
435
436 static int compass_akm_reset(struct i2c_client *client)
437 {
438         struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
439         int result = 0;
440
441         if(sensor->pdata->reset_pin > 0)
442         {
443                 gpio_direction_output(sensor->pdata->reset_pin, GPIO_LOW);
444                 udelay(10);
445                 gpio_direction_output(sensor->pdata->reset_pin, GPIO_HIGH);
446         }
447         else
448         {
449                 /* Set measure mode */
450                 result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SNG_MEASURE);
451                 if(result)
452                 printk("%s:fail to Set measure mode\n",__func__);
453         }
454
455         udelay(100);
456
457         return result;
458
459 }
460
461
462
463 static int compass_akm_get_openstatus(void)
464 {
465         struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
466         wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) != 0));
467         return atomic_read(&sensor->flags.open_flag);
468 }
469
470 static int compass_akm_get_closestatus(void)
471 {
472         struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
473         wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) <= 0));
474         return atomic_read(&sensor->flags.open_flag);
475 }
476
477
478 /* ioctl - I/O control */
479 static long compass_dev_ioctl(struct file *file,
480                           unsigned int cmd, unsigned long arg)
481 {
482     struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
483         struct i2c_client *client = this_client;
484         void __user *argp = (void __user *)arg;
485         int result = 0;
486         struct akm_platform_data compass;
487
488         /* NOTE: In this function the size of "char" should be 1-byte. */
489         char compass_data[SENSOR_DATA_SIZE];    /* for GETDATA */
490         char rwbuf[RWBUF_SIZE];                 /* for READ/WRITE */
491         char mode;                              /* for SET_MODE*/
492         int value[YPR_DATA_SIZE];               /* for SET_YPR */
493         int status;                             /* for OPEN/CLOSE_STATUS */
494         int ret = -1;                           /* Return value. */
495
496         //int8_t sensor_buf[SENSOR_DATA_SIZE];  /* for GETDATA */
497         //int32_t ypr_buf[YPR_DATA_SIZE];       /* for SET_YPR */
498         int16_t acc_buf[3];                     /* for GET_ACCEL */
499         int64_t delay[AKM_NUM_SENSORS];         /* for GET_DELAY */
500         char layout;            /* for GET_LAYOUT */
501         char outbit;            /* for GET_OUTBIT */
502
503         switch (cmd) {
504         case ECS_IOCTL_WRITE:
505         case ECS_IOCTL_READ:
506                 if (argp == NULL) {
507                         return -EINVAL;
508                 }
509                 if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) {
510                         return -EFAULT;
511                 }
512                 break;
513         case ECS_IOCTL_SET_MODE:
514                 if (argp == NULL) {
515                         return -EINVAL;
516                 }
517                 if (copy_from_user(&mode, argp, sizeof(mode))) {
518                         return -EFAULT;
519                 }
520                 break;
521         case ECS_IOCTL_SET_YPR:
522                 if (argp == NULL) {
523                         return -EINVAL;
524                 }
525                 if (copy_from_user(&value, argp, sizeof(value))) {
526                         return -EFAULT;
527                 }
528                 break;
529         case ECS_IOCTL_GETDATA:
530         case ECS_IOCTL_GET_OPEN_STATUS:
531         case ECS_IOCTL_GET_CLOSE_STATUS:
532         case ECS_IOCTL_GET_DELAY:
533         case ECS_IOCTL_GET_LAYOUT:
534         case ECS_IOCTL_GET_OUTBIT:
535         case ECS_IOCTL_GET_ACCEL:
536         case ECS_IOCTL_GET_INFO:
537         case ECS_IOCTL_GET_CONF:
538                 /* Just check buffer pointer */
539                 if (argp == NULL) {
540                         printk("%s:invalid argument\n",__func__);
541                         return -EINVAL;
542                 }
543                 break;
544         default:
545                 break;
546         }
547
548         switch (cmd) {
549         case ECS_IOCTL_WRITE:
550                 DBG("%s:ECS_IOCTL_WRITE start\n",__func__);
551                 mutex_lock(&sensor->operation_mutex);
552                 if ((rwbuf[0] < 2) || (rwbuf[0] > (RWBUF_SIZE-1))) {
553                         mutex_unlock(&sensor->operation_mutex);
554                         return -EINVAL;
555                 }
556                 ret = sensor_tx_data(client, &rwbuf[1], rwbuf[0]);
557                 if (ret < 0) {
558                         mutex_unlock(&sensor->operation_mutex);
559                         printk("%s:fait to tx data\n",__func__);
560                         return ret;
561                 }
562                 mutex_unlock(&sensor->operation_mutex);
563                 break;
564         case ECS_IOCTL_READ:
565                 DBG("%s:ECS_IOCTL_READ start\n",__func__);
566                 mutex_lock(&sensor->operation_mutex);
567                 if ((rwbuf[0] < 1) || (rwbuf[0] > (RWBUF_SIZE-1))) {
568                         mutex_unlock(&sensor->operation_mutex);
569                         printk("%s:data is error\n",__func__);
570                         return -EINVAL;
571                 }
572                 ret = sensor_rx_data(client, &rwbuf[1], rwbuf[0]);
573                 if (ret < 0) {
574                         mutex_unlock(&sensor->operation_mutex);
575                         printk("%s:fait to rx data\n",__func__);
576                         return ret;
577                 }
578                 mutex_unlock(&sensor->operation_mutex);
579                 break;
580         case ECS_IOCTL_SET_MODE:
581                 DBG("%s:ECS_IOCTL_SET_MODE start\n",__func__);
582                 mutex_lock(&sensor->operation_mutex);
583                 if(sensor->ops->ctrl_data != mode)
584                 {
585                         ret = compass_akm_set_mode(client, mode);
586                         if (ret < 0) {
587                                 printk("%s:fait to set mode\n",__func__);
588                                 mutex_unlock(&sensor->operation_mutex);
589                                 return ret;
590                         }
591
592                         sensor->ops->ctrl_data = mode;
593                 }
594                 mutex_unlock(&sensor->operation_mutex);
595                 break;
596         case ECS_IOCTL_GETDATA:
597                         DBG("%s:ECS_IOCTL_GETDATA start\n",__func__);
598                         mutex_lock(&sensor->data_mutex);
599                         memcpy(compass_data, sensor->sensor_data, SENSOR_DATA_SIZE);    //get data from buffer
600                         mutex_unlock(&sensor->data_mutex);
601                         break;
602         case ECS_IOCTL_SET_YPR:
603                         DBG("%s:ECS_IOCTL_SET_YPR start\n",__func__);
604                         mutex_lock(&sensor->data_mutex);
605                         compass_set_YPR(value);
606                         mutex_unlock(&sensor->data_mutex);
607                 break;
608         case ECS_IOCTL_GET_OPEN_STATUS:
609                 status = compass_akm_get_openstatus();
610                 DBG("%s:openstatus=%d\n",__func__,status);
611                 break;
612         case ECS_IOCTL_GET_CLOSE_STATUS:
613                 status = compass_akm_get_closestatus();
614                 DBG("%s:closestatus=%d\n",__func__,status);
615                 break;
616         case ECS_IOCTL_GET_DELAY:
617                 DBG("%s:ECS_IOCTL_GET_DELAY start\n",__func__);
618                 mutex_lock(&sensor->operation_mutex);
619                 delay[0] = sensor->flags.delay;
620                 delay[1] = sensor->flags.delay;
621                 delay[2] = sensor->flags.delay;
622                 mutex_unlock(&sensor->operation_mutex);
623                 break;
624
625         case ECS_IOCTL_GET_PLATFORM_DATA:
626                 DBG("%s:ECS_IOCTL_GET_PLATFORM_DATA start\n",__func__);
627         //      memcpy(compass.m_layout, sensor->pdata->m_layout, sizeof(sensor->pdata->m_layout));
628         //      memcpy(compass.project_name, sensor->pdata->project_name, sizeof(sensor->pdata->project_name));
629                 ret = copy_to_user(argp, &compass, sizeof(compass));
630                 if(ret < 0)
631                 {
632                         printk("%s:error,ret=%d\n",__FUNCTION__, ret);
633                         return ret;
634                 }
635                 break;
636         case ECS_IOCTL_GET_LAYOUT:
637                 DBG("%s:ECS_IOCTL_GET_LAYOUT start\n",__func__);
638                 if((sensor->pdata->layout >= 1) && (sensor->pdata->layout <=8 ))
639                 layout = sensor->pdata->layout;
640                 else
641                 layout = 1;
642                 break;
643         case ECS_IOCTL_GET_OUTBIT:
644                 DBG("%s:ECS_IOCTL_GET_OUTBIT start\n",__func__);
645                 outbit = 1;     //sensor->pdata->outbit;
646                 break;
647         case ECS_IOCTL_RESET:
648                 DBG("%s:ECS_IOCTL_RESET start\n",__func__);
649                 ret = compass_akm_reset(client);
650                 if (ret < 0)
651                         return ret;
652                 break;
653         case ECS_IOCTL_GET_ACCEL:
654                 DBG("%s:ECS_IOCTL_GET_ACCEL start,no accel data\n",__func__);
655                 mutex_lock(&sensor->operation_mutex);
656                 acc_buf[0] = g_akm_rbuf[6];
657                 acc_buf[1] = g_akm_rbuf[7];
658                 acc_buf[2] = g_akm_rbuf[8];
659                 mutex_unlock(&sensor->operation_mutex);
660                 break;
661         case ECS_IOCTL_GET_INFO:
662                 ret = copy_to_user(argp, g_sensor_info, sizeof(g_sensor_info));
663                 if(ret < 0)
664                 {
665                         printk("%s:error,ret=%d\n",__FUNCTION__, ret);
666                         return ret;
667                 }
668                 break;
669         case ECS_IOCTL_GET_CONF:
670                 ret = copy_to_user(argp, g_sensor_conf, sizeof(g_sensor_conf));
671                 if(ret < 0)
672                 {
673                         printk("%s:error,ret=%d\n",__FUNCTION__, ret);
674                         return ret;
675                 }
676                 break;
677
678         default:
679                 return -ENOTTY;
680         }
681
682         switch (cmd) {
683         case ECS_IOCTL_READ:
684                 if (copy_to_user(argp, &rwbuf, rwbuf[0]+1)) {
685                         return -EFAULT;
686                 }
687                 break;
688         case ECS_IOCTL_GETDATA:
689                 if (copy_to_user(argp, &compass_data, sizeof(compass_data))) {
690                         return -EFAULT;
691                 }
692                 break;
693         case ECS_IOCTL_GET_OPEN_STATUS:
694         case ECS_IOCTL_GET_CLOSE_STATUS:
695                 if (copy_to_user(argp, &status, sizeof(status))) {
696                         return -EFAULT;
697                 }
698                 break;
699         case ECS_IOCTL_GET_DELAY:
700                 if (copy_to_user(argp, &delay, sizeof(delay))) {
701                         return -EFAULT;
702                 }
703                 break;
704         case ECS_IOCTL_GET_LAYOUT:
705                 if (copy_to_user(argp, &layout, sizeof(layout))) {
706                         printk("%s:error:%d\n",__FUNCTION__,__LINE__);
707                         return -EFAULT;
708                 }
709                 break;
710         case ECS_IOCTL_GET_OUTBIT:
711                 if (copy_to_user(argp, &outbit, sizeof(outbit))) {
712                         printk("%s:error:%d\n",__FUNCTION__,__LINE__);
713                         return -EFAULT;
714                 }
715                 break;
716         case ECS_IOCTL_GET_ACCEL:
717                 if (copy_to_user(argp, &acc_buf, sizeof(acc_buf))) {
718                         printk("%s:error:%d\n",__FUNCTION__,__LINE__);
719                         return -EFAULT;
720                 }
721                 break;
722         default:
723                 break;
724         }
725
726         return result;
727 }
728
729 static struct file_operations compass_dev_fops =
730 {
731         .owner = THIS_MODULE,
732         .open = compass_dev_open,
733         .release = compass_dev_release,
734         .unlocked_ioctl = compass_dev_ioctl,
735 };
736
737
738 static struct miscdevice compass_dev_device =
739 {
740         .minor = MISC_DYNAMIC_MINOR,
741         .name = "akm_dev",
742         .fops = &compass_dev_fops,
743 };
744
745 struct sensor_operate compass_akm09911_ops = {
746         .name                           = "akm09911",
747         .type                           = SENSOR_TYPE_COMPASS,  //it is important
748         .id_i2c                         = COMPASS_ID_AK09911,
749         .read_reg                       = AK09911_REG_ST1,      //read data
750         .read_len                       = SENSOR_DATA_SIZE,     //data length
751         .id_reg                         = AK09911_REG_WIA2,     //read id
752         .id_data                        = AK09911_DEVICE_ID,
753         .precision                      = 8,                    //12 bits
754         .ctrl_reg                       = AK09911_REG_CNTL2,    //enable or disable
755         .int_status_reg                 = SENSOR_UNKNOW_DATA,   //not exist
756         .range                          = {-0xffff,0xffff},
757         .trig                           = IRQF_TRIGGER_RISING,  //if LEVEL interrupt then IRQF_ONESHOT
758         .active                         = sensor_active,
759         .init                           = sensor_init,
760         .report                         = sensor_report_value,
761         .misc_dev                       = NULL,                 //private misc support
762 };
763
764 /****************operate according to sensor chip:end************/
765
766 //function name should not be changed
767 static struct sensor_operate *compass_get_ops(void)
768 {
769         return &compass_akm09911_ops;
770 }
771
772
773 static int __init compass_akm09911_init(void)
774 {
775         struct sensor_operate *ops = compass_get_ops();
776         int result = 0;
777         int type = ops->type;
778         result = sensor_register_slave(type, NULL, NULL, compass_get_ops);
779
780         return result;
781 }
782
783 static void __exit compass_akm09911_exit(void)
784 {
785         struct sensor_operate *ops = compass_get_ops();
786         int type = ops->type;
787         sensor_unregister_slave(type, NULL, NULL, compass_get_ops);
788 }
789
790
791 module_init(compass_akm09911_init);
792 module_exit(compass_akm09911_exit);
793
794