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 <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 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 #define AK8963_MEASUREMENT_TIME_US 10000
50
51 #define AK8963_MODE_SNG_MEASURE 0x01
52 #define AK8963_MODE_SELF_TEST 0x08
53 #define AK8963_MODE_FUSE_ACCESS 0x0F
54 #define AK8963_MODE_POWERDOWN 0x00
55
56 #define AK8963_REG_WIA 0x00
57 #define AK8963_REG_INFO 0x01
58 #define AK8963_REG_ST1 0x02
59 #define AK8963_REG_HXL 0x03
60 #define AK8963_REG_HXH 0x04
61 #define AK8963_REG_HYL 0x05
62 #define AK8963_REG_HYH 0x06
63 #define AK8963_REG_HZL 0x07
64 #define AK8963_REG_HZH 0x08
65 #define AK8963_REG_ST2 0x09
66 #define AK8963_REG_CNTL1 0x0A
67 #define AK8963_REG_CNTL2 0x0B
68 #define AK8963_REG_ASTC 0x0C
69 #define AK8963_REG_TS1 0x0D
70 #define AK8963_REG_TS2 0x0E
71 #define AK8963_REG_I2CDIS 0x0F
72
73 #define AK8963_WIA_VALUE 0x48
74
75 #define AK8963_FUSE_ASAX 0x10
76 #define AK8963_FUSE_ASAY 0x11
77 #define AK8963_FUSE_ASAZ 0x12
78
79 #define AK8963_INFO_DATA (0x03 << 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)
87 #define ECS_IOCTL_SET_MODE _IOW(COMPASS_IOCTL_MAGIC, 0x04, short)
88 #define ECS_IOCTL_GETDATA _IOR(COMPASS_IOCTL_MAGIC, 0x05, char[SENSOR_DATA_SIZE])
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_DELAY _IOR(COMPASS_IOCTL_MAGIC, 0x30, short)
96 #define ECS_IOCTL_GET_PROJECT_NAME _IOR(COMPASS_IOCTL_MAGIC, 0x0D, char[64])
97 #define ECS_IOCTL_GET_MATRIX _IOR(COMPASS_IOCTL_MAGIC, 0x0E, short [4][3][3])
98 #define ECS_IOCTL_GET_PLATFORM_DATA _IOR(COMPASS_IOCTL_MAGIC, 0x0E, struct akm_platform_data)
99 #define ECS_IOCTL_GET_INFO _IOR(COMPASS_IOCTL_MAGIC, 0x27, unsigned char[AKM_SENSOR_INFO_SIZE])
100 #define ECS_IOCTL_GET_CONF _IOR(COMPASS_IOCTL_MAGIC, 0x28, unsigned char[AKM_SENSOR_CONF_SIZE])
101
102 #define AK8963_DEVICE_ID 0x48
103 static struct i2c_client *this_client;
104 static struct miscdevice compass_dev_device;
105
106 static int g_akm_rbuf_ready;
107 static int g_akm_rbuf[12];
108
109 /****************operate according to sensor chip:start************/
110
sensor_active(struct i2c_client * client,int enable,int rate)111 static int sensor_active(struct i2c_client *client, int enable, int rate)
112 {
113 struct sensor_private_data *sensor =
114 (struct sensor_private_data *)i2c_get_clientdata(client);
115 int result = 0;
116
117 if (enable)
118 sensor->ops->ctrl_data = AK8963_MODE_SNG_MEASURE;
119 else
120 sensor->ops->ctrl_data = AK8963_MODE_POWERDOWN;
121
122 result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
123 if (result)
124 pr_err("%s:fail to active sensor\n", __func__);
125
126 return result;
127 }
128
sensor_init(struct i2c_client * client)129 static int sensor_init(struct i2c_client *client)
130 {
131 struct sensor_private_data *sensor =
132 (struct sensor_private_data *)i2c_get_clientdata(client);
133 int result = 0;
134 char info = 0;
135
136 this_client = client;
137
138 result = sensor->ops->active(client, 0, 0);
139 if (result) {
140 pr_err("%s:line=%d,error\n", __func__, __LINE__);
141 return result;
142 }
143
144 sensor->status_cur = SENSOR_OFF;
145
146 info = sensor_read_reg(client, AK8963_REG_INFO);
147 if ((info & (0x0f << 3)) != AK8963_INFO_DATA) {
148 pr_err("%s:info=0x%x,it is not %s\n", __func__, info, sensor->ops->name);
149 return -1;
150 }
151
152 result = misc_register(&compass_dev_device);
153 if (result < 0) {
154 pr_err("%s:fail to register misc device %s\n", __func__, compass_dev_device.name);
155 result = -1;
156 }
157
158 return result;
159 }
160
compass_report_value(void)161 static void compass_report_value(void)
162 {
163 struct sensor_private_data *sensor =
164 (struct sensor_private_data *)i2c_get_clientdata(this_client);
165 static int flag;
166
167 if (!g_akm_rbuf_ready) {
168 pr_info("g_akm_rbuf not ready..............\n");
169 return;
170 }
171
172 /* Report magnetic vector information */
173 if (atomic_read(&sensor->flags.mv_flag) && (g_akm_rbuf[0] & MAG_DATA_READY)) {
174 /*
175 *input dev will ignore report data if data value is the same with last_value,
176 *sample rate will not enough by this way, so just avoid this case
177 */
178 if ((sensor->axis.x == g_akm_rbuf[5]) &&
179 (sensor->axis.y == g_akm_rbuf[6]) && (sensor->axis.z == g_akm_rbuf[7])) {
180 if (flag) {
181 flag = 0;
182 sensor->axis.x += 1;
183 sensor->axis.y += 1;
184 sensor->axis.z += 1;
185 } else {
186 flag = 1;
187 sensor->axis.x -= 1;
188 sensor->axis.y -= 1;
189 sensor->axis.z -= 1;
190 }
191 } else {
192 sensor->axis.x = g_akm_rbuf[5];
193 sensor->axis.y = g_akm_rbuf[6];
194 sensor->axis.z = g_akm_rbuf[7];
195 }
196 input_report_abs(sensor->input_dev, ABS_HAT0X, sensor->axis.x);
197 input_report_abs(sensor->input_dev, ABS_HAT0Y, sensor->axis.y);
198 input_report_abs(sensor->input_dev, ABS_BRAKE, sensor->axis.z);
199 input_report_abs(sensor->input_dev, ABS_HAT1X, g_akm_rbuf[8]);
200 }
201 input_sync(sensor->input_dev);
202 }
203
sensor_report_value(struct i2c_client * client)204 static int sensor_report_value(struct i2c_client *client)
205 {
206 struct sensor_private_data *sensor = (struct sensor_private_data *)i2c_get_clientdata(client);
207 char buffer[8] = {0};
208 unsigned char *stat;
209 unsigned char *stat2;
210 int ret = 0;
211 char value = 0;
212
213 mutex_lock(&sensor->data_mutex);
214 compass_report_value();
215 mutex_unlock(&sensor->data_mutex);
216
217 if (sensor->ops->read_len < 8) {
218 pr_err("%s:length is error,len=%d\n", __func__, sensor->ops->read_len);
219 return -1;
220 }
221
222 memset(buffer, 0, 8);
223
224 /* Data bytes from hardware xL, xH, yL, yH, zL, zH */
225 do {
226 *buffer = sensor->ops->read_reg;
227 ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
228 if (ret < 0)
229 return ret;
230 } while (0);
231
232 stat = &buffer[0];
233 stat2 = &buffer[7];
234
235 /*
236 * ST : data ready -
237 * Measurement has been completed and data is ready to be read.
238 */
239 if ((*stat & 0x01) != 0x01) {
240 pr_err("%s:ST is not set\n", __func__);
241 return -1;
242 }
243
244 /*
245 * ST2 : data error -
246 * occurs when data read is started outside of a readable period;
247 * data read would not be correct.
248 * Valid in continuous measurement mode only.
249 * In single measurement mode this error should not occour but we
250 * stil account for it and return an error, since the data would be
251 * corrupted.
252 * DERR bit is self-clearing when ST2 register is read.
253 */
254 if (*stat2 & 0x04) {
255 pr_err("%s:compass data error\n", __func__);
256 return -2;
257 }
258
259 /*
260 * ST2 : overflow -
261 * the sum of the absolute values of all axis |X|+|Y|+|Z| < 2400uT.
262 * This is likely to happen in presence of an external magnetic
263 * disturbance; it indicates, the sensor data is incorrect and should
264 * be ignored.
265 * An error is returned.
266 * HOFL bit clears when a new measurement starts.
267 */
268 if (*stat2 & 0x08) {
269 pr_err("%s:compass data overflow\n", __func__);
270 return -3;
271 }
272
273 mutex_lock(&sensor->data_mutex);
274 memcpy(sensor->sensor_data, buffer, sensor->ops->read_len);
275 mutex_unlock(&sensor->data_mutex);
276
277 if ((sensor->pdata->irq_enable) && (sensor->ops->int_status_reg >= 0))
278 value = sensor_read_reg(client, sensor->ops->int_status_reg);
279
280 ret = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
281 if (ret) {
282 pr_err("%s:fail to set ctrl_data:0x%x\n", __func__, sensor->ops->ctrl_data);
283 return ret;
284 }
285
286 return ret;
287 }
288
compass_set_YPR(int * rbuf)289 static void compass_set_YPR(int *rbuf)
290 {
291 /* No events are reported */
292 if (!rbuf[0]) {
293 pr_err("%s:Don't waste a time.", __func__);
294 return;
295 }
296
297 g_akm_rbuf_ready = 1;
298 memcpy(g_akm_rbuf, rbuf, 12 * sizeof(int));
299 }
300
compass_dev_open(struct inode * inode,struct file * file)301 static int compass_dev_open(struct inode *inode, struct file *file)
302 {
303 return 0;
304 }
305
compass_dev_release(struct inode * inode,struct file * file)306 static int compass_dev_release(struct inode *inode, struct file *file)
307 {
308 return 0;
309 }
310
compass_akm_set_mode(struct i2c_client * client,char mode)311 static int compass_akm_set_mode(struct i2c_client *client, char mode)
312 {
313 struct sensor_private_data *sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
314 int result = 0;
315
316 switch (mode & 0x0f) {
317 case AK8963_MODE_SNG_MEASURE:
318 case AK8963_MODE_SELF_TEST:
319 case AK8963_MODE_FUSE_ACCESS:
320 if (sensor->status_cur == SENSOR_OFF) {
321 sensor->stop_work = 0;
322 sensor->status_cur = SENSOR_ON;
323 pr_info("compass ak09911 start measure");
324 schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));
325 }
326 break;
327
328 case AK8963_MODE_POWERDOWN:
329 if (sensor->status_cur == SENSOR_ON) {
330 sensor->stop_work = 1;
331 cancel_delayed_work_sync(&sensor->delaywork);
332 pr_info("compass ak09911 stop measure");
333 g_akm_rbuf_ready = 0;
334 sensor->status_cur = SENSOR_OFF;
335 }
336 break;
337 }
338
339 switch (mode & 0x0f) {
340 case AK8963_MODE_SNG_MEASURE:
341 result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode);
342 if (result)
343 pr_err("%s:i2c error,mode=%d\n", __func__, mode);
344 break;
345 case AK8963_MODE_SELF_TEST:
346 result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode);
347 if (result)
348 pr_err("%s:i2c error,mode=%d\n", __func__, mode);
349 break;
350 case AK8963_MODE_FUSE_ACCESS:
351 result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode);
352 if (result)
353 pr_err("%s:i2c error,mode=%d\n", __func__, mode);
354 break;
355 case AK8963_MODE_POWERDOWN:
356 /* Set powerdown mode */
357 result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8963_MODE_POWERDOWN);
358 if (result)
359 pr_err("%s:i2c error,mode=%d\n", __func__, mode);
360 udelay(100);
361 break;
362 default:
363 pr_err("%s: Unknown mode(%d)", __func__, mode);
364 result = -EINVAL;
365 break;
366 }
367
368 return result;
369 }
370
compass_akm_reset(struct i2c_client * client)371 static int compass_akm_reset(struct i2c_client *client)
372 {
373 struct sensor_private_data *sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
374 int result = 0;
375
376 if (sensor->pdata->reset_pin > 0) {
377 gpio_direction_output(sensor->pdata->reset_pin, GPIO_LOW);
378 udelay(10);
379 gpio_direction_output(sensor->pdata->reset_pin, GPIO_HIGH);
380 } else {
381 /* Set measure mode */
382 result = sensor_write_reg(client, AK8963_REG_CNTL2, AK8963_MODE_SNG_MEASURE);
383 if (result)
384 pr_err("%s:fail to Set measure mode\n", __func__);
385 }
386
387 udelay(100);
388
389 return result;
390 }
391
compass_akm_get_openstatus(void)392 static int compass_akm_get_openstatus(void)
393 {
394 struct sensor_private_data *sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
395
396 wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) != 0));
397
398 return atomic_read(&sensor->flags.open_flag);
399 }
400
compass_akm_get_closestatus(void)401 static int compass_akm_get_closestatus(void)
402 {
403 struct sensor_private_data *sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
404
405 wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) <= 0));
406
407 return atomic_read(&sensor->flags.open_flag);
408 }
409
410 /* ioctl - I/O control */
compass_dev_ioctl(struct file * file,unsigned int cmd,unsigned long arg)411 static long compass_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
412 {
413 struct sensor_private_data *sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
414 struct i2c_client *client = this_client;
415 void __user *argp = (void __user *)arg;
416 int result = 0;
417 struct akm_platform_data compass;
418 unsigned char sense_info[AKM_SENSOR_INFO_SIZE];
419 unsigned char sense_conf[AKM_SENSOR_CONF_SIZE];
420
421 /* NOTE: In this function the size of "char" should be 1-byte. */
422 char compass_data[SENSOR_DATA_SIZE]; /* for GETDATA */
423 char rwbuf[RWBUF_SIZE]; /* for READ/WRITE */
424 char mode; /* for SET_MODE*/
425 int value[12]; /* for SET_YPR */
426 int status; /* for OPEN/CLOSE_STATUS */
427 int ret = -1; /* Return value. */
428
429 int16_t acc_buf[3]; /* for GET_ACCEL */
430 int64_t delay[AKM_NUM_SENSORS]; /* for GET_DELAY */
431
432 char layout; /* for GET_LAYOUT */
433 char outbit; /* for GET_OUTBIT */
434
435 switch (cmd) {
436 case ECS_IOCTL_WRITE:
437 case ECS_IOCTL_READ:
438 if (!argp)
439 return -EINVAL;
440 if (copy_from_user(&rwbuf, argp, sizeof(rwbuf)))
441 return -EFAULT;
442 break;
443 case ECS_IOCTL_SET_MODE:
444 if (!argp)
445 return -EINVAL;
446 if (copy_from_user(&mode, argp, sizeof(mode)))
447 return -EFAULT;
448 break;
449 case ECS_IOCTL_SET_YPR:
450 if (!argp)
451 return -EINVAL;
452 if (copy_from_user(&value, argp, sizeof(value)))
453 return -EFAULT;
454 break;
455 case ECS_IOCTL_GET_INFO:
456 case ECS_IOCTL_GET_CONF:
457 case ECS_IOCTL_GETDATA:
458 case ECS_IOCTL_GET_OPEN_STATUS:
459 case ECS_IOCTL_GET_CLOSE_STATUS:
460 case ECS_IOCTL_GET_DELAY:
461 case ECS_IOCTL_GET_LAYOUT:
462 case ECS_IOCTL_GET_OUTBIT:
463 case ECS_IOCTL_GET_ACCEL:
464 /* Just check buffer pointer */
465 if (!argp) {
466 pr_err("%s:invalid argument\n", __func__);
467 return -EINVAL;
468 }
469 break;
470 default:
471 break;
472 }
473
474 switch (cmd) {
475 case ECS_IOCTL_GET_INFO:
476 sense_info[0] = AK8963_REG_WIA;
477 mutex_lock(&sensor->operation_mutex);
478 ret = sensor_rx_data(client, &sense_info[0], AKM_SENSOR_INFO_SIZE);
479 mutex_unlock(&sensor->operation_mutex);
480 if (ret < 0) {
481 pr_err("%s:fait to get sense_info\n", __func__);
482 return ret;
483 }
484 /* Check read data */
485 if (sense_info[0] != AK8963_WIA_VALUE) {
486 dev_err(&client->dev,
487 "%s: The device is not AKM Compass.", __func__);
488 return -ENXIO;
489 }
490 break;
491 case ECS_IOCTL_GET_CONF:
492 sense_conf[0] = AK8963_FUSE_ASAX;
493 mutex_lock(&sensor->operation_mutex);
494 ret = sensor_rx_data(client, &sense_conf[0], AKM_SENSOR_CONF_SIZE);
495 mutex_unlock(&sensor->operation_mutex);
496 if (ret < 0) {
497 pr_err("%s:fait to get sense_conf\n", __func__);
498 return ret;
499 }
500 break;
501 case ECS_IOCTL_WRITE:
502 mutex_lock(&sensor->operation_mutex);
503 if ((rwbuf[0] < 2) || (rwbuf[0] > (RWBUF_SIZE - 1))) {
504 mutex_unlock(&sensor->operation_mutex);
505 return -EINVAL;
506 }
507 ret = sensor_tx_data(client, &rwbuf[1], rwbuf[0]);
508 if (ret < 0) {
509 mutex_unlock(&sensor->operation_mutex);
510 pr_err("%s:fait to tx data\n", __func__);
511 return ret;
512 }
513 mutex_unlock(&sensor->operation_mutex);
514 break;
515 case ECS_IOCTL_READ:
516 mutex_lock(&sensor->operation_mutex);
517 if ((rwbuf[0] < 1) || (rwbuf[0] > (RWBUF_SIZE - 1))) {
518 mutex_unlock(&sensor->operation_mutex);
519 pr_err("%s:data is error\n", __func__);
520 return -EINVAL;
521 }
522 ret = sensor_rx_data(client, &rwbuf[1], rwbuf[0]);
523 if (ret < 0) {
524 mutex_unlock(&sensor->operation_mutex);
525 pr_err("%s:fait to rx data\n", __func__);
526 return ret;
527 }
528 mutex_unlock(&sensor->operation_mutex);
529 break;
530 case ECS_IOCTL_SET_MODE:
531 mutex_lock(&sensor->operation_mutex);
532 if (sensor->ops->ctrl_data != mode) {
533 ret = compass_akm_set_mode(client, mode);
534 if (ret < 0) {
535 pr_err("%s:fait to set mode\n", __func__);
536 mutex_unlock(&sensor->operation_mutex);
537 return ret;
538 }
539
540 sensor->ops->ctrl_data = mode;
541 }
542 mutex_unlock(&sensor->operation_mutex);
543 break;
544 case ECS_IOCTL_GETDATA:
545 mutex_lock(&sensor->data_mutex);
546 memcpy(compass_data, sensor->sensor_data, SENSOR_DATA_SIZE);
547 mutex_unlock(&sensor->data_mutex);
548 break;
549 case ECS_IOCTL_SET_YPR:
550 mutex_lock(&sensor->data_mutex);
551 compass_set_YPR(value);
552 mutex_unlock(&sensor->data_mutex);
553 break;
554 case ECS_IOCTL_GET_OPEN_STATUS:
555 status = compass_akm_get_openstatus();
556 break;
557 case ECS_IOCTL_GET_CLOSE_STATUS:
558 status = compass_akm_get_closestatus();
559 break;
560 case ECS_IOCTL_GET_DELAY:
561 mutex_lock(&sensor->operation_mutex);
562 delay[0] = sensor->flags.delay;
563 delay[1] = sensor->flags.delay;
564 delay[2] = sensor->flags.delay;
565 mutex_unlock(&sensor->operation_mutex);
566 break;
567
568 case ECS_IOCTL_GET_PLATFORM_DATA:
569 ret = copy_to_user(argp, &compass, sizeof(compass));
570 if (ret < 0) {
571 pr_err("%s:error,ret=%d\n", __func__, ret);
572 return ret;
573 }
574 break;
575 case ECS_IOCTL_GET_LAYOUT:
576 layout = sensor->pdata->layout;
577 break;
578 case ECS_IOCTL_GET_OUTBIT:
579 outbit = 1;
580 break;
581 case ECS_IOCTL_RESET:
582 ret = compass_akm_reset(client);
583 if (ret < 0)
584 return ret;
585 break;
586 case ECS_IOCTL_GET_ACCEL:
587 break;
588
589 default:
590 return -ENOTTY;
591 }
592
593 switch (cmd) {
594 case ECS_IOCTL_READ:
595 if (copy_to_user(argp, &rwbuf, rwbuf[0] + 1))
596 return -EFAULT;
597 break;
598 case ECS_IOCTL_GETDATA:
599 if (copy_to_user(argp, &compass_data, sizeof(compass_data)))
600 return -EFAULT;
601 break;
602 case ECS_IOCTL_GET_OPEN_STATUS:
603 case ECS_IOCTL_GET_CLOSE_STATUS:
604 if (copy_to_user(argp, &status, sizeof(status)))
605 return -EFAULT;
606 break;
607 case ECS_IOCTL_GET_DELAY:
608 if (copy_to_user(argp, &delay, sizeof(delay)))
609 return -EFAULT;
610 break;
611 case ECS_IOCTL_GET_LAYOUT:
612 if (copy_to_user(argp, &layout, sizeof(layout))) {
613 pr_err("%s:error:%d\n", __func__, __LINE__);
614 return -EFAULT;
615 }
616 break;
617 case ECS_IOCTL_GET_OUTBIT:
618 if (copy_to_user(argp, &outbit, sizeof(outbit))) {
619 pr_err("%s:error:%d\n", __func__, __LINE__);
620 return -EFAULT;
621 }
622 break;
623 case ECS_IOCTL_GET_ACCEL:
624 if (copy_to_user(argp, &acc_buf, sizeof(acc_buf))) {
625 pr_err("%s:error:%d\n", __func__, __LINE__);
626 return -EFAULT;
627 }
628 break;
629 case ECS_IOCTL_GET_INFO:
630 if (copy_to_user(argp, &sense_info, sizeof(sense_info))) {
631 pr_err("%s:error:%d\n", __func__, __LINE__);
632 return -EFAULT;
633 }
634 break;
635 case ECS_IOCTL_GET_CONF:
636 if (copy_to_user(argp, &sense_conf, sizeof(sense_conf))) {
637 pr_err("%s:error:%d\n", __func__, __LINE__);
638 return -EFAULT;
639 }
640 break;
641 default:
642 break;
643 }
644
645 return result;
646 }
647
648 static const struct file_operations compass_dev_fops = {
649 .owner = THIS_MODULE,
650 .open = compass_dev_open,
651 .release = compass_dev_release,
652 .unlocked_ioctl = compass_dev_ioctl,
653 };
654
655 static struct miscdevice compass_dev_device = {
656 .minor = MISC_DYNAMIC_MINOR,
657 .name = "akm8963_dev",
658 .fops = &compass_dev_fops,
659 };
660
661 static struct sensor_operate compass_akm8963_ops = {
662 .name = "akm8963",
663 .type = SENSOR_TYPE_COMPASS,
664 .id_i2c = COMPASS_ID_AK8963,
665 .read_reg = AK8963_REG_ST1,
666 .read_len = SENSOR_DATA_SIZE,
667 .id_reg = AK8963_REG_WIA,
668 .id_data = AK8963_DEVICE_ID,
669 .precision = 8,
670 .ctrl_reg = AK8963_REG_CNTL1,
671 .int_status_reg = SENSOR_UNKNOW_DATA,
672 .range = {-0xffff, 0xffff},
673 .trig = IRQF_TRIGGER_RISING,
674 .active = sensor_active,
675 .init = sensor_init,
676 .report = sensor_report_value,
677 .misc_dev = NULL,
678 };
679
680 /****************operate according to sensor chip:end************/
compass_akm8963_probe(struct i2c_client * client,const struct i2c_device_id * devid)681 static int compass_akm8963_probe(struct i2c_client *client,
682 const struct i2c_device_id *devid)
683 {
684 return sensor_register_device(client, NULL, devid, &compass_akm8963_ops);
685 }
686
compass_akm8963_remove(struct i2c_client * client)687 static int compass_akm8963_remove(struct i2c_client *client)
688 {
689 return sensor_unregister_device(client, NULL, &compass_akm8963_ops);
690 }
691
692 static const struct i2c_device_id compass_akm8963_id[] = {
693 {"ak8963", COMPASS_ID_AK8963},
694 {}
695 };
696
697 static struct i2c_driver compass_akm8963_driver = {
698 .probe = compass_akm8963_probe,
699 .remove = compass_akm8963_remove,
700 .shutdown = sensor_shutdown,
701 .id_table = compass_akm8963_id,
702 .driver = {
703 .name = "compass_akm8963",
704 #ifdef CONFIG_PM
705 .pm = &sensor_pm_ops,
706 #endif
707 },
708 };
709
710 module_i2c_driver(compass_akm8963_driver);
711
712 MODULE_AUTHOR("luowei <lw@rock-chips.com>");
713 MODULE_DESCRIPTION("akm8963 3-Axis compasss driver");
714 MODULE_LICENSE("GPL");
715