2 * hmc6352.c - Honeywell Compass Driver
4 * Copyright (C) 2009 Intel Corp
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 #include <linux/module.h>
25 #include <linux/init.h>
26 #include <linux/slab.h>
27 #include <linux/i2c.h>
28 #include <linux/err.h>
29 #include <linux/delay.h>
30 #include <linux/sysfs.h>
32 static DEFINE_MUTEX(compass_mutex
);
34 static int compass_command(struct i2c_client
*c
, u8 cmd
)
36 int ret
= i2c_master_send(c
, &cmd
, 1);
38 dev_warn(&c
->dev
, "command '%c' failed.\n", cmd
);
42 static int compass_store(struct device
*dev
, const char *buf
, size_t count
,
45 struct i2c_client
*c
= to_i2c_client(dev
);
49 ret
= kstrtoul(buf
, 10, &val
);
52 if (val
>= strlen(map
))
54 mutex_lock(&compass_mutex
);
55 ret
= compass_command(c
, map
[val
]);
56 mutex_unlock(&compass_mutex
);
62 static ssize_t
compass_calibration_store(struct device
*dev
,
63 struct device_attribute
*attr
, const char *buf
, size_t count
)
65 return compass_store(dev
, buf
, count
, "EC");
68 static ssize_t
compass_power_mode_store(struct device
*dev
,
69 struct device_attribute
*attr
, const char *buf
, size_t count
)
71 return compass_store(dev
, buf
, count
, "SW");
74 static ssize_t
compass_heading_data_show(struct device
*dev
,
75 struct device_attribute
*attr
, char *buf
)
77 struct i2c_client
*client
= to_i2c_client(dev
);
78 unsigned char i2c_data
[2];
81 mutex_lock(&compass_mutex
);
82 ret
= compass_command(client
, 'A');
84 mutex_unlock(&compass_mutex
);
87 msleep(10); /* sending 'A' cmd we need to wait for 7-10 millisecs */
88 ret
= i2c_master_recv(client
, i2c_data
, 2);
89 mutex_unlock(&compass_mutex
);
91 dev_warn(dev
, "i2c read data cmd failed\n");
94 ret
= (i2c_data
[0] << 8) | i2c_data
[1];
95 return sprintf(buf
, "%d.%d\n", ret
/10, ret
%10);
99 static DEVICE_ATTR(heading0_input
, S_IRUGO
, compass_heading_data_show
, NULL
);
100 static DEVICE_ATTR(calibration
, S_IWUSR
, NULL
, compass_calibration_store
);
101 static DEVICE_ATTR(power_state
, S_IWUSR
, NULL
, compass_power_mode_store
);
103 static struct attribute
*mid_att_compass
[] = {
104 &dev_attr_heading0_input
.attr
,
105 &dev_attr_calibration
.attr
,
106 &dev_attr_power_state
.attr
,
110 static const struct attribute_group m_compass_gr
= {
112 .attrs
= mid_att_compass
115 static int hmc6352_probe(struct i2c_client
*client
,
116 const struct i2c_device_id
*id
)
120 res
= sysfs_create_group(&client
->dev
.kobj
, &m_compass_gr
);
122 dev_err(&client
->dev
, "device_create_file failed\n");
125 dev_info(&client
->dev
, "%s HMC6352 compass chip found\n",
130 static int hmc6352_remove(struct i2c_client
*client
)
132 sysfs_remove_group(&client
->dev
.kobj
, &m_compass_gr
);
136 static struct i2c_device_id hmc6352_id
[] = {
141 MODULE_DEVICE_TABLE(i2c
, hmc6352_id
);
143 static struct i2c_driver hmc6352_driver
= {
147 .probe
= hmc6352_probe
,
148 .remove
= hmc6352_remove
,
149 .id_table
= hmc6352_id
,
152 module_i2c_driver(hmc6352_driver
);
154 MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com");
155 MODULE_DESCRIPTION("hmc6352 Compass Driver");
156 MODULE_LICENSE("GPL v2");