aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio/magnetometer
diff options
context:
space:
mode:
authorJonathan Cameron <jic23@kernel.org>2013-03-24 12:58:00 -0400
committerJonathan Cameron <jic23@kernel.org>2013-04-02 13:36:47 -0400
commit2fc72cd8354e3e9c4893fc082614266ddb599902 (patch)
tree0b8eeac08972a61011e6083343c0218ef0241ffb /drivers/iio/magnetometer
parentc411f600cea54d1e00a32071502226acc5072428 (diff)
iio:magnetometer:ak8975 move driver out of staging
Issues raised in last series to propose this have now been resolved so there should be no reason this driver cannot graduate from staging. Signed-off-by: Jonathan Cameron <jic23@kernel.org> Acked-by: Laxman Dewangan <ldewangan@nvidia.com>
Diffstat (limited to 'drivers/iio/magnetometer')
-rw-r--r--drivers/iio/magnetometer/Kconfig11
-rw-r--r--drivers/iio/magnetometer/Makefile1
-rw-r--r--drivers/iio/magnetometer/ak8975.c485
3 files changed, 497 insertions, 0 deletions
diff --git a/drivers/iio/magnetometer/Kconfig b/drivers/iio/magnetometer/Kconfig
index cd29be54f643..bd1cfb666695 100644
--- a/drivers/iio/magnetometer/Kconfig
+++ b/drivers/iio/magnetometer/Kconfig
@@ -3,6 +3,17 @@
3# 3#
4menu "Magnetometer sensors" 4menu "Magnetometer sensors"
5 5
6config AK8975
7 tristate "Asahi Kasei AK8975 3-Axis Magnetometer"
8 depends on I2C
9 depends on GPIOLIB
10 help
11 Say yes here to build support for Asahi Kasei AK8975 3-Axis
12 Magnetometer.
13
14 To compile this driver as a module, choose M here: the module
15 will be called ak8975.
16
6config HID_SENSOR_MAGNETOMETER_3D 17config HID_SENSOR_MAGNETOMETER_3D
7 depends on HID_SENSOR_HUB 18 depends on HID_SENSOR_HUB
8 select IIO_BUFFER 19 select IIO_BUFFER
diff --git a/drivers/iio/magnetometer/Makefile b/drivers/iio/magnetometer/Makefile
index e78672876dc2..7f328e37fbab 100644
--- a/drivers/iio/magnetometer/Makefile
+++ b/drivers/iio/magnetometer/Makefile
@@ -2,6 +2,7 @@
2# Makefile for industrial I/O Magnetometer sensor drivers 2# Makefile for industrial I/O Magnetometer sensor drivers
3# 3#
4 4
5obj-$(CONFIG_AK8975) += ak8975.o
5obj-$(CONFIG_HID_SENSOR_MAGNETOMETER_3D) += hid-sensor-magn-3d.o 6obj-$(CONFIG_HID_SENSOR_MAGNETOMETER_3D) += hid-sensor-magn-3d.o
6 7
7obj-$(CONFIG_IIO_ST_MAGN_3AXIS) += st_magn.o 8obj-$(CONFIG_IIO_ST_MAGN_3AXIS) += st_magn.o
diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c
new file mode 100644
index 000000000000..af6c320a534e
--- /dev/null
+++ b/drivers/iio/magnetometer/ak8975.c
@@ -0,0 +1,485 @@
1/*
2 * A sensor driver for the magnetometer AK8975.
3 *
4 * Magnetic compass sensor driver for monitoring magnetic flux information.
5 *
6 * Copyright (c) 2010, NVIDIA Corporation.
7 *
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; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23#include <linux/module.h>
24#include <linux/kernel.h>
25#include <linux/slab.h>
26#include <linux/i2c.h>
27#include <linux/err.h>
28#include <linux/mutex.h>
29#include <linux/delay.h>
30
31#include <linux/gpio.h>
32
33#include <linux/iio/iio.h>
34#include <linux/iio/sysfs.h>
35/*
36 * Register definitions, as well as various shifts and masks to get at the
37 * individual fields of the registers.
38 */
39#define AK8975_REG_WIA 0x00
40#define AK8975_DEVICE_ID 0x48
41
42#define AK8975_REG_INFO 0x01
43
44#define AK8975_REG_ST1 0x02
45#define AK8975_REG_ST1_DRDY_SHIFT 0
46#define AK8975_REG_ST1_DRDY_MASK (1 << AK8975_REG_ST1_DRDY_SHIFT)
47
48#define AK8975_REG_HXL 0x03
49#define AK8975_REG_HXH 0x04
50#define AK8975_REG_HYL 0x05
51#define AK8975_REG_HYH 0x06
52#define AK8975_REG_HZL 0x07
53#define AK8975_REG_HZH 0x08
54#define AK8975_REG_ST2 0x09
55#define AK8975_REG_ST2_DERR_SHIFT 2
56#define AK8975_REG_ST2_DERR_MASK (1 << AK8975_REG_ST2_DERR_SHIFT)
57
58#define AK8975_REG_ST2_HOFL_SHIFT 3
59#define AK8975_REG_ST2_HOFL_MASK (1 << AK8975_REG_ST2_HOFL_SHIFT)
60
61#define AK8975_REG_CNTL 0x0A
62#define AK8975_REG_CNTL_MODE_SHIFT 0
63#define AK8975_REG_CNTL_MODE_MASK (0xF << AK8975_REG_CNTL_MODE_SHIFT)
64#define AK8975_REG_CNTL_MODE_POWER_DOWN 0
65#define AK8975_REG_CNTL_MODE_ONCE 1
66#define AK8975_REG_CNTL_MODE_SELF_TEST 8
67#define AK8975_REG_CNTL_MODE_FUSE_ROM 0xF
68
69#define AK8975_REG_RSVC 0x0B
70#define AK8975_REG_ASTC 0x0C
71#define AK8975_REG_TS1 0x0D
72#define AK8975_REG_TS2 0x0E
73#define AK8975_REG_I2CDIS 0x0F
74#define AK8975_REG_ASAX 0x10
75#define AK8975_REG_ASAY 0x11
76#define AK8975_REG_ASAZ 0x12
77
78#define AK8975_MAX_REGS AK8975_REG_ASAZ
79
80/*
81 * Miscellaneous values.
82 */
83#define AK8975_MAX_CONVERSION_TIMEOUT 500
84#define AK8975_CONVERSION_DONE_POLL_TIME 10
85
86/*
87 * Per-instance context data for the device.
88 */
89struct ak8975_data {
90 struct i2c_client *client;
91 struct attribute_group attrs;
92 struct mutex lock;
93 u8 asa[3];
94 long raw_to_gauss[3];
95 u8 reg_cache[AK8975_MAX_REGS];
96 int eoc_gpio;
97};
98
99static const int ak8975_index_to_reg[] = {
100 AK8975_REG_HXL, AK8975_REG_HYL, AK8975_REG_HZL,
101};
102
103/*
104 * Helper function to write to the I2C device's registers.
105 */
106static int ak8975_write_data(struct i2c_client *client,
107 u8 reg, u8 val, u8 mask, u8 shift)
108{
109 struct iio_dev *indio_dev = i2c_get_clientdata(client);
110 struct ak8975_data *data = iio_priv(indio_dev);
111 u8 regval;
112 int ret;
113
114 regval = (data->reg_cache[reg] & ~mask) | (val << shift);
115 ret = i2c_smbus_write_byte_data(client, reg, regval);
116 if (ret < 0) {
117 dev_err(&client->dev, "Write to device fails status %x\n", ret);
118 return ret;
119 }
120 data->reg_cache[reg] = regval;
121
122 return 0;
123}
124
125/*
126 * Perform some start-of-day setup, including reading the asa calibration
127 * values and caching them.
128 */
129static int ak8975_setup(struct i2c_client *client)
130{
131 struct iio_dev *indio_dev = i2c_get_clientdata(client);
132 struct ak8975_data *data = iio_priv(indio_dev);
133 u8 device_id;
134 int ret;
135
136 /* Confirm that the device we're talking to is really an AK8975. */
137 ret = i2c_smbus_read_byte_data(client, AK8975_REG_WIA);
138 if (ret < 0) {
139 dev_err(&client->dev, "Error reading WIA\n");
140 return ret;
141 }
142 device_id = ret;
143 if (device_id != AK8975_DEVICE_ID) {
144 dev_err(&client->dev, "Device ak8975 not found\n");
145 return -ENODEV;
146 }
147
148 /* Write the fused rom access mode. */
149 ret = ak8975_write_data(client,
150 AK8975_REG_CNTL,
151 AK8975_REG_CNTL_MODE_FUSE_ROM,
152 AK8975_REG_CNTL_MODE_MASK,
153 AK8975_REG_CNTL_MODE_SHIFT);
154 if (ret < 0) {
155 dev_err(&client->dev, "Error in setting fuse access mode\n");
156 return ret;
157 }
158
159 /* Get asa data and store in the device data. */
160 ret = i2c_smbus_read_i2c_block_data(client, AK8975_REG_ASAX,
161 3, data->asa);
162 if (ret < 0) {
163 dev_err(&client->dev, "Not able to read asa data\n");
164 return ret;
165 }
166
167 /* After reading fuse ROM data set power-down mode */
168 ret = ak8975_write_data(client,
169 AK8975_REG_CNTL,
170 AK8975_REG_CNTL_MODE_POWER_DOWN,
171 AK8975_REG_CNTL_MODE_MASK,
172 AK8975_REG_CNTL_MODE_SHIFT);
173 if (ret < 0) {
174 dev_err(&client->dev, "Error in setting power-down mode\n");
175 return ret;
176 }
177
178/*
179 * Precalculate scale factor (in Gauss units) for each axis and
180 * store in the device data.
181 *
182 * This scale factor is axis-dependent, and is derived from 3 calibration
183 * factors ASA(x), ASA(y), and ASA(z).
184 *
185 * These ASA values are read from the sensor device at start of day, and
186 * cached in the device context struct.
187 *
188 * Adjusting the flux value with the sensitivity adjustment value should be
189 * done via the following formula:
190 *
191 * Hadj = H * ( ( ( (ASA-128)*0.5 ) / 128 ) + 1 )
192 *
193 * where H is the raw value, ASA is the sensitivity adjustment, and Hadj
194 * is the resultant adjusted value.
195 *
196 * We reduce the formula to:
197 *
198 * Hadj = H * (ASA + 128) / 256
199 *
200 * H is in the range of -4096 to 4095. The magnetometer has a range of
201 * +-1229uT. To go from the raw value to uT is:
202 *
203 * HuT = H * 1229/4096, or roughly, 3/10.
204 *
205 * Since 1uT = 100 gauss, our final scale factor becomes:
206 *
207 * Hadj = H * ((ASA + 128) / 256) * 3/10 * 100
208 * Hadj = H * ((ASA + 128) * 30 / 256
209 *
210 * Since ASA doesn't change, we cache the resultant scale factor into the
211 * device context in ak8975_setup().
212 */
213 data->raw_to_gauss[0] = ((data->asa[0] + 128) * 30) >> 8;
214 data->raw_to_gauss[1] = ((data->asa[1] + 128) * 30) >> 8;
215 data->raw_to_gauss[2] = ((data->asa[2] + 128) * 30) >> 8;
216
217 return 0;
218}
219
220static int wait_conversion_complete_gpio(struct ak8975_data *data)
221{
222 struct i2c_client *client = data->client;
223 u32 timeout_ms = AK8975_MAX_CONVERSION_TIMEOUT;
224 int ret;
225
226 /* Wait for the conversion to complete. */
227 while (timeout_ms) {
228 msleep(AK8975_CONVERSION_DONE_POLL_TIME);
229 if (gpio_get_value(data->eoc_gpio))
230 break;
231 timeout_ms -= AK8975_CONVERSION_DONE_POLL_TIME;
232 }
233 if (!timeout_ms) {
234 dev_err(&client->dev, "Conversion timeout happened\n");
235 return -EINVAL;
236 }
237
238 ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST1);
239 if (ret < 0)
240 dev_err(&client->dev, "Error in reading ST1\n");
241
242 return ret;
243}
244
245static int wait_conversion_complete_polled(struct ak8975_data *data)
246{
247 struct i2c_client *client = data->client;
248 u8 read_status;
249 u32 timeout_ms = AK8975_MAX_CONVERSION_TIMEOUT;
250 int ret;
251
252 /* Wait for the conversion to complete. */
253 while (timeout_ms) {
254 msleep(AK8975_CONVERSION_DONE_POLL_TIME);
255 ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST1);
256 if (ret < 0) {
257 dev_err(&client->dev, "Error in reading ST1\n");
258 return ret;
259 }
260 read_status = ret;
261 if (read_status)
262 break;
263 timeout_ms -= AK8975_CONVERSION_DONE_POLL_TIME;
264 }
265 if (!timeout_ms) {
266 dev_err(&client->dev, "Conversion timeout happened\n");
267 return -EINVAL;
268 }
269 return read_status;
270}
271
272/*
273 * Emits the raw flux value for the x, y, or z axis.
274 */
275static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
276{
277 struct ak8975_data *data = iio_priv(indio_dev);
278 struct i2c_client *client = data->client;
279 u16 meas_reg;
280 s16 raw;
281 int ret;
282
283 mutex_lock(&data->lock);
284
285 /* Set up the device for taking a sample. */
286 ret = ak8975_write_data(client,
287 AK8975_REG_CNTL,
288 AK8975_REG_CNTL_MODE_ONCE,
289 AK8975_REG_CNTL_MODE_MASK,
290 AK8975_REG_CNTL_MODE_SHIFT);
291 if (ret < 0) {
292 dev_err(&client->dev, "Error in setting operating mode\n");
293 goto exit;
294 }
295
296 /* Wait for the conversion to complete. */
297 if (gpio_is_valid(data->eoc_gpio))
298 ret = wait_conversion_complete_gpio(data);
299 else
300 ret = wait_conversion_complete_polled(data);
301 if (ret < 0)
302 goto exit;
303
304 if (ret & AK8975_REG_ST1_DRDY_MASK) {
305 ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST2);
306 if (ret < 0) {
307 dev_err(&client->dev, "Error in reading ST2\n");
308 goto exit;
309 }
310 if (ret & (AK8975_REG_ST2_DERR_MASK |
311 AK8975_REG_ST2_HOFL_MASK)) {
312 dev_err(&client->dev, "ST2 status error 0x%x\n", ret);
313 ret = -EINVAL;
314 goto exit;
315 }
316 }
317
318 /* Read the flux value from the appropriate register
319 (the register is specified in the iio device attributes). */
320 ret = i2c_smbus_read_word_data(client, ak8975_index_to_reg[index]);
321 if (ret < 0) {
322 dev_err(&client->dev, "Read axis data fails\n");
323 goto exit;
324 }
325 meas_reg = ret;
326
327 mutex_unlock(&data->lock);
328
329 /* Endian conversion of the measured values. */
330 raw = (s16) (le16_to_cpu(meas_reg));
331
332 /* Clamp to valid range. */
333 raw = clamp_t(s16, raw, -4096, 4095);
334 *val = raw;
335 return IIO_VAL_INT;
336
337exit:
338 mutex_unlock(&data->lock);
339 return ret;
340}
341
342static int ak8975_read_raw(struct iio_dev *indio_dev,
343 struct iio_chan_spec const *chan,
344 int *val, int *val2,
345 long mask)
346{
347 struct ak8975_data *data = iio_priv(indio_dev);
348
349 switch (mask) {
350 case IIO_CHAN_INFO_RAW:
351 return ak8975_read_axis(indio_dev, chan->address, val);
352 case IIO_CHAN_INFO_SCALE:
353 *val = data->raw_to_gauss[chan->address];
354 return IIO_VAL_INT;
355 }
356 return -EINVAL;
357}
358
359#define AK8975_CHANNEL(axis, index) \
360 { \
361 .type = IIO_MAGN, \
362 .modified = 1, \
363 .channel2 = IIO_MOD_##axis, \
364 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
365 BIT(IIO_CHAN_INFO_SCALE), \
366 .address = index, \
367 }
368
369static const struct iio_chan_spec ak8975_channels[] = {
370 AK8975_CHANNEL(X, 0), AK8975_CHANNEL(Y, 1), AK8975_CHANNEL(Z, 2),
371};
372
373static const struct iio_info ak8975_info = {
374 .read_raw = &ak8975_read_raw,
375 .driver_module = THIS_MODULE,
376};
377
378static int ak8975_probe(struct i2c_client *client,
379 const struct i2c_device_id *id)
380{
381 struct ak8975_data *data;
382 struct iio_dev *indio_dev;
383 int eoc_gpio;
384 int err;
385
386 /* Grab and set up the supplied GPIO. */
387 if (client->dev.platform_data == NULL)
388 eoc_gpio = -1;
389 else
390 eoc_gpio = *(int *)(client->dev.platform_data);
391
392 /* We may not have a GPIO based IRQ to scan, that is fine, we will
393 poll if so */
394 if (gpio_is_valid(eoc_gpio)) {
395 err = gpio_request_one(eoc_gpio, GPIOF_IN, "ak_8975");
396 if (err < 0) {
397 dev_err(&client->dev,
398 "failed to request GPIO %d, error %d\n",
399 eoc_gpio, err);
400 goto exit;
401 }
402 }
403
404 /* Register with IIO */
405 indio_dev = iio_device_alloc(sizeof(*data));
406 if (indio_dev == NULL) {
407 err = -ENOMEM;
408 goto exit_gpio;
409 }
410 data = iio_priv(indio_dev);
411 i2c_set_clientdata(client, indio_dev);
412 /* Perform some basic start-of-day setup of the device. */
413 err = ak8975_setup(client);
414 if (err < 0) {
415 dev_err(&client->dev, "AK8975 initialization fails\n");
416 goto exit_free_iio;
417 }
418
419 data->client = client;
420 mutex_init(&data->lock);
421 data->eoc_gpio = eoc_gpio;
422 indio_dev->dev.parent = &client->dev;
423 indio_dev->channels = ak8975_channels;
424 indio_dev->num_channels = ARRAY_SIZE(ak8975_channels);
425 indio_dev->info = &ak8975_info;
426 indio_dev->modes = INDIO_DIRECT_MODE;
427
428 err = iio_device_register(indio_dev);
429 if (err < 0)
430 goto exit_free_iio;
431
432 return 0;
433
434exit_free_iio:
435 iio_device_free(indio_dev);
436exit_gpio:
437 if (gpio_is_valid(eoc_gpio))
438 gpio_free(eoc_gpio);
439exit:
440 return err;
441}
442
443static int ak8975_remove(struct i2c_client *client)
444{
445 struct iio_dev *indio_dev = i2c_get_clientdata(client);
446 struct ak8975_data *data = iio_priv(indio_dev);
447
448 iio_device_unregister(indio_dev);
449
450 if (gpio_is_valid(data->eoc_gpio))
451 gpio_free(data->eoc_gpio);
452
453 iio_device_free(indio_dev);
454
455 return 0;
456}
457
458static const struct i2c_device_id ak8975_id[] = {
459 {"ak8975", 0},
460 {}
461};
462
463MODULE_DEVICE_TABLE(i2c, ak8975_id);
464
465static const struct of_device_id ak8975_of_match[] = {
466 { .compatible = "asahi-kasei,ak8975", },
467 { .compatible = "ak8975", },
468 { }
469};
470MODULE_DEVICE_TABLE(of, ak8975_of_match);
471
472static struct i2c_driver ak8975_driver = {
473 .driver = {
474 .name = "ak8975",
475 .of_match_table = ak8975_of_match,
476 },
477 .probe = ak8975_probe,
478 .remove = ak8975_remove,
479 .id_table = ak8975_id,
480};
481module_i2c_driver(ak8975_driver);
482
483MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
484MODULE_DESCRIPTION("AK8975 magnetometer driver");
485MODULE_LICENSE("GPL");