xref: /OK3568_Linux_fs/kernel/drivers/input/sensors/compass/ak8963.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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