input: sensors: fromdos and remove trailing whitespace
[firefly-linux-kernel-4.4.55.git] / drivers / input / sensors / compass / ak8963.c
1 /* drivers/input/sensors/access/akm8963.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 #define AKM_SENSOR_INFO_SIZE 2
35 #define AKM_SENSOR_CONF_SIZE 3
36 #define SENSOR_DATA_SIZE        8
37 #define YPR_DATA_SIZE           12
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 /*! \name AK8963 constant definition
50  \anchor AK8963_Def
51  Constant definitions of the AK8963.*/
52 #define AK8963_MEASUREMENT_TIME_US      10000
53
54 /*! \name AK8963 operation mode
55  \anchor AK8963_Mode
56  Defines an operation mode of the AK8963.*/
57 /*! @{*/
58 #define AK8963_MODE_SNG_MEASURE 0x01
59 #define AK8963_MODE_SELF_TEST   0x08
60 #define AK8963_MODE_FUSE_ACCESS 0x0F
61 #define AK8963_MODE_POWERDOWN   0x00
62
63 /*! @}*/
64
65 /*! \name AK8963 register address
66 \anchor AK8963_REG
67 Defines a register address of the AK8963.*/
68 /*! @{*/
69 #define AK8963_REG_WIA          0x00
70 #define AK8963_REG_INFO         0x01
71 #define AK8963_REG_ST1          0x02
72 #define AK8963_REG_HXL          0x03
73 #define AK8963_REG_HXH          0x04
74 #define AK8963_REG_HYL          0x05
75 #define AK8963_REG_HYH          0x06
76 #define AK8963_REG_HZL          0x07
77 #define AK8963_REG_HZH          0x08
78 #define AK8963_REG_ST2          0x09
79 #define AK8963_REG_CNTL1        0x0A
80 #define AK8963_REG_CNTL2        0x0B
81 #define AK8963_REG_ASTC         0x0C
82 #define AK8963_REG_TS1          0x0D
83 #define AK8963_REG_TS2          0x0E
84 #define AK8963_REG_I2CDIS       0x0F
85
86 #define AK8963_WIA_VALUE                0x48
87
88 /*! @}*/
89
90 /*! \name AK8963 fuse-rom address
91 \anchor AK8963_FUSE
92 Defines a read-only address of the fuse ROM of the AK8963.*/
93 /*! @{*/
94 #define AK8963_FUSE_ASAX        0x10
95 #define AK8963_FUSE_ASAY        0x11
96 #define AK8963_FUSE_ASAZ        0x12
97 /*! @}*/
98
99 #define AK8963_INFO_DATA        (0x03<<3)
100
101
102 #define COMPASS_IOCTL_MAGIC                   'c'
103
104 /* IOCTLs for AKM library */
105 #define ECS_IOCTL_WRITE                 _IOW(COMPASS_IOCTL_MAGIC, 0x01, char*)
106 #define ECS_IOCTL_READ                  _IOWR(COMPASS_IOCTL_MAGIC, 0x02, char*)
107 #define ECS_IOCTL_RESET                 _IO(COMPASS_IOCTL_MAGIC, 0x03) /* NOT used in AK8975 */
108 #define ECS_IOCTL_SET_MODE              _IOW(COMPASS_IOCTL_MAGIC, 0x04, short)
109 #define ECS_IOCTL_GETDATA               _IOR(COMPASS_IOCTL_MAGIC, 0x05, char[SENSOR_DATA_SIZE])
110 #define ECS_IOCTL_SET_YPR               _IOW(COMPASS_IOCTL_MAGIC, 0x06, short[12])
111 #define ECS_IOCTL_GET_OPEN_STATUS       _IOR(COMPASS_IOCTL_MAGIC, 0x07, int)
112 #define ECS_IOCTL_GET_CLOSE_STATUS      _IOR(COMPASS_IOCTL_MAGIC, 0x08, int)
113 #define ECS_IOCTL_GET_LAYOUT            _IOR(COMPASS_IOCTL_MAGIC, 0x09, char)
114 #define ECS_IOCTL_GET_ACCEL             _IOR(COMPASS_IOCTL_MAGIC, 0x0A, short[3])
115 #define ECS_IOCTL_GET_OUTBIT            _IOR(COMPASS_IOCTL_MAGIC, 0x0B, char)
116 #define ECS_IOCTL_GET_DELAY             _IOR(COMPASS_IOCTL_MAGIC, 0x30, short)
117 #define ECS_IOCTL_GET_PROJECT_NAME      _IOR(COMPASS_IOCTL_MAGIC, 0x0D, char[64])
118 #define ECS_IOCTL_GET_MATRIX            _IOR(COMPASS_IOCTL_MAGIC, 0x0E, short [4][3][3])
119 #define ECS_IOCTL_GET_PLATFORM_DATA     _IOR(COMPASS_IOCTL_MAGIC, 0x0E, struct akm_platform_data)
120 #define ECS_IOCTL_GET_INFO                      _IOR(COMPASS_IOCTL_MAGIC, 0x27, unsigned char[AKM_SENSOR_INFO_SIZE])
121 #define ECS_IOCTL_GET_CONF                      _IOR(COMPASS_IOCTL_MAGIC, 0x28, unsigned char[AKM_SENSOR_CONF_SIZE])
122
123 #define AK8963_DEVICE_ID                0x48
124 static struct i2c_client *this_client;
125 static struct miscdevice compass_dev_device;
126
127 static short g_akm_rbuf[12];
128
129
130 /****************operate according to sensor chip:start************/
131
132 static int sensor_active(struct i2c_client *client, int enable, int rate)
133 {
134         struct sensor_private_data *sensor =
135             (struct sensor_private_data *) i2c_get_clientdata(client);
136         int result = 0;
137
138         //sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
139
140         //register setting according to chip datasheet
141         if(enable)
142         {
143                 sensor->ops->ctrl_data = AK8963_MODE_SNG_MEASURE;
144         }
145         else
146         {
147                 sensor->ops->ctrl_data = AK8963_MODE_POWERDOWN;
148         }
149
150         DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);
151         result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
152         if(result)
153                 printk("%s:fail to active sensor\n",__func__);
154
155         return result;
156
157 }
158
159 static int sensor_init(struct i2c_client *client)
160 {
161         struct sensor_private_data *sensor =
162             (struct sensor_private_data *) i2c_get_clientdata(client);
163         int result = 0;
164         char info = 0;
165
166         this_client = client;
167
168         result = sensor->ops->active(client,0,0);
169         if(result)
170         {
171                 printk("%s:line=%d,error\n",__func__,__LINE__);
172                 return result;
173         }
174
175         sensor->status_cur = SENSOR_OFF;
176
177         info = sensor_read_reg(client, AK8963_REG_INFO);
178         if((info & (0x0f<<3)) != AK8963_INFO_DATA)
179         {
180                 printk("%s:info=0x%x,it is not %s\n",__func__, info, sensor->ops->name);
181                 return -1;
182         }
183
184         result = misc_register(&compass_dev_device);
185         if (result < 0) {
186                 printk("%s:fail to register misc device %s\n", __func__, compass_dev_device.name);
187                 result = -1;
188         }
189
190         DBG("%s:status_cur=%d\n",__func__, sensor->status_cur);
191         return result;
192 }
193
194 static int sensor_report_value(struct i2c_client *client)
195 {
196         struct sensor_private_data *sensor =
197                 (struct sensor_private_data *) i2c_get_clientdata(client);
198         char buffer[8] = {0};
199         unsigned char *stat;
200         unsigned char *stat2;
201         int ret = 0;
202         char value = 0;
203         int i;
204
205         if(sensor->ops->read_len < 8)   //sensor->ops->read_len = 8
206         {
207                 printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
208                 return -1;
209         }
210
211         memset(buffer, 0, 8);
212
213         /* Data bytes from hardware xL, xH, yL, yH, zL, zH */
214         do {
215                 *buffer = sensor->ops->read_reg;
216                 ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
217                 if (ret < 0)
218                 return ret;
219         } while (0);
220
221         stat = &buffer[0];
222         stat2 = &buffer[7];
223
224         /*
225          * ST : data ready -
226          * Measurement has been completed and data is ready to be read.
227          */
228         if ((*stat & 0x01) != 0x01) {
229                 DBG(KERN_ERR "%s:ST is not set\n",__func__);
230                 return -1;
231         }
232
233         /*
234          * ST2 : data error -
235          * occurs when data read is started outside of a readable period;
236          * data read would not be correct.
237          * Valid in continuous measurement mode only.
238          * In single measurement mode this error should not occour but we
239          * stil account for it and return an error, since the data would be
240          * corrupted.
241          * DERR bit is self-clearing when ST2 register is read.
242          */
243         if (*stat2 & 0x04)
244         {
245                 DBG(KERN_ERR "%s:compass data error\n",__func__);
246                 return -2;
247         }
248
249         /*
250          * ST2 : overflow -
251          * the sum of the absolute values of all axis |X|+|Y|+|Z| < 2400uT.
252          * This is likely to happen in presence of an external magnetic
253          * disturbance; it indicates, the sensor data is incorrect and should
254          * be ignored.
255          * An error is returned.
256          * HOFL bit clears when a new measurement starts.
257          */
258         if (*stat2 & 0x08)
259         {
260                 DBG(KERN_ERR "%s:compass data overflow\n",__func__);
261                 return -3;
262         }
263
264         /* »¥³âµØ»º´æÊý¾Ý. */
265         mutex_lock(&sensor->data_mutex);
266         memcpy(sensor->sensor_data, buffer, sensor->ops->read_len);
267         mutex_unlock(&sensor->data_mutex);
268         DBG("%s:",__func__);
269         for(i=0; i<sensor->ops->read_len; i++)
270                 DBG("0x%x,",buffer[i]);
271         DBG("\n");
272
273         if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0))    //read sensor intterupt status register
274         {
275
276                 value = sensor_read_reg(client, sensor->ops->int_status_reg);
277                 DBG("%s:sensor int status :0x%x\n",__func__,value);
278         }
279
280
281         //trigger next measurement
282         ret = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
283         if(ret)
284         {
285                 printk(KERN_ERR "%s:fail to set ctrl_data:0x%x\n",__func__,sensor->ops->ctrl_data);
286                 return ret;
287         }
288
289         return ret;
290 }
291
292 static void compass_set_YPR(int *rbuf)
293 {
294         struct sensor_private_data *sensor =
295             (struct sensor_private_data *) i2c_get_clientdata(this_client);
296
297         /* No events are reported */
298         if (!rbuf[0]) {
299                 printk("%s:Don't waste a time.",__func__);
300                 return;
301         }
302
303         DBG("%s:buf[0]=0x%x\n",__func__, rbuf[0]);
304
305         /* Report magnetic sensor information */
306         if (atomic_read(&sensor->flags.m_flag) && (rbuf[0] & ORI_DATA_READY)) {
307                 input_report_abs(sensor->input_dev, ABS_RX, rbuf[9]);
308                 input_report_abs(sensor->input_dev, ABS_RY, rbuf[10]);
309                 input_report_abs(sensor->input_dev, ABS_RZ, rbuf[11]);
310                 input_report_abs(sensor->input_dev, ABS_RUDDER, rbuf[4]);
311                 DBG("%s:m_flag:x=%d,y=%d,z=%d,RUDDER=%d\n", __func__, rbuf[9], rbuf[10], rbuf[11], rbuf[4]);
312         }
313
314         /* Report acceleration sensor information */
315         if (atomic_read(&sensor->flags.a_flag) && (rbuf[0] & ACC_DATA_READY)) {
316                 input_report_abs(sensor->input_dev, ABS_X, rbuf[1]);
317                 input_report_abs(sensor->input_dev, ABS_Y, rbuf[2]);
318                 input_report_abs(sensor->input_dev, ABS_Z, rbuf[3]);
319                 input_report_abs(sensor->input_dev, ABS_WHEEL, rbuf[4]);
320
321                 DBG("%s:a_flag:x=%d,y=%d,z=%d,WHEEL=%d\n",__func__,rbuf[1], rbuf[2], rbuf[3], rbuf[4]);
322         }
323
324         /* Report magnetic vector information */
325         if (atomic_read(&sensor->flags.mv_flag) && (rbuf[0] & MAG_DATA_READY)) {
326                 input_report_abs(sensor->input_dev, ABS_HAT0X, rbuf[5]);
327                 input_report_abs(sensor->input_dev, ABS_HAT0Y, rbuf[6]);
328                 input_report_abs(sensor->input_dev, ABS_BRAKE, rbuf[7]);
329                 input_report_abs(sensor->input_dev, ABS_HAT1X, rbuf[8]);
330
331                 DBG("%s:mv_flag:x=%d,y=%d,z=%d,status=%d\n", __func__, rbuf[5], rbuf[6], rbuf[7], rbuf[8]);
332         }
333
334         input_sync(sensor->input_dev);
335
336         memcpy(g_akm_rbuf, rbuf, 12);   //used for ECS_IOCTL_GET_ACCEL
337 }
338
339
340
341 static int compass_dev_open(struct inode *inode, struct file *file)
342 {
343         int result = 0;
344         DBG("%s\n",__func__);
345
346         return result;
347 }
348
349
350 static int compass_dev_release(struct inode *inode, struct file *file)
351 {
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 & 0x0f)
364         {
365                 case AK8963_MODE_SNG_MEASURE:
366                 case AK8963_MODE_SELF_TEST:
367                 case AK8963_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 AK8963_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 & 0x0f)
403         {
404                 case AK8963_MODE_SNG_MEASURE:
405                         result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode);
406                         if(result)
407                         printk("%s:i2c error,mode=%d\n",__func__,mode);
408                         break;
409                 case AK8963_MODE_SELF_TEST:
410                         result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode);
411                         if(result)
412                         printk("%s:i2c error,mode=%d\n",__func__,mode);
413                         break;
414                 case AK8963_MODE_FUSE_ACCESS:
415                         result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode);
416                         if(result)
417                         printk("%s:i2c error,mode=%d\n",__func__,mode);
418                         break;
419                 case AK8963_MODE_POWERDOWN:
420                         /* Set powerdown mode */
421                         result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8963_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, AK8963_REG_CNTL2, AK8963_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         unsigned char sense_info[AKM_SENSOR_INFO_SIZE];
488         unsigned char sense_conf[AKM_SENSOR_CONF_SIZE];
489
490         /* NOTE: In this function the size of "char" should be 1-byte. */
491         char compass_data[SENSOR_DATA_SIZE];    /* for GETDATA */
492         char rwbuf[RWBUF_SIZE];                 /* for READ/WRITE */
493         char mode;                              /* for SET_MODE*/
494         int value[12];                  /* for SET_YPR */
495         int status;                             /* for OPEN/CLOSE_STATUS */
496         int ret = -1;                           /* Return value. */
497
498         //int8_t sensor_buf[SENSOR_DATA_SIZE];  /* for GETDATA */
499         //int32_t ypr_buf[YPR_DATA_SIZE];       /* for SET_YPR */
500         int16_t acc_buf[3];                     /* for GET_ACCEL */
501         int64_t delay[AKM_NUM_SENSORS];         /* for GET_DELAY */
502
503         char layout;            /* for GET_LAYOUT */
504         char outbit;            /* for GET_OUTBIT */
505
506         switch (cmd) {
507         case ECS_IOCTL_WRITE:
508         case ECS_IOCTL_READ:
509                 if (argp == NULL) {
510                         return -EINVAL;
511                 }
512                 if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) {
513                         return -EFAULT;
514                 }
515                 break;
516         case ECS_IOCTL_SET_MODE:
517                 if (argp == NULL) {
518                         return -EINVAL;
519                 }
520                 if (copy_from_user(&mode, argp, sizeof(mode))) {
521                         return -EFAULT;
522                 }
523                 break;
524         case ECS_IOCTL_SET_YPR:
525                 if (argp == NULL) {
526                         return -EINVAL;
527                 }
528                 if (copy_from_user(&value, argp, sizeof(value))) {
529                         return -EFAULT;
530                 }
531                 break;
532         case ECS_IOCTL_GET_INFO:
533         case ECS_IOCTL_GET_CONF:
534         case ECS_IOCTL_GETDATA:
535         case ECS_IOCTL_GET_OPEN_STATUS:
536         case ECS_IOCTL_GET_CLOSE_STATUS:
537         case ECS_IOCTL_GET_DELAY:
538         case ECS_IOCTL_GET_LAYOUT:
539         case ECS_IOCTL_GET_OUTBIT:
540         case ECS_IOCTL_GET_ACCEL:
541                 /* Just check buffer pointer */
542                 if (argp == NULL) {
543                         printk("%s:invalid argument\n",__func__);
544                         return -EINVAL;
545                 }
546                 break;
547         default:
548                 break;
549         }
550
551         switch (cmd) {
552         case ECS_IOCTL_GET_INFO:
553                 sense_info[0] = AK8963_REG_WIA;
554                 mutex_lock(&sensor->operation_mutex);
555                 ret = sensor_rx_data(client, &sense_info[0], AKM_SENSOR_INFO_SIZE);
556                 mutex_unlock(&sensor->operation_mutex);
557                 if (ret < 0) {
558                         printk("%s:fait to get sense_info\n", __func__);
559                         return ret;
560                 }
561                 /* Check read data */
562                 if (sense_info[0] != AK8963_WIA_VALUE) {
563                         dev_err(&client->dev,
564                                 "%s: The device is not AKM Compass.", __func__);
565                         return -ENXIO;
566                 }
567                 break;
568         case ECS_IOCTL_GET_CONF:
569                 sense_conf[0] = AK8963_FUSE_ASAX;
570                 mutex_lock(&sensor->operation_mutex);
571                 ret = sensor_rx_data(client, &sense_conf[0], AKM_SENSOR_CONF_SIZE);
572                 mutex_unlock(&sensor->operation_mutex);
573                 if (ret < 0) {
574                         printk("%s:fait to get sense_conf\n", __func__);
575                         return ret;
576                 }
577                 break;
578         case ECS_IOCTL_WRITE:
579                 DBG("%s:ECS_IOCTL_WRITE start\n",__func__);
580                 mutex_lock(&sensor->operation_mutex);
581                 if ((rwbuf[0] < 2) || (rwbuf[0] > (RWBUF_SIZE-1))) {
582                         mutex_unlock(&sensor->operation_mutex);
583                         return -EINVAL;
584                 }
585                 ret = sensor_tx_data(client, &rwbuf[1], rwbuf[0]);
586                 if (ret < 0) {
587                         mutex_unlock(&sensor->operation_mutex);
588                         printk("%s:fait to tx data\n",__func__);
589                         return ret;
590                 }
591                 mutex_unlock(&sensor->operation_mutex);
592                 break;
593         case ECS_IOCTL_READ:
594                 DBG("%s:ECS_IOCTL_READ start\n",__func__);
595                 mutex_lock(&sensor->operation_mutex);
596                 if ((rwbuf[0] < 1) || (rwbuf[0] > (RWBUF_SIZE-1))) {
597                         mutex_unlock(&sensor->operation_mutex);
598                         printk("%s:data is error\n",__func__);
599                         return -EINVAL;
600                 }
601                 ret = sensor_rx_data(client, &rwbuf[1], rwbuf[0]);
602                 if (ret < 0) {
603                         mutex_unlock(&sensor->operation_mutex);
604                         printk("%s:fait to rx data\n",__func__);
605                         return ret;
606                 }
607                 mutex_unlock(&sensor->operation_mutex);
608                 break;
609         case ECS_IOCTL_SET_MODE:
610                 DBG("%s:ECS_IOCTL_SET_MODE start\n",__func__);
611                 mutex_lock(&sensor->operation_mutex);
612                 if(sensor->ops->ctrl_data != mode)
613                 {
614                         ret = compass_akm_set_mode(client, mode);
615                         if (ret < 0) {
616                                 printk("%s:fait to set mode\n",__func__);
617                                 mutex_unlock(&sensor->operation_mutex);
618                                 return ret;
619                         }
620
621                         sensor->ops->ctrl_data = mode;
622                 }
623                 mutex_unlock(&sensor->operation_mutex);
624                 break;
625         case ECS_IOCTL_GETDATA:
626                         DBG("%s:ECS_IOCTL_GETDATA start\n",__func__);
627                         mutex_lock(&sensor->data_mutex);
628                         memcpy(compass_data, sensor->sensor_data, SENSOR_DATA_SIZE);    //get data from buffer
629                         mutex_unlock(&sensor->data_mutex);
630                         break;
631         case ECS_IOCTL_SET_YPR:
632                         DBG("%s:ECS_IOCTL_SET_YPR start\n",__func__);
633                         mutex_lock(&sensor->data_mutex);
634                         compass_set_YPR(value);
635                         mutex_unlock(&sensor->data_mutex);
636                 break;
637         case ECS_IOCTL_GET_OPEN_STATUS:
638                 status = compass_akm_get_openstatus();
639                 DBG("%s:openstatus=%d\n",__func__,status);
640                 break;
641         case ECS_IOCTL_GET_CLOSE_STATUS:
642                 status = compass_akm_get_closestatus();
643                 DBG("%s:closestatus=%d\n",__func__,status);
644                 break;
645         case ECS_IOCTL_GET_DELAY:
646                 DBG("%s:ECS_IOCTL_GET_DELAY start\n",__func__);
647                 mutex_lock(&sensor->operation_mutex);
648                 delay[0] = sensor->flags.delay;
649                 delay[1] = sensor->flags.delay;
650                 delay[2] = sensor->flags.delay;
651                 mutex_unlock(&sensor->operation_mutex);
652                 break;
653
654         case ECS_IOCTL_GET_PLATFORM_DATA:
655                 DBG("%s:ECS_IOCTL_GET_PLATFORM_DATA start\n",__func__);
656                 //memcpy(compass.m_layout, sensor->pdata->m_layout, sizeof(sensor->pdata->m_layout));
657                 //memcpy(compass.project_name, sensor->pdata->project_name, sizeof(sensor->pdata->project_name));
658                 ret = copy_to_user(argp, &compass, sizeof(compass));
659                 if(ret < 0)
660                 {
661                         printk("%s:error,ret=%d\n",__FUNCTION__, ret);
662                         return ret;
663                 }
664                 break;
665         case ECS_IOCTL_GET_LAYOUT:
666                 DBG("%s:ECS_IOCTL_GET_LAYOUT start\n",__func__);
667                 layout = sensor->pdata->layout;
668                 break;
669         case ECS_IOCTL_GET_OUTBIT:
670                 DBG("%s:ECS_IOCTL_GET_OUTBIT start\n",__func__);
671                 outbit = 1; //sensor->pdata->outbit;
672                 break;
673         case ECS_IOCTL_RESET:
674                 DBG("%s:ECS_IOCTL_RESET start\n",__func__);
675                 ret = compass_akm_reset(client);
676                 if (ret < 0)
677                         return ret;
678                 break;
679         case ECS_IOCTL_GET_ACCEL:
680                 DBG("%s:ECS_IOCTL_GET_ACCEL start,no accel data\n",__func__);
681                 mutex_lock(&sensor->operation_mutex);
682                 acc_buf[0] = g_akm_rbuf[6];
683                 acc_buf[1] = g_akm_rbuf[7];
684                 acc_buf[2] = g_akm_rbuf[8];
685                 mutex_unlock(&sensor->operation_mutex);
686                 break;
687
688         default:
689                 return -ENOTTY;
690         }
691
692         switch (cmd) {
693         case ECS_IOCTL_READ:
694                 if (copy_to_user(argp, &rwbuf, rwbuf[0]+1)) {
695                         return -EFAULT;
696                 }
697                 break;
698         case ECS_IOCTL_GETDATA:
699                 if (copy_to_user(argp, &compass_data, sizeof(compass_data))) {
700                         return -EFAULT;
701                 }
702                 break;
703         case ECS_IOCTL_GET_OPEN_STATUS:
704         case ECS_IOCTL_GET_CLOSE_STATUS:
705                 if (copy_to_user(argp, &status, sizeof(status))) {
706                         return -EFAULT;
707                 }
708                 break;
709         case ECS_IOCTL_GET_DELAY:
710                 if (copy_to_user(argp, &delay, sizeof(delay))) {
711                         return -EFAULT;
712                 }
713                 break;
714         case ECS_IOCTL_GET_LAYOUT:
715                 if (copy_to_user(argp, &layout, sizeof(layout))) {
716                         printk("%s:error:%d\n",__FUNCTION__,__LINE__);
717                         return -EFAULT;
718                 }
719                 break;
720         case ECS_IOCTL_GET_OUTBIT:
721                 if (copy_to_user(argp, &outbit, sizeof(outbit))) {
722                         printk("%s:error:%d\n",__FUNCTION__,__LINE__);
723                         return -EFAULT;
724                 }
725                 break;
726         case ECS_IOCTL_GET_ACCEL:
727                 if (copy_to_user(argp, &acc_buf, sizeof(acc_buf))) {
728                         printk("%s:error:%d\n",__FUNCTION__,__LINE__);
729                         return -EFAULT;
730                 }
731                 break;
732         case ECS_IOCTL_GET_INFO:
733                 if (copy_to_user(argp, &sense_info,     sizeof(sense_info))) {
734                         printk("%s:error:%d\n", __FUNCTION__, __LINE__);
735                         return -EFAULT;
736                 }
737                 break;
738         case ECS_IOCTL_GET_CONF:
739                 if (copy_to_user(argp, &sense_conf,     sizeof(sense_conf))) {
740                         printk("%s:error:%d\n", __FUNCTION__, __LINE__);
741                         return -EFAULT;
742                 }
743                 break;
744         default:
745                 break;
746         }
747
748         return result;
749 }
750
751 static struct file_operations compass_dev_fops =
752 {
753         .owner = THIS_MODULE,
754         .open = compass_dev_open,
755         .release = compass_dev_release,
756         .unlocked_ioctl = compass_dev_ioctl,
757 };
758
759
760 static struct miscdevice compass_dev_device =
761 {
762         .minor = MISC_DYNAMIC_MINOR,
763         .name = "akm8963_dev",
764         .fops = &compass_dev_fops,
765 };
766
767 struct sensor_operate compass_akm8963_ops = {
768         .name                           = "akm8963",
769         .type                           = SENSOR_TYPE_COMPASS,  //it is important
770         .id_i2c                         = COMPASS_ID_AK8963,
771         .read_reg                       = AK8963_REG_ST1,       //read data
772         .read_len                       = SENSOR_DATA_SIZE,     //data length
773         .id_reg                         = AK8963_REG_WIA,       //read id
774         .id_data                        = AK8963_DEVICE_ID,
775         .precision                      = 8,                    //12 bits
776         .ctrl_reg                       = AK8963_REG_CNTL1,     //enable or disable
777         .int_status_reg                 = SENSOR_UNKNOW_DATA,   //not exist
778         .range                          = {-0xffff,0xffff},
779         .trig                           = IRQF_TRIGGER_RISING,  //if LEVEL interrupt then IRQF_ONESHOT
780         .active                         = sensor_active,
781         .init                           = sensor_init,
782         .report                         = sensor_report_value,
783         .misc_dev                       = NULL,                 //private misc support
784 };
785
786 /****************operate according to sensor chip:end************/
787
788 //function name should not be changed
789 static struct sensor_operate *compass_get_ops(void)
790 {
791         return &compass_akm8963_ops;
792 }
793
794
795 static int __init compass_akm8963_init(void)
796 {
797         struct sensor_operate *ops = compass_get_ops();
798         int result = 0;
799         int type = ops->type;
800         result = sensor_register_slave(type, NULL, NULL, compass_get_ops);
801
802         return result;
803 }
804
805 static void __exit compass_akm8963_exit(void)
806 {
807         struct sensor_operate *ops = compass_get_ops();
808         int type = ops->type;
809         sensor_unregister_slave(type, NULL, NULL, compass_get_ops);
810 }
811
812
813 module_init(compass_akm8963_init);
814 module_exit(compass_akm8963_exit);
815
816