2 * drivers/i2c/chips/ak8973.c - ak8973 compass driver
4 * Copyright (C) 2008 viral wang <viralwang@gmail.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
11 #include <linux/interrupt.h>
12 #include <linux/i2c.h>
13 #include <linux/slab.h>
14 #include <linux/irq.h>
15 #include <linux/miscdevice.h>
17 #include <asm/uaccess.h>
18 #include <linux/delay.h>
19 #include <linux/input.h>
20 #include <linux/workqueue.h>
21 #include <linux/freezer.h>
23 #include<linux/earlysuspend.h>
26 #define MAX_FAILURE_COUNT 3
28 static struct i2c_client *this_client;
31 struct input_dev *input_dev;
32 struct work_struct work;
33 #ifdef CONFIG_HAS_EARLYSUSPEND
34 struct early_suspend early_suspend_akm;
38 /* Addresses to scan -- protected by sense_data_mutex */
39 static char sense_data[RBUFF_SIZE + 1];
40 static struct mutex sense_data_mutex;
41 #define AKM8973_RETRY_COUNT 10
42 static DECLARE_WAIT_QUEUE_HEAD(data_ready_wq);
43 static DECLARE_WAIT_QUEUE_HEAD(open_wq);
45 static atomic_t data_ready;
46 static atomic_t open_count;
47 static atomic_t open_flag;
48 static atomic_t reserve_open_flag;
50 static atomic_t m_flag;
51 static atomic_t a_flag;
52 static atomic_t t_flag;
53 static atomic_t mv_flag;
55 static int failure_count = 0;
57 static short akmd_delay = 0;
58 #ifdef CONFIG_HAS_EARLYSUSPEND
59 static atomic_t suspend_flag = ATOMIC_INIT(0);
62 static int AKI2C_RxData(char *rxData, int length)
65 struct i2c_msg msgs[] = {
67 .addr = this_client->addr,
73 .addr = this_client->addr,
80 for (loop_i = 0; loop_i < AKM8973_RETRY_COUNT; loop_i++) {
81 if (i2c_transfer(this_client->adapter, msgs, 2) > 0) {
87 if (loop_i >= AKM8973_RETRY_COUNT) {
88 printk(KERN_ERR "%s retry over %d\n", __func__, AKM8973_RETRY_COUNT);
94 static int AKI2C_TxData(char *txData, int length)
97 struct i2c_msg msg[] = {
99 .addr = this_client->addr,
106 for (loop_i = 0; loop_i < AKM8973_RETRY_COUNT; loop_i++) {
107 if (i2c_transfer(this_client->adapter, msg, 1) > 0) {
113 if (loop_i >= AKM8973_RETRY_COUNT) {
114 printk(KERN_ERR "%s retry over %d\n", __func__, AKM8973_RETRY_COUNT);
120 static int AKECS_StartMeasure(void)
124 /* Set measure mode */
125 buffer[0] = AKECS_REG_MS1;
126 buffer[1] = AKECS_MODE_MEASURE;
129 return AKI2C_TxData(buffer, 2);
132 static int AKECS_PowerDown(void)
137 /* Set powerdown mode */
138 buffer[0] = AKECS_REG_MS1;
139 buffer[1] = AKECS_MODE_POWERDOWN;
141 ret = AKI2C_TxData(buffer, 2);
145 /* Dummy read for clearing INT pin */
146 buffer[0] = AKECS_REG_TMPS;
148 ret = AKI2C_RxData(buffer, 1);
154 static int AKECS_StartE2PRead(void)
158 /* Set measure mode */
159 buffer[0] = AKECS_REG_MS1;
160 buffer[1] = AKECS_MODE_E2P_READ;
162 return AKI2C_TxData(buffer, 2);
165 static int AKECS_GetData(void)
167 char buffer[RBUFF_SIZE + 1];
170 memset(buffer, 0, RBUFF_SIZE + 1);
171 buffer[0] = AKECS_REG_ST;
172 ret = AKI2C_RxData(buffer, RBUFF_SIZE+1);
176 mutex_lock(&sense_data_mutex);
177 memcpy(sense_data, buffer, sizeof(buffer));
178 atomic_set(&data_ready, 1);
179 wake_up(&data_ready_wq);
180 mutex_unlock(&sense_data_mutex);
185 static int AKECS_SetMode(char mode)
190 case AKECS_MODE_MEASURE:
191 ret = AKECS_StartMeasure();
193 case AKECS_MODE_E2P_READ:
194 ret = AKECS_StartE2PRead();
196 case AKECS_MODE_POWERDOWN:
197 ret = AKECS_PowerDown();
203 /* wait at least 300us after changing mode */
208 static int AKECS_TransRBuff(char *rbuf, int size)
210 wait_event_interruptible_timeout(data_ready_wq,
211 atomic_read(&data_ready), 1000);
212 if (!atomic_read(&data_ready)) {
213 #ifdef CONFIG_HAS_EARLYSUSPEND
214 if (!atomic_read(&suspend_flag)) {
216 "AKM8973 AKECS_TransRBUFF: Data not ready\n");
218 if (failure_count >= MAX_FAILURE_COUNT) {
220 "AKM8973 AKECS_TransRBUFF: successive %d failure.\n",
222 atomic_set(&open_flag, -1);
231 mutex_lock(&sense_data_mutex);
232 memcpy(&rbuf[1], &sense_data[1], size);
233 atomic_set(&data_ready, 0);
234 mutex_unlock(&sense_data_mutex);
241 static void AKECS_Report_Value(short *rbuf)
243 struct akm8973_data *data = i2c_get_clientdata(this_client);
245 printk(KERN_INFO"AKECS_Report_Value: yaw = %d, pitch = %d, roll = %d\n", rbuf[0],
247 printk(KERN_INFO" tmp = %d, m_stat= %d, g_stat=%d\n", rbuf[3],
249 printk(KERN_INFO" G_Sensor: x = %d LSB, y = %d LSB, z = %d LSB\n",
250 rbuf[6], rbuf[7], rbuf[8]);
252 /* Report magnetic sensor information */
253 if (atomic_read(&m_flag)) {
254 input_report_abs(data->input_dev, ABS_RX, rbuf[0]);
255 input_report_abs(data->input_dev, ABS_RY, rbuf[1]);
256 input_report_abs(data->input_dev, ABS_RZ, rbuf[2]);
257 input_report_abs(data->input_dev, ABS_RUDDER, rbuf[4]);
260 /* Report acceleration sensor information */
261 if (atomic_read(&a_flag)) {
262 input_report_abs(data->input_dev, ABS_X, rbuf[6]);
263 input_report_abs(data->input_dev, ABS_Y, rbuf[7]);
264 input_report_abs(data->input_dev, ABS_Z, rbuf[8]);
265 input_report_abs(data->input_dev, ABS_WHEEL, rbuf[5]);
268 /* Report temperature information */
269 if (atomic_read(&t_flag))
270 input_report_abs(data->input_dev, ABS_THROTTLE, rbuf[3]);
272 if (atomic_read(&mv_flag)) {
273 input_report_abs(data->input_dev, ABS_HAT0X, rbuf[9]);
274 input_report_abs(data->input_dev, ABS_HAT0Y, rbuf[10]);
275 input_report_abs(data->input_dev, ABS_BRAKE, rbuf[11]);
278 input_sync(data->input_dev);
281 static int AKECS_GetOpenStatus(void)
283 wait_event_interruptible(open_wq, (atomic_read(&open_flag) != 0));
284 return atomic_read(&open_flag);
287 static int AKECS_GetCloseStatus(void)
289 wait_event_interruptible(open_wq, (atomic_read(&open_flag) <= 0));
290 return atomic_read(&open_flag);
293 static void AKECS_CloseDone(void)
295 atomic_set(&m_flag, 1);
296 atomic_set(&a_flag, 1);
297 atomic_set(&t_flag, 1);
298 atomic_set(&mv_flag, 1);
301 static int akm_aot_open(struct inode *inode, struct file *file)
304 if (atomic_cmpxchg(&open_count, 0, 1) == 0) {
305 if (atomic_cmpxchg(&open_flag, 0, 1) == 0) {
306 atomic_set(&reserve_open_flag, 1);
314 static int akm_aot_release(struct inode *inode, struct file *file)
316 atomic_set(&reserve_open_flag, 0);
317 atomic_set(&open_flag, 0);
318 atomic_set(&open_count, 0);
324 akm_aot_ioctl(struct inode *inode, struct file *file,
325 unsigned int cmd, unsigned long arg)
327 void __user *argp = (void __user *)arg;
331 case ECS_IOCTL_APP_SET_MFLAG:
332 case ECS_IOCTL_APP_SET_AFLAG:
333 case ECS_IOCTL_APP_SET_TFLAG:
334 case ECS_IOCTL_APP_SET_MVFLAG:
335 if (copy_from_user(&flag, argp, sizeof(flag)))
337 if (flag < 0 || flag > 1)
340 case ECS_IOCTL_APP_SET_DELAY:
341 if (copy_from_user(&flag, argp, sizeof(flag)))
349 case ECS_IOCTL_APP_SET_MFLAG:
350 atomic_set(&m_flag, flag);
352 case ECS_IOCTL_APP_GET_MFLAG:
353 flag = atomic_read(&m_flag);
355 case ECS_IOCTL_APP_SET_AFLAG:
356 atomic_set(&a_flag, flag);
358 case ECS_IOCTL_APP_GET_AFLAG:
359 flag = atomic_read(&a_flag);
361 case ECS_IOCTL_APP_SET_TFLAG:
362 atomic_set(&t_flag, flag);
364 case ECS_IOCTL_APP_GET_TFLAG:
365 flag = atomic_read(&t_flag);
367 case ECS_IOCTL_APP_SET_MVFLAG:
368 atomic_set(&mv_flag, flag);
370 case ECS_IOCTL_APP_GET_MVFLAG:
371 flag = atomic_read(&mv_flag);
373 case ECS_IOCTL_APP_SET_DELAY:
376 case ECS_IOCTL_APP_GET_DELAY:
384 case ECS_IOCTL_APP_GET_MFLAG:
385 case ECS_IOCTL_APP_GET_AFLAG:
386 case ECS_IOCTL_APP_GET_TFLAG:
387 case ECS_IOCTL_APP_GET_MVFLAG:
388 case ECS_IOCTL_APP_GET_DELAY:
389 if (copy_to_user(argp, &flag, sizeof(flag)))
399 static int akmd_open(struct inode *inode, struct file *file)
401 return nonseekable_open(inode, file);
404 static int akmd_release(struct inode *inode, struct file *file)
411 akmd_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
415 void __user *argp = (void __user *)arg;
417 char msg[RBUFF_SIZE + 1], rwbuf[5];
418 int ret = -1, status;
419 short mode, value[12], delay;
422 case ECS_IOCTL_WRITE:
424 if (copy_from_user(&rwbuf, argp, sizeof(rwbuf)))
427 case ECS_IOCTL_SET_MODE:
428 if (copy_from_user(&mode, argp, sizeof(mode)))
431 case ECS_IOCTL_SET_YPR:
432 if (copy_from_user(&value, argp, sizeof(value)))
440 case ECS_IOCTL_WRITE:
443 ret = AKI2C_TxData(&rwbuf[1], rwbuf[0]);
450 ret = AKI2C_RxData(&rwbuf[1], rwbuf[0]);
454 case ECS_IOCTL_SET_MODE:
455 ret = AKECS_SetMode((char)mode);
459 case ECS_IOCTL_GETDATA:
460 ret = AKECS_TransRBuff(msg, RBUFF_SIZE);
464 case ECS_IOCTL_SET_YPR:
465 AKECS_Report_Value(value);
467 case ECS_IOCTL_GET_OPEN_STATUS:
468 status = AKECS_GetOpenStatus();
470 case ECS_IOCTL_GET_CLOSE_STATUS:
471 status = AKECS_GetCloseStatus();
473 case ECS_IOCTL_GET_DELAY:
482 if (copy_to_user(argp, &rwbuf, sizeof(rwbuf)))
485 case ECS_IOCTL_GETDATA:
486 if (copy_to_user(argp, &msg, sizeof(msg)))
489 case ECS_IOCTL_GET_OPEN_STATUS:
490 case ECS_IOCTL_GET_CLOSE_STATUS:
491 if (copy_to_user(argp, &status, sizeof(status)))
494 case ECS_IOCTL_GET_DELAY:
495 if (copy_to_user(argp, &delay, sizeof(delay)))
505 static void akm_work_func(struct work_struct *work)
507 if (AKECS_GetData() < 0)
508 printk(KERN_ERR "AKM8973 akm_work_func: Get data failed\n");
509 enable_irq(this_client->irq);
512 static irqreturn_t akm8973_interrupt(int irq, void *dev_id)
514 struct akm8973_data *data = dev_id;
515 disable_irq(this_client->irq);
516 schedule_work(&data->work);
519 #ifdef CONFIG_HAS_EARLYSUSPEND
520 static void akm8973_early_suspend(struct early_suspend *handler)
522 atomic_set(&suspend_flag, 1);
523 atomic_set(&reserve_open_flag, atomic_read(&open_flag));
524 atomic_set(&open_flag, 0);
526 disable_irq(this_client->irq);
529 static void akm8973_early_resume(struct early_suspend *handler)
531 enable_irq(this_client->irq);
532 atomic_set(&suspend_flag, 0);
533 atomic_set(&open_flag, atomic_read(&reserve_open_flag));
537 static struct file_operations akmd_fops = {
538 .owner = THIS_MODULE,
540 .release = akmd_release,
544 static struct file_operations akm_aot_fops = {
545 .owner = THIS_MODULE,
546 .open = akm_aot_open,
547 .release = akm_aot_release,
548 .ioctl = akm_aot_ioctl,
552 static struct miscdevice akm_aot_device = {
553 .minor = MISC_DYNAMIC_MINOR,
554 .name = "akm8973_aot",
555 .fops = &akm_aot_fops,
559 static struct miscdevice akmd_device = {
560 .minor = MISC_DYNAMIC_MINOR,
561 .name = "akm8973_daemon",
565 static ssize_t compass_reset_store(struct device *dev,
566 struct device_attribute *attr,
567 const char *buf, size_t count)
572 sscanf(buf, "%u", &val);
579 static DEVICE_ATTR(reset, 0644, NULL, compass_reset_store);
581 int akm8973_probe(struct i2c_client *client, const struct i2c_device_id *id)
583 struct akm8973_data *akm;
586 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
588 goto exit_check_functionality_failed;
591 akm = kzalloc(sizeof(struct akm8973_data), GFP_KERNEL);
594 goto exit_alloc_data_failed;
597 INIT_WORK(&akm->work, akm_work_func);
598 i2c_set_clientdata(client, akm);
600 this_client = client;
602 err = AKECS_PowerDown();
604 printk(KERN_ERR"AKM8973 akm8973_probe: set power down mode error\n");
605 goto exit_set_mode_failed;
608 err = request_irq(client->irq, akm8973_interrupt, IRQF_TRIGGER_HIGH,
612 printk(KERN_ERR"AKM8973 akm8973_probe: request irq failed\n");
613 goto exit_irq_request_failed;
616 akm->input_dev = input_allocate_device();
618 if (!akm->input_dev) {
621 "AKM8973 akm8973_probe: Failed to allocate input device\n");
622 goto exit_input_dev_alloc_failed;
625 set_bit(EV_ABS, akm->input_dev->evbit);
627 input_set_abs_params(akm->input_dev, ABS_RX, 0, 360, 0, 0);
629 input_set_abs_params(akm->input_dev, ABS_RY, -180, 180, 0, 0);
631 input_set_abs_params(akm->input_dev, ABS_RZ, -90, 90, 0, 0);
632 /* x-axis acceleration */
633 input_set_abs_params(akm->input_dev, ABS_X, -1872, 1872, 0, 0);
634 /* y-axis acceleration */
635 input_set_abs_params(akm->input_dev, ABS_Y, -1872, 1872, 0, 0);
636 /* z-axis acceleration */
637 input_set_abs_params(akm->input_dev, ABS_Z, -1872, 1872, 0, 0);
639 input_set_abs_params(akm->input_dev, ABS_THROTTLE, -30, 85, 0, 0);
640 /* status of magnetic sensor */
641 input_set_abs_params(akm->input_dev, ABS_RUDDER, -32768, 3, 0, 0);
642 /* status of acceleration sensor */
643 input_set_abs_params(akm->input_dev, ABS_WHEEL, -32768, 3, 0, 0);
645 input_set_abs_params(akm->input_dev, ABS_GAS, 0, 65535, 0, 0);
646 /* x-axis of raw magnetic vector */
647 input_set_abs_params(akm->input_dev, ABS_HAT0X, -2048, 2032, 0, 0);
648 /* y-axis of raw magnetic vector */
649 input_set_abs_params(akm->input_dev, ABS_HAT0Y, -2048, 2032, 0, 0);
650 /* z-axis of raw magnetic vector */
651 input_set_abs_params(akm->input_dev, ABS_BRAKE, -2048, 2032, 0, 0);
653 akm->input_dev->name = "compass";
655 err = input_register_device(akm->input_dev);
659 "AKM8973 akm8973_probe: Unable to register input device: %s\n",
660 akm->input_dev->name);
661 goto exit_input_register_device_failed;
664 err = misc_register(&akmd_device);
666 printk(KERN_ERR "AKM8973 akm8973_probe: akmd_device register failed\n");
667 goto exit_misc_device_register_failed;
670 err = misc_register(&akm_aot_device);
673 "AKM8973 akm8973_probe: akm_aot_device register failed\n");
674 goto exit_misc_device_register_failed;
677 mutex_init(&sense_data_mutex);
679 init_waitqueue_head(&data_ready_wq);
680 init_waitqueue_head(&open_wq);
682 /* As default, report all information */
683 atomic_set(&m_flag, 1);
684 atomic_set(&a_flag, 1);
685 atomic_set(&t_flag, 1);
686 atomic_set(&mv_flag, 1);
687 #ifdef CONFIG_HAS_EARLYSUSPEND
688 akm->early_suspend_akm.suspend = akm8973_early_suspend;
689 akm->early_suspend_akm.resume = akm8973_early_resume;
690 register_early_suspend(&akm->early_suspend_akm);
692 err = device_create_file(&client->dev, &dev_attr_reset);
695 "AKM8973 akm8973_probe: create dev_attr_reset failed\n");
699 exit_misc_device_register_failed:
700 exit_input_register_device_failed:
701 input_free_device(akm->input_dev);
702 exit_input_dev_alloc_failed:
703 free_irq(client->irq, akm);
704 exit_irq_request_failed:
705 exit_set_mode_failed:
707 exit_alloc_data_failed:
708 exit_check_functionality_failed:
713 static int akm8973_remove(struct i2c_client *client)
715 struct akm8973_data *akm = i2c_get_clientdata(client);
716 free_irq(client->irq, akm);
717 input_unregister_device(akm->input_dev);
721 static const struct i2c_device_id akm8973_id[] = {
722 { AKM8973_I2C_NAME, 0 },
726 static struct i2c_driver akm8973_driver = {
727 .probe = akm8973_probe,
728 .remove = akm8973_remove,
729 .id_table = akm8973_id,
731 .name = AKM8973_I2C_NAME,
735 static int __init akm8973_init(void)
737 printk(KERN_INFO "AKM8973 compass driver: init\n");
738 return i2c_add_driver(&akm8973_driver);
741 static void __exit akm8973_exit(void)
743 i2c_del_driver(&akm8973_driver);
746 module_init(akm8973_init);
747 module_exit(akm8973_exit);
749 MODULE_AUTHOR("viral wang <viral_wang@htc.com>");
750 MODULE_DESCRIPTION("AKM8973 compass driver");
751 MODULE_LICENSE("GPL");