Commit | Line | Data |
---|---|---|
3285aae1 AC |
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 "../iio.h" | |
34 | #include "magnet.h" | |
35 | ||
36 | /* | |
37 | * Register definitions, as well as various shifts and masks to get at the | |
38 | * individual fields of the registers. | |
39 | */ | |
40 | #define AK8975_REG_WIA 0x00 | |
41 | #define AK8975_DEVICE_ID 0x48 | |
42 | ||
43 | #define AK8975_REG_INFO 0x01 | |
44 | ||
45 | #define AK8975_REG_ST1 0x02 | |
46 | #define AK8975_REG_ST1_DRDY_SHIFT 0 | |
47 | #define AK8975_REG_ST1_DRDY_MASK (1 << AK8975_REG_ST1_DRDY_SHIFT) | |
48 | ||
49 | #define AK8975_REG_HXL 0x03 | |
50 | #define AK8975_REG_HXH 0x04 | |
51 | #define AK8975_REG_HYL 0x05 | |
52 | #define AK8975_REG_HYH 0x06 | |
53 | #define AK8975_REG_HZL 0x07 | |
54 | #define AK8975_REG_HZH 0x08 | |
55 | #define AK8975_REG_ST2 0x09 | |
56 | #define AK8975_REG_ST2_DERR_SHIFT 2 | |
57 | #define AK8975_REG_ST2_DERR_MASK (1 << AK8975_REG_ST2_DERR_SHIFT) | |
58 | ||
59 | #define AK8975_REG_ST2_HOFL_SHIFT 3 | |
60 | #define AK8975_REG_ST2_HOFL_MASK (1 << AK8975_REG_ST2_HOFL_SHIFT) | |
61 | ||
62 | #define AK8975_REG_CNTL 0x0A | |
63 | #define AK8975_REG_CNTL_MODE_SHIFT 0 | |
64 | #define AK8975_REG_CNTL_MODE_MASK (0xF << AK8975_REG_CNTL_MODE_SHIFT) | |
65 | #define AK8975_REG_CNTL_MODE_POWER_DOWN 0 | |
66 | #define AK8975_REG_CNTL_MODE_ONCE 1 | |
67 | #define AK8975_REG_CNTL_MODE_SELF_TEST 8 | |
68 | #define AK8975_REG_CNTL_MODE_FUSE_ROM 0xF | |
69 | ||
70 | #define AK8975_REG_RSVC 0x0B | |
71 | #define AK8975_REG_ASTC 0x0C | |
72 | #define AK8975_REG_TS1 0x0D | |
73 | #define AK8975_REG_TS2 0x0E | |
74 | #define AK8975_REG_I2CDIS 0x0F | |
75 | #define AK8975_REG_ASAX 0x10 | |
76 | #define AK8975_REG_ASAY 0x11 | |
77 | #define AK8975_REG_ASAZ 0x12 | |
78 | ||
79 | #define AK8975_MAX_REGS AK8975_REG_ASAZ | |
80 | ||
81 | /* | |
82 | * Miscellaneous values. | |
83 | */ | |
84 | #define AK8975_MAX_CONVERSION_TIMEOUT 500 | |
85 | #define AK8975_CONVERSION_DONE_POLL_TIME 10 | |
86 | ||
87 | /* | |
88 | * Per-instance context data for the device. | |
89 | */ | |
90 | struct ak8975_data { | |
91 | struct i2c_client *client; | |
92 | struct iio_dev *indio_dev; | |
93 | struct attribute_group attrs; | |
94 | struct mutex lock; | |
95 | u8 asa[3]; | |
96 | long raw_to_gauss[3]; | |
97 | unsigned long mode; | |
98 | u8 reg_cache[AK8975_MAX_REGS]; | |
99 | int eoc_gpio; | |
100 | int eoc_irq; | |
101 | }; | |
102 | ||
103 | /* | |
104 | * Helper function to write to the I2C device's registers. | |
105 | */ | |
106 | static int ak8975_write_data(struct i2c_client *client, | |
107 | u8 reg, u8 val, u8 mask, u8 shift) | |
108 | { | |
109 | u8 regval; | |
110 | struct i2c_msg msg; | |
111 | u8 w_data[2]; | |
112 | int ret = 0; | |
113 | ||
114 | struct ak8975_data *data = i2c_get_clientdata(client); | |
115 | ||
116 | regval = data->reg_cache[reg]; | |
117 | regval &= ~mask; | |
118 | regval |= val << shift; | |
119 | ||
120 | w_data[0] = reg; | |
121 | w_data[1] = regval; | |
122 | ||
123 | msg.addr = client->addr; | |
124 | msg.flags = 0; | |
125 | msg.len = 2; | |
126 | msg.buf = w_data; | |
127 | ||
128 | ret = i2c_transfer(client->adapter, &msg, 1); | |
129 | if (ret < 0) { | |
130 | dev_err(&client->dev, "Write to device fails status %x\n", ret); | |
131 | return ret; | |
132 | } | |
133 | data->reg_cache[reg] = regval; | |
134 | ||
135 | return 0; | |
136 | } | |
137 | ||
138 | /* | |
139 | * Helper function to read a contiguous set of the I2C device's registers. | |
140 | */ | |
141 | static int ak8975_read_data(struct i2c_client *client, | |
142 | u8 reg, u8 length, u8 *buffer) | |
143 | { | |
144 | struct i2c_msg msg[2]; | |
145 | u8 w_data[2]; | |
146 | int ret; | |
147 | ||
148 | w_data[0] = reg; | |
149 | ||
150 | msg[0].addr = client->addr; | |
151 | msg[0].flags = I2C_M_NOSTART; /* set repeated start and write */ | |
152 | msg[0].len = 1; | |
153 | msg[0].buf = w_data; | |
154 | ||
155 | msg[1].addr = client->addr; | |
156 | msg[1].flags = I2C_M_RD; | |
157 | msg[1].len = length; | |
158 | msg[1].buf = buffer; | |
159 | ||
160 | ret = i2c_transfer(client->adapter, msg, 2); | |
161 | if (ret < 0) { | |
162 | dev_err(&client->dev, "Read from device fails\n"); | |
163 | return ret; | |
164 | } | |
165 | ||
166 | return 0; | |
167 | } | |
168 | ||
169 | /* | |
170 | * Perform some start-of-day setup, including reading the asa calibration | |
171 | * values and caching them. | |
172 | */ | |
173 | static int ak8975_setup(struct i2c_client *client) | |
174 | { | |
175 | struct ak8975_data *data = i2c_get_clientdata(client); | |
176 | u8 device_id; | |
177 | int ret; | |
178 | ||
179 | /* Confirm that the device we're talking to is really an AK8975. */ | |
180 | ret = ak8975_read_data(client, AK8975_REG_WIA, 1, &device_id); | |
181 | if (ret < 0) { | |
182 | dev_err(&client->dev, "Error reading WIA\n"); | |
183 | return ret; | |
184 | } | |
185 | if (device_id != AK8975_DEVICE_ID) { | |
186 | dev_err(&client->dev, "Device ak8975 not found\n"); | |
187 | return -ENODEV; | |
188 | } | |
189 | ||
190 | /* Write the fused rom access mode. */ | |
191 | ret = ak8975_write_data(client, | |
192 | AK8975_REG_CNTL, | |
193 | AK8975_REG_CNTL_MODE_FUSE_ROM, | |
194 | AK8975_REG_CNTL_MODE_MASK, | |
195 | AK8975_REG_CNTL_MODE_SHIFT); | |
196 | if (ret < 0) { | |
197 | dev_err(&client->dev, "Error in setting fuse access mode\n"); | |
198 | return ret; | |
199 | } | |
200 | ||
201 | /* Get asa data and store in the device data. */ | |
202 | ret = ak8975_read_data(client, AK8975_REG_ASAX, 3, data->asa); | |
203 | if (ret < 0) { | |
204 | dev_err(&client->dev, "Not able to read asa data\n"); | |
205 | return ret; | |
206 | } | |
207 | ||
208 | /* Precalculate scale factor for each axis and | |
209 | store in the device data. */ | |
210 | data->raw_to_gauss[0] = ((data->asa[0] + 128) * 30) >> 8; | |
211 | data->raw_to_gauss[1] = ((data->asa[1] + 128) * 30) >> 8; | |
212 | data->raw_to_gauss[2] = ((data->asa[2] + 128) * 30) >> 8; | |
213 | ||
214 | return 0; | |
215 | } | |
216 | ||
217 | /* | |
218 | * Shows the device's mode. 0 = off, 1 = on. | |
219 | */ | |
220 | static ssize_t show_mode(struct device *dev, struct device_attribute *devattr, | |
221 | char *buf) | |
222 | { | |
223 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | |
224 | struct ak8975_data *data = indio_dev->dev_data; | |
225 | ||
226 | return sprintf(buf, "%lu\n", data->mode); | |
227 | } | |
228 | ||
229 | /* | |
230 | * Sets the device's mode. 0 = off, 1 = on. The device's mode must be on | |
231 | * for the magn raw attributes to be available. | |
232 | */ | |
233 | static ssize_t store_mode(struct device *dev, struct device_attribute *devattr, | |
234 | const char *buf, size_t count) | |
235 | { | |
236 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | |
237 | struct ak8975_data *data = indio_dev->dev_data; | |
238 | struct i2c_client *client = data->client; | |
239 | unsigned long oval; | |
240 | int ret; | |
241 | ||
242 | /* Convert mode string and do some basic sanity checking on it. | |
243 | only 0 or 1 are valid. */ | |
244 | if (strict_strtoul(buf, 10, &oval)) | |
245 | return -EINVAL; | |
246 | ||
247 | if (oval > 1) { | |
248 | dev_err(dev, "mode value is not supported\n"); | |
249 | return -EINVAL; | |
250 | } | |
251 | ||
252 | mutex_lock(&data->lock); | |
253 | ||
254 | /* Write the mode to the device. */ | |
255 | if (data->mode != oval) { | |
256 | ret = ak8975_write_data(client, | |
257 | AK8975_REG_CNTL, | |
258 | (u8)oval, | |
259 | AK8975_REG_CNTL_MODE_MASK, | |
260 | AK8975_REG_CNTL_MODE_SHIFT); | |
261 | ||
262 | if (ret < 0) { | |
263 | dev_err(&client->dev, "Error in setting mode\n"); | |
264 | mutex_unlock(&data->lock); | |
265 | return ret; | |
266 | } | |
267 | data->mode = oval; | |
268 | } | |
269 | ||
270 | mutex_unlock(&data->lock); | |
271 | ||
272 | return count; | |
273 | } | |
274 | ||
275 | /* | |
276 | * Emits the scale factor to bring the raw value into Gauss units. | |
277 | * | |
278 | * This scale factor is axis-dependent, and is derived from 3 calibration | |
279 | * factors ASA(x), ASA(y), and ASA(z). | |
280 | * | |
281 | * These ASA values are read from the sensor device at start of day, and | |
282 | * cached in the device context struct. | |
283 | * | |
284 | * Adjusting the flux value with the sensitivity adjustment value should be | |
285 | * done via the following formula: | |
286 | * | |
287 | * Hadj = H * ( ( ( (ASA-128)*0.5 ) / 128 ) + 1 ) | |
288 | * | |
289 | * where H is the raw value, ASA is the sensitivity adjustment, and Hadj | |
290 | * is the resultant adjusted value. | |
291 | * | |
292 | * We reduce the formula to: | |
293 | * | |
294 | * Hadj = H * (ASA + 128) / 256 | |
295 | * | |
296 | * H is in the range of -4096 to 4095. The magnetometer has a range of | |
297 | * +-1229uT. To go from the raw value to uT is: | |
298 | * | |
299 | * HuT = H * 1229/4096, or roughly, 3/10. | |
300 | * | |
301 | * Since 1uT = 100 gauss, our final scale factor becomes: | |
302 | * | |
303 | * Hadj = H * ((ASA + 128) / 256) * 3/10 * 100 | |
304 | * Hadj = H * ((ASA + 128) * 30 / 256 | |
305 | * | |
306 | * Since ASA doesn't change, we cache the resultant scale factor into the | |
307 | * device context in ak8975_setup(). | |
308 | */ | |
309 | static ssize_t show_scale(struct device *dev, struct device_attribute *devattr, | |
310 | char *buf) | |
311 | { | |
312 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | |
313 | struct ak8975_data *data = indio_dev->dev_data; | |
314 | struct iio_dev_attr *this_attr = to_iio_dev_attr(devattr); | |
315 | ||
316 | return sprintf(buf, "%ld\n", data->raw_to_gauss[this_attr->address]); | |
317 | } | |
318 | ||
319 | /* | |
320 | * Emits the raw flux value for the x, y, or z axis. | |
321 | */ | |
322 | static ssize_t show_raw(struct device *dev, struct device_attribute *devattr, | |
323 | char *buf) | |
324 | { | |
325 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | |
326 | struct ak8975_data *data = indio_dev->dev_data; | |
327 | struct i2c_client *client = data->client; | |
328 | struct iio_dev_attr *this_attr = to_iio_dev_attr(devattr); | |
329 | u32 timeout_ms = AK8975_MAX_CONVERSION_TIMEOUT; | |
330 | u16 meas_reg; | |
331 | s16 raw; | |
332 | u8 read_status; | |
333 | int ret; | |
334 | ||
335 | mutex_lock(&data->lock); | |
336 | ||
337 | if (data->mode == 0) { | |
338 | dev_err(&client->dev, "Operating mode is in power down mode\n"); | |
339 | ret = -EBUSY; | |
340 | goto exit; | |
341 | } | |
342 | ||
343 | /* Set up the device for taking a sample. */ | |
344 | ret = ak8975_write_data(client, | |
345 | AK8975_REG_CNTL, | |
346 | AK8975_REG_CNTL_MODE_ONCE, | |
347 | AK8975_REG_CNTL_MODE_MASK, | |
348 | AK8975_REG_CNTL_MODE_SHIFT); | |
349 | if (ret < 0) { | |
350 | dev_err(&client->dev, "Error in setting operating mode\n"); | |
351 | goto exit; | |
352 | } | |
353 | ||
354 | /* Wait for the conversion to complete. */ | |
355 | while (timeout_ms) { | |
356 | msleep(AK8975_CONVERSION_DONE_POLL_TIME); | |
357 | if (gpio_get_value(data->eoc_gpio)) | |
358 | break; | |
359 | timeout_ms -= AK8975_CONVERSION_DONE_POLL_TIME; | |
360 | } | |
361 | if (!timeout_ms) { | |
362 | dev_err(&client->dev, "Conversion timeout happened\n"); | |
363 | ret = -EINVAL; | |
364 | goto exit; | |
365 | } | |
366 | ||
367 | ret = ak8975_read_data(client, AK8975_REG_ST1, 1, &read_status); | |
368 | if (ret < 0) { | |
369 | dev_err(&client->dev, "Error in reading ST1\n"); | |
370 | goto exit; | |
371 | } | |
372 | ||
373 | if (read_status & AK8975_REG_ST1_DRDY_MASK) { | |
374 | ret = ak8975_read_data(client, AK8975_REG_ST2, 1, &read_status); | |
375 | if (ret < 0) { | |
376 | dev_err(&client->dev, "Error in reading ST2\n"); | |
377 | goto exit; | |
378 | } | |
379 | if (read_status & (AK8975_REG_ST2_DERR_MASK | | |
380 | AK8975_REG_ST2_HOFL_MASK)) { | |
381 | dev_err(&client->dev, "ST2 status error 0x%x\n", | |
382 | read_status); | |
383 | ret = -EINVAL; | |
384 | goto exit; | |
385 | } | |
386 | } | |
387 | ||
388 | /* Read the flux value from the appropriate register | |
389 | (the register is specified in the iio device attributes). */ | |
390 | ret = ak8975_read_data(client, this_attr->address, 2, (u8 *)&meas_reg); | |
391 | if (ret < 0) { | |
392 | dev_err(&client->dev, "Read axis data fails\n"); | |
393 | goto exit; | |
394 | } | |
395 | ||
396 | mutex_unlock(&data->lock); | |
397 | ||
398 | /* Endian conversion of the measured values. */ | |
399 | raw = (s16) (le16_to_cpu(meas_reg)); | |
400 | ||
401 | /* Clamp to valid range. */ | |
402 | raw = clamp_t(s16, raw, -4096, 4095); | |
403 | ||
404 | return sprintf(buf, "%d\n", raw); | |
405 | ||
406 | exit: | |
407 | mutex_unlock(&data->lock); | |
408 | return ret; | |
409 | } | |
410 | ||
411 | static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, show_mode, store_mode, 0); | |
412 | static IIO_DEV_ATTR_MAGN_X_SCALE(S_IRUGO, show_scale, NULL, 0); | |
413 | static IIO_DEV_ATTR_MAGN_Y_SCALE(S_IRUGO, show_scale, NULL, 1); | |
414 | static IIO_DEV_ATTR_MAGN_Z_SCALE(S_IRUGO, show_scale, NULL, 2); | |
415 | static IIO_DEV_ATTR_MAGN_X(show_raw, AK8975_REG_HXL); | |
416 | static IIO_DEV_ATTR_MAGN_Y(show_raw, AK8975_REG_HYL); | |
417 | static IIO_DEV_ATTR_MAGN_Z(show_raw, AK8975_REG_HZL); | |
418 | ||
419 | static struct attribute *ak8975_attr[] = { | |
420 | &iio_dev_attr_mode.dev_attr.attr, | |
421 | &iio_dev_attr_magn_x_scale.dev_attr.attr, | |
422 | &iio_dev_attr_magn_y_scale.dev_attr.attr, | |
423 | &iio_dev_attr_magn_z_scale.dev_attr.attr, | |
424 | &iio_dev_attr_magn_x_raw.dev_attr.attr, | |
425 | &iio_dev_attr_magn_y_raw.dev_attr.attr, | |
426 | &iio_dev_attr_magn_z_raw.dev_attr.attr, | |
427 | NULL | |
428 | }; | |
429 | ||
430 | static struct attribute_group ak8975_attr_group = { | |
431 | .attrs = ak8975_attr, | |
432 | }; | |
433 | ||
434 | static int ak8975_probe(struct i2c_client *client, | |
435 | const struct i2c_device_id *id) | |
436 | { | |
437 | struct ak8975_data *data; | |
438 | int err; | |
439 | ||
440 | /* Allocate our device context. */ | |
441 | data = kzalloc(sizeof(struct ak8975_data), GFP_KERNEL); | |
442 | if (!data) { | |
443 | dev_err(&client->dev, "Memory allocation fails\n"); | |
444 | err = -ENOMEM; | |
445 | goto exit; | |
446 | } | |
447 | ||
448 | i2c_set_clientdata(client, data); | |
449 | data->client = client; | |
450 | ||
451 | mutex_init(&data->lock); | |
452 | ||
453 | /* Grab and set up the supplied GPIO. */ | |
454 | data->eoc_irq = client->irq; | |
ecc1058a | 455 | data->eoc_gpio = irq_to_gpio(client->irq); |
3285aae1 AC |
456 | |
457 | if (!data->eoc_gpio) { | |
458 | dev_err(&client->dev, "failed, no valid GPIO\n"); | |
459 | err = -EINVAL; | |
460 | goto exit_free; | |
461 | } | |
462 | ||
463 | err = gpio_request(data->eoc_gpio, "ak_8975"); | |
464 | if (err < 0) { | |
465 | dev_err(&client->dev, "failed to request GPIO %d, error %d\n", | |
466 | data->eoc_gpio, err); | |
467 | goto exit_free; | |
468 | } | |
469 | ||
470 | err = gpio_direction_input(data->eoc_gpio); | |
471 | if (err < 0) { | |
472 | dev_err(&client->dev, "Failed to configure input direction for" | |
473 | " GPIO %d, error %d\n", data->eoc_gpio, err); | |
474 | goto exit_gpio; | |
475 | } | |
476 | ||
477 | /* Perform some basic start-of-day setup of the device. */ | |
478 | err = ak8975_setup(client); | |
479 | if (err < 0) { | |
480 | dev_err(&client->dev, "AK8975 initialization fails\n"); | |
481 | goto exit_gpio; | |
482 | } | |
483 | ||
484 | /* Register with IIO */ | |
485 | data->indio_dev = iio_allocate_device(); | |
486 | if (data->indio_dev == NULL) { | |
487 | err = -ENOMEM; | |
488 | goto exit_gpio; | |
489 | } | |
490 | ||
491 | data->indio_dev->dev.parent = &client->dev; | |
492 | data->indio_dev->attrs = &ak8975_attr_group; | |
493 | data->indio_dev->dev_data = (void *)(data); | |
494 | data->indio_dev->driver_module = THIS_MODULE; | |
495 | data->indio_dev->modes = INDIO_DIRECT_MODE; | |
496 | ||
497 | err = iio_device_register(data->indio_dev); | |
498 | if (err < 0) | |
499 | goto exit_free_iio; | |
500 | ||
501 | return 0; | |
502 | ||
503 | exit_free_iio: | |
504 | iio_free_device(data->indio_dev); | |
505 | exit_gpio: | |
506 | gpio_free(data->eoc_gpio); | |
507 | exit_free: | |
508 | kfree(data); | |
509 | exit: | |
510 | return err; | |
511 | } | |
512 | ||
513 | static int ak8975_remove(struct i2c_client *client) | |
514 | { | |
515 | struct ak8975_data *data = i2c_get_clientdata(client); | |
516 | ||
517 | iio_device_unregister(data->indio_dev); | |
518 | iio_free_device(data->indio_dev); | |
519 | ||
520 | gpio_free(data->eoc_gpio); | |
521 | ||
522 | kfree(data); | |
523 | ||
524 | return 0; | |
525 | } | |
526 | ||
527 | static const struct i2c_device_id ak8975_id[] = { | |
528 | {"ak8975", 0}, | |
529 | {} | |
530 | }; | |
531 | ||
532 | MODULE_DEVICE_TABLE(i2c, ak8975_id); | |
533 | ||
534 | static struct i2c_driver ak8975_driver = { | |
535 | .driver = { | |
536 | .name = "ak8975", | |
537 | }, | |
538 | .probe = ak8975_probe, | |
539 | .remove = __devexit_p(ak8975_remove), | |
540 | .id_table = ak8975_id, | |
541 | }; | |
542 | ||
543 | static int __init ak8975_init(void) | |
544 | { | |
545 | return i2c_add_driver(&ak8975_driver); | |
546 | } | |
547 | ||
548 | static void __exit ak8975_exit(void) | |
549 | { | |
550 | i2c_del_driver(&ak8975_driver); | |
551 | } | |
552 | ||
553 | module_init(ak8975_init); | |
554 | module_exit(ak8975_exit); | |
555 | ||
556 | MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); | |
557 | MODULE_DESCRIPTION("AK8975 magnetometer driver"); | |
558 | MODULE_LICENSE("GPL"); |