1 /* drivers/input/sensors/access/akm09911.c
3 * Copyright (C) 2012-2015 ROCKCHIP.
4 * Author: luowei <lw@rock-chips.com>
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.
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.
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>
32 #include <linux/sensor-dev.h>
36 #define SENSOR_DATA_SIZE 9
37 #define YPR_DATA_SIZE 16
40 #define ACC_DATA_FLAG 0
41 #define MAG_DATA_FLAG 1
42 #define ORI_DATA_FLAG 2
43 #define AKM_NUM_SENSORS 3
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))
49 /*Constant definitions of the AK09911.*/
50 #define AK09911_MEASUREMENT_TIME_US 10000
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
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
78 #define AK09911_FUSE_ASAX 0x60
79 #define AK09911_FUSE_ASAY 0x61
80 #define AK09911_FUSE_ASAZ 0x62
82 #define AK09911_INFO_SIZE 2
83 #define AK09911_CONF_SIZE 3
87 #define COMPASS_IOCTL_MAGIC 'c'
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)
108 #define AK09911_DEVICE_ID 0x05
109 static struct i2c_client *this_client;
110 static struct miscdevice compass_dev_device;
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];
117 /****************operate according to sensor chip:start************/
119 static int sensor_active(struct i2c_client *client, int enable, int rate)
121 struct sensor_private_data *sensor =
122 (struct sensor_private_data *) i2c_get_clientdata(client);
125 //sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
127 //register setting according to chip datasheet
130 sensor->ops->ctrl_data = AK09911_MODE_SNG_MEASURE;
134 sensor->ops->ctrl_data = AK09911_MODE_POWERDOWN;
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);
140 printk("%s:fail to active sensor\n",__func__);
146 static int sensor_init(struct i2c_client *client)
148 struct sensor_private_data *sensor =
149 (struct sensor_private_data *) i2c_get_clientdata(client);
152 this_client = client;
154 result = sensor->ops->active(client,0,0);
157 printk("%s:line=%d,error\n",__func__,__LINE__);
161 sensor->status_cur = SENSOR_OFF;
163 result = misc_register(&compass_dev_device);
165 printk("%s:fail to register misc device %s\n", __func__, compass_dev_device.name);
169 g_sensor_info[0] = AK09911_REG_WIA1;
170 result = sensor_rx_data(client, g_sensor_info, AK09911_INFO_SIZE);
173 printk("%s:line=%d,error\n",__func__,__LINE__);
178 g_sensor_conf[0] = AK09911_FUSE_ASAX;
179 result = sensor_rx_data(client, g_sensor_conf, AK09911_CONF_SIZE);
182 printk("%s:line=%d,error\n",__func__,__LINE__);
186 DBG("%s:status_cur=%d\n",__func__, sensor->status_cur);
190 static int sensor_report_value(struct i2c_client *client)
192 struct sensor_private_data *sensor =
193 (struct sensor_private_data *) i2c_get_clientdata(client);
194 char buffer[SENSOR_DATA_SIZE] = {0};
196 unsigned char *stat2;
201 if(sensor->ops->read_len < SENSOR_DATA_SIZE) //sensor->ops->read_len = 8
203 printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
207 memset(buffer, 0, SENSOR_DATA_SIZE);
209 /* Data bytes from hardware xL, xH, yL, yH, zL, zH */
211 *buffer = sensor->ops->read_reg;
212 ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
222 * Measurement has been completed and data is ready to be read.
224 if ((*stat & 0x01) != 0x01) {
225 DBG(KERN_ERR "%s:ST is not set\n",__func__);
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
237 * DERR bit is self-clearing when ST2 register is read.
241 DBG(KERN_ERR "%s:compass data error\n",__func__);
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
251 * An error is returned.
252 * HOFL bit clears when a new measurement starts.
256 DBG(KERN_ERR "%s:compass data overflow\n",__func__);
260 /* »¥³âµØ»º´æÊý¾Ý. */
261 mutex_lock(&sensor->data_mutex);
262 memcpy(sensor->sensor_data, buffer, sensor->ops->read_len);
263 mutex_unlock(&sensor->data_mutex);
265 for(i=0; i<sensor->ops->read_len; i++)
266 DBG("0x%x,",buffer[i]);
269 if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register
272 value = sensor_read_reg(client, sensor->ops->int_status_reg);
273 DBG("%s:sensor int status :0x%x\n",__func__,value);
277 //trigger next measurement
278 ret = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
281 printk(KERN_ERR "%s:fail to set ctrl_data:0x%x\n",__func__,sensor->ops->ctrl_data);
288 static void compass_set_YPR(int *rbuf)
290 struct sensor_private_data *sensor =
291 (struct sensor_private_data *) i2c_get_clientdata(this_client);
293 /* No events are reported */
295 printk("%s:Don't waste a time.",__func__);
299 DBG("%s:buf[0]=0x%x\n",__func__, rbuf[0]);
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]);
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]);
317 DBG("%s:a_flag:x=%d,y=%d,z=%d,WHEEL=%d\n",__func__,rbuf[1], rbuf[2], rbuf[3], rbuf[4]);
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]);
327 DBG("%s:mv_flag:x=%d,y=%d,z=%d,status=%d\n",__func__,rbuf[5], rbuf[6], rbuf[7], rbuf[8]);
330 input_sync(sensor->input_dev);
332 memcpy(g_akm_rbuf, rbuf, 12); //used for ECS_IOCTL_GET_ACCEL
337 static int compass_dev_open(struct inode *inode, struct file *file)
339 struct sensor_private_data* sensor =
340 (struct sensor_private_data *)i2c_get_clientdata(this_client);
342 DBG("%s\n",__func__);
348 static int compass_dev_release(struct inode *inode, struct file *file)
350 struct sensor_private_data* sensor =
351 (struct sensor_private_data *)i2c_get_clientdata(this_client);
353 DBG("%s\n",__func__);
358 static int compass_akm_set_mode(struct i2c_client *client, char mode)
360 struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
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)
370 if(sensor->pdata->irq_enable)
372 //DBG("%s:enable irq=%d\n",__func__,client->irq);
373 //enable_irq(client->irq);
377 schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));
380 sensor->status_cur = SENSOR_ON;
385 case AK09911_MODE_POWERDOWN:
386 if(sensor->status_cur == SENSOR_ON)
388 if(sensor->pdata->irq_enable)
390 //DBG("%s:disable irq=%d\n",__func__,client->irq);
391 //disable_irq_nosync(client->irq);//disable irq
394 cancel_delayed_work_sync(&sensor->delaywork);
396 sensor->status_cur = SENSOR_OFF;
404 case AK09911_MODE_SNG_MEASURE:
405 result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SNG_MEASURE);
407 printk("%s:i2c error,mode=%d\n",__func__,mode);
409 case AK09911_MODE_SELF_TEST:
410 result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SELF_TEST);
412 printk("%s:i2c error,mode=%d\n",__func__,mode);
414 case AK09911_MODE_FUSE_ACCESS:
415 result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_FUSE_ACCESS);
417 printk("%s:i2c error,mode=%d\n",__func__,mode);
419 case AK09911_MODE_POWERDOWN:
420 /* Set powerdown mode */
421 result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_POWERDOWN);
423 printk("%s:i2c error,mode=%d\n",__func__,mode);
427 printk("%s: Unknown mode(%d)", __func__, mode);
431 DBG("%s:mode=0x%x\n",__func__,mode);
436 static int compass_akm_reset(struct i2c_client *client)
438 struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
441 if(sensor->pdata->reset_pin > 0)
443 gpio_direction_output(sensor->pdata->reset_pin, GPIO_LOW);
445 gpio_direction_output(sensor->pdata->reset_pin, GPIO_HIGH);
449 /* Set measure mode */
450 result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SNG_MEASURE);
452 printk("%s:fail to Set measure mode\n",__func__);
463 static int compass_akm_get_openstatus(void)
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);
470 static int compass_akm_get_closestatus(void)
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);
478 /* ioctl - I/O control */
479 static long compass_dev_ioctl(struct file *file,
480 unsigned int cmd, unsigned long arg)
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;
486 struct akm_platform_data compass;
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. */
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 */
504 case ECS_IOCTL_WRITE:
509 if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) {
513 case ECS_IOCTL_SET_MODE:
517 if (copy_from_user(&mode, argp, sizeof(mode))) {
521 case ECS_IOCTL_SET_YPR:
525 if (copy_from_user(&value, argp, sizeof(value))) {
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 */
540 printk("%s:invalid argument\n",__func__);
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);
556 ret = sensor_tx_data(client, &rwbuf[1], rwbuf[0]);
558 mutex_unlock(&sensor->operation_mutex);
559 printk("%s:fait to tx data\n",__func__);
562 mutex_unlock(&sensor->operation_mutex);
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__);
572 ret = sensor_rx_data(client, &rwbuf[1], rwbuf[0]);
574 mutex_unlock(&sensor->operation_mutex);
575 printk("%s:fait to rx data\n",__func__);
578 mutex_unlock(&sensor->operation_mutex);
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)
585 ret = compass_akm_set_mode(client, mode);
587 printk("%s:fait to set mode\n",__func__);
588 mutex_unlock(&sensor->operation_mutex);
592 sensor->ops->ctrl_data = mode;
594 mutex_unlock(&sensor->operation_mutex);
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);
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);
608 case ECS_IOCTL_GET_OPEN_STATUS:
609 status = compass_akm_get_openstatus();
610 DBG("%s:openstatus=%d\n",__func__,status);
612 case ECS_IOCTL_GET_CLOSE_STATUS:
613 status = compass_akm_get_closestatus();
614 DBG("%s:closestatus=%d\n",__func__,status);
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);
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));
632 printk("%s:error,ret=%d\n",__FUNCTION__, ret);
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;
643 case ECS_IOCTL_GET_OUTBIT:
644 DBG("%s:ECS_IOCTL_GET_OUTBIT start\n",__func__);
645 outbit = 1; //sensor->pdata->outbit;
647 case ECS_IOCTL_RESET:
648 DBG("%s:ECS_IOCTL_RESET start\n",__func__);
649 ret = compass_akm_reset(client);
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);
661 case ECS_IOCTL_GET_INFO:
662 ret = copy_to_user(argp, g_sensor_info, sizeof(g_sensor_info));
665 printk("%s:error,ret=%d\n",__FUNCTION__, ret);
669 case ECS_IOCTL_GET_CONF:
670 ret = copy_to_user(argp, g_sensor_conf, sizeof(g_sensor_conf));
673 printk("%s:error,ret=%d\n",__FUNCTION__, ret);
684 if (copy_to_user(argp, &rwbuf, rwbuf[0]+1)) {
688 case ECS_IOCTL_GETDATA:
689 if (copy_to_user(argp, &compass_data, sizeof(compass_data))) {
693 case ECS_IOCTL_GET_OPEN_STATUS:
694 case ECS_IOCTL_GET_CLOSE_STATUS:
695 if (copy_to_user(argp, &status, sizeof(status))) {
699 case ECS_IOCTL_GET_DELAY:
700 if (copy_to_user(argp, &delay, sizeof(delay))) {
704 case ECS_IOCTL_GET_LAYOUT:
705 if (copy_to_user(argp, &layout, sizeof(layout))) {
706 printk("%s:error:%d\n",__FUNCTION__,__LINE__);
710 case ECS_IOCTL_GET_OUTBIT:
711 if (copy_to_user(argp, &outbit, sizeof(outbit))) {
712 printk("%s:error:%d\n",__FUNCTION__,__LINE__);
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__);
729 static struct file_operations compass_dev_fops =
731 .owner = THIS_MODULE,
732 .open = compass_dev_open,
733 .release = compass_dev_release,
734 .unlocked_ioctl = compass_dev_ioctl,
738 static struct miscdevice compass_dev_device =
740 .minor = MISC_DYNAMIC_MINOR,
742 .fops = &compass_dev_fops,
745 struct sensor_operate compass_akm09911_ops = {
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,
760 .report = sensor_report_value,
761 .misc_dev = NULL, //private misc support
764 /****************operate according to sensor chip:end************/
766 //function name should not be changed
767 static struct sensor_operate *compass_get_ops(void)
769 return &compass_akm09911_ops;
773 static int __init compass_akm09911_init(void)
775 struct sensor_operate *ops = compass_get_ops();
777 int type = ops->type;
778 result = sensor_register_slave(type, NULL, NULL, compass_get_ops);
783 static void __exit compass_akm09911_exit(void)
785 struct sensor_operate *ops = compass_get_ops();
786 int type = ops->type;
787 sensor_unregister_slave(type, NULL, NULL, compass_get_ops);
791 module_init(compass_akm09911_init);
792 module_exit(compass_akm09911_exit);