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 <linux/uaccess.h>
23 #include <linux/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 SENSOR_DATA_SIZE 9
35 #define YPR_DATA_SIZE 16
36 #define RWBUF_SIZE 16
37
38 #define ACC_DATA_FLAG 0
39 #define MAG_DATA_FLAG 1
40 #define ORI_DATA_FLAG 2
41 #define AKM_NUM_SENSORS 3
42
43 #define ACC_DATA_READY (1 << (ACC_DATA_FLAG))
44 #define MAG_DATA_READY (1 << (MAG_DATA_FLAG))
45 #define ORI_DATA_READY (1 << (ORI_DATA_FLAG))
46
47 /*Constant definitions of the AK09911.*/
48 #define AK09911_MEASUREMENT_TIME_US 10000
49
50 #define AK09911_MODE_SNG_MEASURE 0x01
51 #define AK09911_MODE_SELF_TEST 0x10
52 #define AK09911_MODE_FUSE_ACCESS 0x1F
53 #define AK09911_MODE_POWERDOWN 0x00
54 #define AK09911_RESET_DATA 0x01
55
56 /* Device specific constant values */
57 #define AK09911_REG_WIA1 0x00
58 #define AK09911_REG_WIA2 0x01
59 #define AK09911_REG_INFO1 0x02
60 #define AK09911_REG_INFO2 0x03
61 #define AK09911_REG_ST1 0x10
62 #define AK09911_REG_HXL 0x11
63 #define AK09911_REG_HXH 0x12
64 #define AK09911_REG_HYL 0x13
65 #define AK09911_REG_HYH 0x14
66 #define AK09911_REG_HZL 0x15
67 #define AK09911_REG_HZH 0x16
68 #define AK09911_REG_TMPS 0x17
69 #define AK09911_REG_ST2 0x18
70 #define AK09911_REG_CNTL1 0x30
71 #define AK09911_REG_CNTL2 0x31
72 #define AK09911_REG_CNTL3 0x32
73
74 #define AK09911_FUSE_ASAX 0x60
75 #define AK09911_FUSE_ASAY 0x61
76 #define AK09911_FUSE_ASAZ 0x62
77
78 #define AK09911_INFO_SIZE 2
79 #define AK09911_CONF_SIZE 3
80
81 #define COMPASS_IOCTL_MAGIC 'c'
82
83 /* IOCTLs for AKM library */
84 #define ECS_IOCTL_WRITE _IOW(COMPASS_IOCTL_MAGIC, 0x01, char*)
85 #define ECS_IOCTL_READ _IOWR(COMPASS_IOCTL_MAGIC, 0x02, char*)
86 #define ECS_IOCTL_RESET _IO(COMPASS_IOCTL_MAGIC, 0x03) /* NOT used in AK8975 */
87 #define ECS_IOCTL_SET_MODE _IOW(COMPASS_IOCTL_MAGIC, 0x04, short)
88 #define ECS_IOCTL_GETDATA _IOR(COMPASS_IOCTL_MAGIC, 0x05, char[8])
89 #define ECS_IOCTL_SET_YPR _IOW(COMPASS_IOCTL_MAGIC, 0x06, short[12])
90 #define ECS_IOCTL_GET_OPEN_STATUS _IOR(COMPASS_IOCTL_MAGIC, 0x07, int)
91 #define ECS_IOCTL_GET_CLOSE_STATUS _IOR(COMPASS_IOCTL_MAGIC, 0x08, int)
92 #define ECS_IOCTL_GET_LAYOUT _IOR(COMPASS_IOCTL_MAGIC, 0x09, char)
93 #define ECS_IOCTL_GET_ACCEL _IOR(COMPASS_IOCTL_MAGIC, 0x0A, short[3])
94 #define ECS_IOCTL_GET_OUTBIT _IOR(COMPASS_IOCTL_MAGIC, 0x0B, char)
95 #define ECS_IOCTL_GET_INFO _IOR(COMPASS_IOCTL_MAGIC, 0x27, unsigned char[AK09911_INFO_SIZE])
96 #define ECS_IOCTL_GET_CONF _IOR(COMPASS_IOCTL_MAGIC, 0x28, unsigned char[AK09911_CONF_SIZE])
97 #define ECS_IOCTL_GET_PLATFORM_DATA _IOR(COMPASS_IOCTL_MAGIC, 0x0E, struct akm_platform_data)
98 #define ECS_IOCTL_GET_DELAY _IOR(COMPASS_IOCTL_MAGIC, 0x30, short)
99
100 #define AK09911_DEVICE_ID 0x05
101 static struct i2c_client *this_client;
102 static struct miscdevice compass_dev_device;
103
104 static int g_akm_rbuf_ready;
105 static int g_akm_rbuf[12];
106 static char g_sensor_info[AK09911_INFO_SIZE];
107 static char g_sensor_conf[AK09911_CONF_SIZE];
108
109 /****************operate according to sensor chip:start************/
sensor_active(struct i2c_client * client,int enable,int rate)110 static int sensor_active(struct i2c_client *client, int enable, int rate)
111 {
112 struct sensor_private_data *sensor =
113 (struct sensor_private_data *)i2c_get_clientdata(client);
114 int result = 0;
115
116 if (enable)
117 sensor->ops->ctrl_data = AK09911_MODE_SNG_MEASURE;
118 else
119 sensor->ops->ctrl_data = AK09911_MODE_POWERDOWN;
120
121 result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
122 if (result)
123 pr_err("%s:fail to active sensor\n", __func__);
124
125 return result;
126 }
127
sensor_init(struct i2c_client * client)128 static int sensor_init(struct i2c_client *client)
129 {
130 struct sensor_private_data *sensor =
131 (struct sensor_private_data *)i2c_get_clientdata(client);
132 int result = 0;
133
134 this_client = client;
135
136 result = sensor->ops->active(client, 0, 0);
137 if (result) {
138 pr_err("%s:line=%d,error\n", __func__, __LINE__);
139 return result;
140 }
141
142 sensor->status_cur = SENSOR_OFF;
143
144 result = misc_register(&compass_dev_device);
145 if (result < 0) {
146 pr_err("%s:fail to register misc device %s\n", __func__, compass_dev_device.name);
147 result = -1;
148 }
149
150 g_sensor_info[0] = AK09911_REG_WIA1;
151 result = sensor_rx_data(client, g_sensor_info, AK09911_INFO_SIZE);
152 if (result) {
153 pr_err("%s:line=%d,error\n", __func__, __LINE__);
154 return result;
155 }
156
157 g_sensor_conf[0] = AK09911_FUSE_ASAX;
158 result = sensor_rx_data(client, g_sensor_conf, AK09911_CONF_SIZE);
159 if (result) {
160 pr_err("%s:line=%d,error\n", __func__, __LINE__);
161 return result;
162 }
163
164 return result;
165 }
166
compass_report_value(void)167 static void compass_report_value(void)
168 {
169 struct sensor_private_data *sensor =
170 (struct sensor_private_data *)i2c_get_clientdata(this_client);
171 static int flag;
172
173 if (!g_akm_rbuf_ready) {
174 pr_info("g_akm_rbuf not ready..............\n");
175 return;
176 }
177
178 /* Report magnetic vector information */
179 if (atomic_read(&sensor->flags.mv_flag) && (g_akm_rbuf[0] & MAG_DATA_READY)) {
180 /*
181 *input dev will ignore report data if data value is the same with last_value,
182 *sample rate will not enough by this way, so just avoid this case
183 */
184 if ((sensor->axis.x == g_akm_rbuf[5]) &&
185 (sensor->axis.y == g_akm_rbuf[6]) && (sensor->axis.z == g_akm_rbuf[7])) {
186 if (flag) {
187 flag = 0;
188 sensor->axis.x += 1;
189 sensor->axis.y += 1;
190 sensor->axis.z += 1;
191 } else {
192 flag = 1;
193 sensor->axis.x -= 1;
194 sensor->axis.y -= 1;
195 sensor->axis.z -= 1;
196 }
197 } else {
198 sensor->axis.x = g_akm_rbuf[5];
199 sensor->axis.y = g_akm_rbuf[6];
200 sensor->axis.z = g_akm_rbuf[7];
201 }
202 input_report_abs(sensor->input_dev, ABS_HAT0X, sensor->axis.x);
203 input_report_abs(sensor->input_dev, ABS_HAT0Y, sensor->axis.y);
204 input_report_abs(sensor->input_dev, ABS_BRAKE, sensor->axis.z);
205 input_report_abs(sensor->input_dev, ABS_HAT1X, g_akm_rbuf[8]);
206 }
207 input_sync(sensor->input_dev);
208 }
209
sensor_report_value(struct i2c_client * client)210 static int sensor_report_value(struct i2c_client *client)
211 {
212 struct sensor_private_data *sensor = (struct sensor_private_data *)i2c_get_clientdata(client);
213 char buffer[SENSOR_DATA_SIZE] = {0};
214 unsigned char *stat;
215 unsigned char *stat2;
216 int ret = 0;
217 char value = 0;
218
219 mutex_lock(&sensor->data_mutex);
220 compass_report_value();
221 mutex_unlock(&sensor->data_mutex);
222
223 if (sensor->ops->read_len < SENSOR_DATA_SIZE) {
224 pr_err("%s:length is error,len=%d\n", __func__, sensor->ops->read_len);
225 return -1;
226 }
227
228 memset(buffer, 0, SENSOR_DATA_SIZE);
229
230 /* Data bytes from hardware xL, xH, yL, yH, zL, zH */
231 do {
232 *buffer = sensor->ops->read_reg;
233 ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
234 if (ret < 0)
235 return ret;
236 } while (0);
237
238 stat = &buffer[0];
239 stat2 = &buffer[7];
240
241 /*
242 * ST : data ready -
243 * Measurement has been completed and data is ready to be read.
244 */
245 if ((*stat & 0x01) != 0x01) {
246 pr_err("%s:ST is not set\n", __func__);
247 return -1;
248 }
249
250 mutex_lock(&sensor->data_mutex);
251 memcpy(sensor->sensor_data, buffer, sensor->ops->read_len);
252 mutex_unlock(&sensor->data_mutex);
253
254 if ((sensor->pdata->irq_enable) && (sensor->ops->int_status_reg >= 0))
255 value = sensor_read_reg(client, sensor->ops->int_status_reg);
256
257 /* trigger next measurement */
258 ret = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
259 if (ret) {
260 pr_err("%s:fail to set ctrl_data:0x%x\n", __func__, sensor->ops->ctrl_data);
261 return ret;
262 }
263
264 return ret;
265 }
266
compass_set_YPR(int * rbuf)267 static void compass_set_YPR(int *rbuf)
268 {
269 /* No events are reported */
270 if (!rbuf[0]) {
271 pr_info("%s:Don't waste a time.", __func__);
272 return;
273 }
274
275 g_akm_rbuf_ready = 1;
276 memcpy(g_akm_rbuf, rbuf, 12 * sizeof(int));
277 }
278
compass_dev_open(struct inode * inode,struct file * file)279 static int compass_dev_open(struct inode *inode, struct file *file)
280 {
281 return 0;
282 }
283
compass_dev_release(struct inode * inode,struct file * file)284 static int compass_dev_release(struct inode *inode, struct file *file)
285 {
286 return 0;
287 }
288
compass_akm_set_mode(struct i2c_client * client,char mode)289 static int compass_akm_set_mode(struct i2c_client *client, char mode)
290 {
291 struct sensor_private_data *sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
292 int result = 0;
293
294 switch (mode & 0x1f) {
295 case AK09911_MODE_SNG_MEASURE:
296 case AK09911_MODE_SELF_TEST:
297 case AK09911_MODE_FUSE_ACCESS:
298 if (sensor->status_cur == SENSOR_OFF) {
299 sensor->stop_work = 0;
300 sensor->status_cur = SENSOR_ON;
301 pr_info("compass ak09911 start measure");
302 schedule_delayed_work(&sensor->delaywork, 0);
303 }
304 break;
305
306 case AK09911_MODE_POWERDOWN:
307 if (sensor->status_cur == SENSOR_ON) {
308 sensor->stop_work = 1;
309 cancel_delayed_work_sync(&sensor->delaywork);
310 pr_info("compass ak09911 stop measure");
311 g_akm_rbuf_ready = 0;
312 sensor->status_cur = SENSOR_OFF;
313 }
314 break;
315 }
316
317 switch (mode & 0x1f) {
318 case AK09911_MODE_SNG_MEASURE:
319 result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SNG_MEASURE);
320 if (result)
321 pr_err("%s:i2c error,mode=%d\n", __func__, mode);
322 break;
323 case AK09911_MODE_SELF_TEST:
324 result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SELF_TEST);
325 if (result)
326 pr_err("%s:i2c error,mode=%d\n", __func__, mode);
327 break;
328 case AK09911_MODE_FUSE_ACCESS:
329 result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_FUSE_ACCESS);
330 if (result)
331 pr_err("%s:i2c error,mode=%d\n", __func__, mode);
332 break;
333 case AK09911_MODE_POWERDOWN:
334 /* Set powerdown mode */
335 result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_POWERDOWN);
336 if (result)
337 pr_err("%s:i2c error,mode=%d\n", __func__, mode);
338 udelay(100);
339 break;
340 default:
341 pr_info("%s: Unknown mode(%d)", __func__, mode);
342 result = -EINVAL;
343 break;
344 }
345 return result;
346 }
347
compass_akm_reset(struct i2c_client * client)348 static int compass_akm_reset(struct i2c_client *client)
349 {
350 struct sensor_private_data *sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
351 int result = 0;
352
353 if (sensor->pdata->reset_pin > 0) {
354 gpio_direction_output(sensor->pdata->reset_pin, GPIO_LOW);
355 udelay(10);
356 gpio_direction_output(sensor->pdata->reset_pin, GPIO_HIGH);
357 } else {
358 /* Set measure mode */
359 result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SNG_MEASURE);
360 if (result)
361 pr_err("%s:fail to Set measure mode\n", __func__);
362 }
363
364 udelay(100);
365
366 return result;
367 }
368
compass_akm_get_openstatus(void)369 static int compass_akm_get_openstatus(void)
370 {
371 struct sensor_private_data *sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
372
373 wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) != 0));
374
375 return atomic_read(&sensor->flags.open_flag);
376 }
377
compass_akm_get_closestatus(void)378 static int compass_akm_get_closestatus(void)
379 {
380 struct sensor_private_data *sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
381
382 wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) <= 0));
383
384 return atomic_read(&sensor->flags.open_flag);
385 }
386
387 /* ioctl - I/O control */
compass_dev_ioctl(struct file * file,unsigned int cmd,unsigned long arg)388 static long compass_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
389 {
390 struct sensor_private_data *sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
391 struct i2c_client *client = this_client;
392 void __user *argp = (void __user *)arg;
393 int result = 0;
394 struct akm_platform_data compass;
395
396 /* NOTE: In this function the size of "char" should be 1-byte. */
397 char compass_data[SENSOR_DATA_SIZE]; /* for GETDATA */
398 char rwbuf[RWBUF_SIZE]; /* for READ/WRITE */
399 char mode; /* for SET_MODE*/
400 int value[YPR_DATA_SIZE]; /* for SET_YPR */
401 int status; /* for OPEN/CLOSE_STATUS */
402 int ret = -1; /* Return value. */
403
404 int16_t acc_buf[3]; /* for GET_ACCEL */
405 int64_t delay[AKM_NUM_SENSORS]; /* for GET_DELAY */
406 char layout; /* for GET_LAYOUT */
407 char outbit; /* for GET_OUTBIT */
408
409 switch (cmd) {
410 case ECS_IOCTL_WRITE:
411 case ECS_IOCTL_READ:
412 if (!argp)
413 return -EINVAL;
414 if (copy_from_user(&rwbuf, argp, sizeof(rwbuf)))
415 return -EFAULT;
416 break;
417 case ECS_IOCTL_SET_MODE:
418 if (!argp)
419 return -EINVAL;
420 if (copy_from_user(&mode, argp, sizeof(mode)))
421 return -EFAULT;
422 break;
423 case ECS_IOCTL_SET_YPR:
424 if (!argp)
425 return -EINVAL;
426 if (copy_from_user(&value, argp, sizeof(value)))
427 return -EFAULT;
428 break;
429 case ECS_IOCTL_GETDATA:
430 case ECS_IOCTL_GET_OPEN_STATUS:
431 case ECS_IOCTL_GET_CLOSE_STATUS:
432 case ECS_IOCTL_GET_DELAY:
433 case ECS_IOCTL_GET_LAYOUT:
434 case ECS_IOCTL_GET_OUTBIT:
435 case ECS_IOCTL_GET_ACCEL:
436 case ECS_IOCTL_GET_INFO:
437 case ECS_IOCTL_GET_CONF:
438 /* Just check buffer pointer */
439 if (!argp) {
440 pr_err("%s:invalid argument\n", __func__);
441 return -EINVAL;
442 }
443 break;
444 default:
445 break;
446 }
447
448 switch (cmd) {
449 case ECS_IOCTL_WRITE:
450 mutex_lock(&sensor->operation_mutex);
451 if ((rwbuf[0] < 2) || (rwbuf[0] > (RWBUF_SIZE - 1))) {
452 mutex_unlock(&sensor->operation_mutex);
453 return -EINVAL;
454 }
455 ret = sensor_tx_data(client, &rwbuf[1], rwbuf[0]);
456 if (ret < 0) {
457 mutex_unlock(&sensor->operation_mutex);
458 pr_err("%s:fait to tx data\n", __func__);
459 return ret;
460 }
461 mutex_unlock(&sensor->operation_mutex);
462 break;
463 case ECS_IOCTL_READ:
464 mutex_lock(&sensor->operation_mutex);
465 if ((rwbuf[0] < 1) || (rwbuf[0] > (RWBUF_SIZE - 1))) {
466 mutex_unlock(&sensor->operation_mutex);
467 pr_err("%s:data is error\n", __func__);
468 return -EINVAL;
469 }
470 ret = sensor_rx_data(client, &rwbuf[1], rwbuf[0]);
471 if (ret < 0) {
472 mutex_unlock(&sensor->operation_mutex);
473 pr_err("%s:fait to rx data\n", __func__);
474 return ret;
475 }
476 mutex_unlock(&sensor->operation_mutex);
477 break;
478 case ECS_IOCTL_SET_MODE:
479 mutex_lock(&sensor->operation_mutex);
480 if (sensor->ops->ctrl_data != mode) {
481 ret = compass_akm_set_mode(client, mode);
482 if (ret < 0) {
483 pr_err("%s:fait to set mode\n", __func__);
484 mutex_unlock(&sensor->operation_mutex);
485 return ret;
486 }
487
488 sensor->ops->ctrl_data = mode;
489 }
490 mutex_unlock(&sensor->operation_mutex);
491 break;
492 case ECS_IOCTL_GETDATA:
493 mutex_lock(&sensor->data_mutex);
494 memcpy(compass_data, sensor->sensor_data, SENSOR_DATA_SIZE);
495 mutex_unlock(&sensor->data_mutex);
496 break;
497 case ECS_IOCTL_SET_YPR:
498 mutex_lock(&sensor->data_mutex);
499 compass_set_YPR(value);
500 mutex_unlock(&sensor->data_mutex);
501 break;
502 case ECS_IOCTL_GET_OPEN_STATUS:
503 status = compass_akm_get_openstatus();
504 break;
505 case ECS_IOCTL_GET_CLOSE_STATUS:
506 status = compass_akm_get_closestatus();
507 break;
508 case ECS_IOCTL_GET_DELAY:
509 mutex_lock(&sensor->operation_mutex);
510 delay[0] = sensor->flags.delay;
511 delay[1] = sensor->flags.delay;
512 delay[2] = sensor->flags.delay;
513 mutex_unlock(&sensor->operation_mutex);
514 break;
515
516 case ECS_IOCTL_GET_PLATFORM_DATA:
517 ret = copy_to_user(argp, &compass, sizeof(compass));
518 if (ret < 0) {
519 pr_err("%s:error,ret=%d\n", __func__, ret);
520 return ret;
521 }
522 break;
523 case ECS_IOCTL_GET_LAYOUT:
524 if ((sensor->pdata->layout >= 1) && (sensor->pdata->layout <= 8))
525 layout = sensor->pdata->layout;
526 else
527 layout = 1;
528 break;
529 case ECS_IOCTL_GET_OUTBIT:
530 outbit = 1;
531 break;
532 case ECS_IOCTL_RESET:
533 ret = compass_akm_reset(client);
534 if (ret < 0)
535 return ret;
536 break;
537 case ECS_IOCTL_GET_ACCEL:
538 break;
539 case ECS_IOCTL_GET_INFO:
540 ret = copy_to_user(argp, g_sensor_info, sizeof(g_sensor_info));
541 if (ret < 0) {
542 pr_err("%s:error,ret=%d\n", __func__, ret);
543 return ret;
544 }
545 break;
546 case ECS_IOCTL_GET_CONF:
547 ret = copy_to_user(argp, g_sensor_conf, sizeof(g_sensor_conf));
548 if (ret < 0) {
549 pr_err("%s:error,ret=%d\n", __func__, ret);
550 return ret;
551 }
552 break;
553
554 default:
555 return -ENOTTY;
556 }
557
558 switch (cmd) {
559 case ECS_IOCTL_READ:
560 if (copy_to_user(argp, &rwbuf, rwbuf[0] + 1))
561 return -EFAULT;
562 break;
563 case ECS_IOCTL_GETDATA:
564 if (copy_to_user(argp, &compass_data, sizeof(compass_data)))
565 return -EFAULT;
566 break;
567 case ECS_IOCTL_GET_OPEN_STATUS:
568 case ECS_IOCTL_GET_CLOSE_STATUS:
569 if (copy_to_user(argp, &status, sizeof(status)))
570 return -EFAULT;
571 break;
572 case ECS_IOCTL_GET_DELAY:
573 if (copy_to_user(argp, &delay, sizeof(delay)))
574 return -EFAULT;
575 break;
576 case ECS_IOCTL_GET_LAYOUT:
577 if (copy_to_user(argp, &layout, sizeof(layout))) {
578 pr_err("%s:error:%d\n", __func__, __LINE__);
579 return -EFAULT;
580 }
581 break;
582 case ECS_IOCTL_GET_OUTBIT:
583 if (copy_to_user(argp, &outbit, sizeof(outbit))) {
584 pr_err("%s:error:%d\n", __func__, __LINE__);
585 return -EFAULT;
586 }
587 break;
588 case ECS_IOCTL_GET_ACCEL:
589 if (copy_to_user(argp, &acc_buf, sizeof(acc_buf))) {
590 pr_err("%s:error:%d\n", __func__, __LINE__);
591 return -EFAULT;
592 }
593 break;
594 default:
595 break;
596 }
597
598 return result;
599 }
600
601 static const struct file_operations compass_dev_fops = {
602 .owner = THIS_MODULE,
603 .open = compass_dev_open,
604 .release = compass_dev_release,
605 .unlocked_ioctl = compass_dev_ioctl,
606 };
607
608 static struct miscdevice compass_dev_device = {
609 .minor = MISC_DYNAMIC_MINOR,
610 .name = "akm_dev",
611 .fops = &compass_dev_fops,
612 };
613
614 static struct sensor_operate compass_akm09911_ops = {
615 .name = "akm09911",
616 .type = SENSOR_TYPE_COMPASS,
617 .id_i2c = COMPASS_ID_AK09911,
618 .read_reg = AK09911_REG_ST1,
619 .read_len = SENSOR_DATA_SIZE,
620 .id_reg = AK09911_REG_WIA2,
621 .id_data = AK09911_DEVICE_ID,
622 .precision = 8,
623 .ctrl_reg = AK09911_REG_CNTL2,
624 .int_status_reg = SENSOR_UNKNOW_DATA,
625 .range = {-0xffff, 0xffff},
626 .trig = IRQF_TRIGGER_RISING,
627 .active = sensor_active,
628 .init = sensor_init,
629 .report = sensor_report_value,
630 .misc_dev = NULL,
631 };
632
633 /****************operate according to sensor chip:end************/
compass_akm09911_probe(struct i2c_client * client,const struct i2c_device_id * devid)634 static int compass_akm09911_probe(struct i2c_client *client,
635 const struct i2c_device_id *devid)
636 {
637 return sensor_register_device(client, NULL, devid, &compass_akm09911_ops);
638 }
639
compass_akm09911_remove(struct i2c_client * client)640 static int compass_akm09911_remove(struct i2c_client *client)
641 {
642 return sensor_unregister_device(client, NULL, &compass_akm09911_ops);
643 }
644
645 static const struct i2c_device_id compass_akm09911_id[] = {
646 {"ak09911", COMPASS_ID_AK09911},
647 {}
648 };
649
650 static struct i2c_driver compass_akm09911_driver = {
651 .probe = compass_akm09911_probe,
652 .remove = compass_akm09911_remove,
653 .shutdown = sensor_shutdown,
654 .id_table = compass_akm09911_id,
655 .driver = {
656 .name = "compass_akm09911",
657 #ifdef CONFIG_PM
658 .pm = &sensor_pm_ops,
659 #endif
660 },
661 };
662
663 module_i2c_driver(compass_akm09911_driver);
664
665 MODULE_AUTHOR("luowei <lw@rock-chips.com>");
666 MODULE_DESCRIPTION("akm09911 3-Axis compasss driver");
667 MODULE_LICENSE("GPL");
668