blob: d25b06ef80751c07abafacafb688a3777b6e3cd8 [file] [log] [blame]
Shubhrajyoti Db4e17822010-07-17 18:32:52 +05301/* Copyright (C) 2010 Texas Instruments
2 Author: Shubhrajyoti Datta <shubhrajyoti@ti.com>
3 Acknowledgement: Jonathan Cameron <jic23@cam.ac.uk> for valuable inputs.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
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 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19
20#include <linux/module.h>
21#include <linux/init.h>
22#include <linux/i2c.h>
23#include <linux/slab.h>
24#include <linux/types.h>
Jonathan Cameron06458e22012-04-25 15:54:58 +010025#include <linux/iio/iio.h>
26#include <linux/iio/sysfs.h>
Shubhrajyoti Db4e17822010-07-17 18:32:52 +053027
Shubhrajyoti Db4e17822010-07-17 18:32:52 +053028#define HMC5843_CONFIG_REG_A 0x00
29#define HMC5843_CONFIG_REG_B 0x01
30#define HMC5843_MODE_REG 0x02
31#define HMC5843_DATA_OUT_X_MSB_REG 0x03
32#define HMC5843_DATA_OUT_X_LSB_REG 0x04
33#define HMC5843_DATA_OUT_Y_MSB_REG 0x05
34#define HMC5843_DATA_OUT_Y_LSB_REG 0x06
35#define HMC5843_DATA_OUT_Z_MSB_REG 0x07
36#define HMC5843_DATA_OUT_Z_LSB_REG 0x08
Peter Meerwald16b91a42012-05-16 18:22:05 +020037/* Beware: Y and Z are exchanged on HMC5883 */
38#define HMC5883_DATA_OUT_Z_MSB_REG 0x05
39#define HMC5883_DATA_OUT_Z_LSB_REG 0x06
40#define HMC5883_DATA_OUT_Y_MSB_REG 0x07
41#define HMC5883_DATA_OUT_Y_LSB_REG 0x08
Shubhrajyoti Db4e17822010-07-17 18:32:52 +053042#define HMC5843_STATUS_REG 0x09
43#define HMC5843_ID_REG_A 0x0A
44#define HMC5843_ID_REG_B 0x0B
45#define HMC5843_ID_REG_C 0x0C
46
Shubhrajyoti Db4e17822010-07-17 18:32:52 +053047
48/*
Peter Meerwald16b91a42012-05-16 18:22:05 +020049 * Beware: identification of the HMC5883 is still "H43";
50 * I2C address is also unchanged
51 */
52#define HMC5843_ID_REG_LENGTH 0x03
53#define HMC5843_ID_STRING "H43"
54#define HMC5843_I2C_ADDRESS 0x1E
Shubhrajyoti Db4e17822010-07-17 18:32:52 +053055
Peter Meerwald16b91a42012-05-16 18:22:05 +020056/*
57 * Range gain settings in (+-)Ga
58 * Beware: HMC5843 and HMC5883 have different recommended sensor field
59 * ranges; default corresponds to +-1.0 Ga and +-1.3 Ga, respectively
60 */
61#define HMC5843_RANGE_GAIN_OFFSET 0x05
62#define HMC5843_RANGE_GAIN_DEFAULT 0x01
63#define HMC5843_RANGE_GAIN_MAX 0x07
Shubhrajyoti Db4e17822010-07-17 18:32:52 +053064
65/*
66 * Device status
67 */
Peter Meerwald16b91a42012-05-16 18:22:05 +020068#define HMC5843_DATA_READY 0x01
69#define HMC5843_DATA_OUTPUT_LOCK 0x02
70/* Does not exist on HMC5883, not used */
71#define HMC5843_VOLTAGE_REGULATOR_ENABLED 0x04
Shubhrajyoti Db4e17822010-07-17 18:32:52 +053072
73/*
74 * Mode register configuration
75 */
Peter Meerwald16b91a42012-05-16 18:22:05 +020076#define HMC5843_MODE_CONVERSION_CONTINUOUS 0x00
77#define HMC5843_MODE_CONVERSION_SINGLE 0x01
78#define HMC5843_MODE_IDLE 0x02
79#define HMC5843_MODE_SLEEP 0x03
80#define HMC5843_MODE_MASK 0x03
Shubhrajyoti Db4e17822010-07-17 18:32:52 +053081
82/*
Peter Meerwald16b91a42012-05-16 18:22:05 +020083 * HMC5843: Minimum data output rate
84 * HMC5883: Typical data output rate
Shubhrajyoti Db4e17822010-07-17 18:32:52 +053085 */
Peter Meerwald16b91a42012-05-16 18:22:05 +020086#define HMC5843_RATE_OFFSET 0x02
87#define HMC5843_RATE_BITMASK 0x1C
Peter Meerwald16b91a42012-05-16 18:22:05 +020088#define HMC5843_RATE_NOT_USED 0x07
89
90/*
91 * Device measurement configuration
92 */
93#define HMC5843_MEAS_CONF_NORMAL 0x00
94#define HMC5843_MEAS_CONF_POSITIVE_BIAS 0x01
95#define HMC5843_MEAS_CONF_NEGATIVE_BIAS 0x02
96#define HMC5843_MEAS_CONF_NOT_USED 0x03
97#define HMC5843_MEAS_CONF_MASK 0x03
98
99/*
100 * Scaling factors: 10000000/Gain
101 */
102static const int hmc5843_regval_to_nanoscale[] = {
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100103 6173, 7692, 10309, 12821, 18868, 21739, 25641, 35714
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530104};
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100105
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530106static const int regval_to_input_field_mg[] = {
107 700,
108 1000,
109 1500,
110 2000,
111 3200,
112 3800,
113 4500,
114 6500
115};
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100116static const char * const regval_to_samp_freq[] = {
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530117 "0.5",
118 "1",
119 "2",
120 "5",
121 "10",
122 "20",
123 "50",
124};
125
126/* Addresses to scan: 0x1E */
127static const unsigned short normal_i2c[] = { HMC5843_I2C_ADDRESS,
Peter Meerwald16b91a42012-05-16 18:22:05 +0200128 I2C_CLIENT_END };
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530129
130/* Each client has this additional data */
131struct hmc5843_data {
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530132 struct mutex lock;
133 u8 rate;
134 u8 meas_conf;
135 u8 operating_mode;
136 u8 range;
137};
138
139static void hmc5843_init_client(struct i2c_client *client);
140
141static s32 hmc5843_configure(struct i2c_client *client,
142 u8 operating_mode)
143{
144 /* The lower two bits contain the current conversion mode */
145 return i2c_smbus_write_byte_data(client,
146 HMC5843_MODE_REG,
Peter Meerwald16b91a42012-05-16 18:22:05 +0200147 operating_mode & HMC5843_MODE_MASK);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530148}
149
Justin P. Mattock4abf6f82012-02-29 22:00:38 -0800150/* Return the measurement value from the specified channel */
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100151static int hmc5843_read_measurement(struct iio_dev *indio_dev,
152 int address,
153 int *val)
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530154{
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530155 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100156 struct hmc5843_data *data = iio_priv(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530157 s32 result;
158
159 mutex_lock(&data->lock);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530160 result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
Peter Meerwald16b91a42012-05-16 18:22:05 +0200161 while (!(result & HMC5843_DATA_READY))
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530162 result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
163
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100164 result = i2c_smbus_read_word_data(client, address);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530165 mutex_unlock(&data->lock);
166 if (result < 0)
167 return -EINVAL;
168
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100169 *val = (s16)swab16((u16)result);
170 return IIO_VAL_INT;
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530171}
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100172
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530173
174/*
175 * From the datasheet
176 * 0 - Continuous-Conversion Mode: In continuous-conversion mode, the
Justin P. Mattock4abf6f82012-02-29 22:00:38 -0800177 * device continuously performs conversions and places the result in the
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530178 * data register.
179 *
180 * 1 - Single-Conversion Mode : device performs a single measurement,
181 * sets RDY high and returned to sleep mode
182 *
183 * 2 - Idle Mode : Device is placed in idle mode.
184 *
185 * 3 - Sleep Mode. Device is placed in sleep mode.
186 *
187 */
188static ssize_t hmc5843_show_operating_mode(struct device *dev,
189 struct device_attribute *attr,
190 char *buf)
191{
Lars-Peter Clausen527cf712012-05-12 15:39:52 +0200192 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100193 struct hmc5843_data *data = iio_priv(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530194 return sprintf(buf, "%d\n", data->operating_mode);
195}
196
197static ssize_t hmc5843_set_operating_mode(struct device *dev,
198 struct device_attribute *attr,
199 const char *buf,
200 size_t count)
201{
Lars-Peter Clausen527cf712012-05-12 15:39:52 +0200202 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530203 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100204 struct hmc5843_data *data = iio_priv(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530205 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
206 unsigned long operating_mode = 0;
207 s32 status;
208 int error;
209 mutex_lock(&data->lock);
Peter Meerwaldd32ec552012-05-16 18:22:04 +0200210 error = kstrtoul(buf, 10, &operating_mode);
Julia Lawalld1ae4da2010-08-04 21:54:26 +0200211 if (error) {
212 count = error;
213 goto exit;
214 }
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530215 dev_dbg(dev, "set Conversion mode to %lu\n", operating_mode);
Peter Meerwald16b91a42012-05-16 18:22:05 +0200216 if (operating_mode > HMC5843_MODE_SLEEP) {
Julia Lawalld1ae4da2010-08-04 21:54:26 +0200217 count = -EINVAL;
218 goto exit;
219 }
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530220
221 status = i2c_smbus_write_byte_data(client, this_attr->address,
222 operating_mode);
223 if (status) {
224 count = -EINVAL;
225 goto exit;
226 }
227 data->operating_mode = operating_mode;
228
229exit:
230 mutex_unlock(&data->lock);
231 return count;
232}
233static IIO_DEVICE_ATTR(operating_mode,
234 S_IWUSR | S_IRUGO,
235 hmc5843_show_operating_mode,
236 hmc5843_set_operating_mode,
237 HMC5843_MODE_REG);
238
239/*
240 * API for setting the measurement configuration to
241 * Normal, Positive bias and Negative bias
242 * From the datasheet
243 *
244 * Normal measurement configuration (default): In normal measurement
245 * configuration the device follows normal measurement flow. Pins BP and BN
246 * are left floating and high impedance.
247 *
248 * Positive bias configuration: In positive bias configuration, a positive
249 * current is forced across the resistive load on pins BP and BN.
250 *
251 * Negative bias configuration. In negative bias configuration, a negative
252 * current is forced across the resistive load on pins BP and BN.
253 *
254 */
255static s32 hmc5843_set_meas_conf(struct i2c_client *client,
256 u8 meas_conf)
257{
Peter Meerwald0462e2b2012-05-16 18:22:03 +0200258 struct iio_dev *indio_dev = i2c_get_clientdata(client);
259 struct hmc5843_data *data = iio_priv(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530260 u8 reg_val;
Peter Meerwald16b91a42012-05-16 18:22:05 +0200261 reg_val = (meas_conf & HMC5843_MEAS_CONF_MASK) |
262 (data->rate << HMC5843_RATE_OFFSET);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530263 return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
264}
265
266static ssize_t hmc5843_show_measurement_configuration(struct device *dev,
267 struct device_attribute *attr,
268 char *buf)
269{
Lars-Peter Clausen527cf712012-05-12 15:39:52 +0200270 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100271 struct hmc5843_data *data = iio_priv(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530272 return sprintf(buf, "%d\n", data->meas_conf);
273}
274
275static ssize_t hmc5843_set_measurement_configuration(struct device *dev,
276 struct device_attribute *attr,
277 const char *buf,
278 size_t count)
279{
Lars-Peter Clausen527cf712012-05-12 15:39:52 +0200280 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530281 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
Peter Meerwald0462e2b2012-05-16 18:22:03 +0200282 struct hmc5843_data *data = iio_priv(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530283 unsigned long meas_conf = 0;
Peter Meerwalde278df12012-05-17 02:28:09 +0200284 int error;
285
286 error = kstrtoul(buf, 10, &meas_conf);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530287 if (error)
288 return error;
Peter Meerwalde278df12012-05-17 02:28:09 +0200289 if (meas_conf >= HMC5843_MEAS_CONF_NOT_USED)
290 return -EINVAL;
291
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530292 mutex_lock(&data->lock);
293
294 dev_dbg(dev, "set mode to %lu\n", meas_conf);
295 if (hmc5843_set_meas_conf(client, meas_conf)) {
296 count = -EINVAL;
297 goto exit;
298 }
299 data->meas_conf = meas_conf;
300
301exit:
302 mutex_unlock(&data->lock);
303 return count;
304}
305static IIO_DEVICE_ATTR(meas_conf,
306 S_IWUSR | S_IRUGO,
307 hmc5843_show_measurement_configuration,
308 hmc5843_set_measurement_configuration,
309 0);
310
311/*
312 * From Datasheet
313 * The table shows the minimum data output
314 * Value | Minimum data output rate(Hz)
315 * 0 | 0.5
316 * 1 | 1
317 * 2 | 2
318 * 3 | 5
319 * 4 | 10 (default)
320 * 5 | 20
321 * 6 | 50
322 * 7 | Not used
323 */
Manuel Stahl11f05c72010-08-31 14:27:33 +0200324static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("0.5 1 2 5 10 20 50");
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530325
326static s32 hmc5843_set_rate(struct i2c_client *client,
327 u8 rate)
328{
Peter Meerwald0462e2b2012-05-16 18:22:03 +0200329 struct iio_dev *indio_dev = i2c_get_clientdata(client);
330 struct hmc5843_data *data = iio_priv(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530331 u8 reg_val;
332
Peter Meerwald16b91a42012-05-16 18:22:05 +0200333 reg_val = (data->meas_conf) | (rate << HMC5843_RATE_OFFSET);
334 if (rate >= HMC5843_RATE_NOT_USED) {
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530335 dev_err(&client->dev,
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100336 "This data output rate is not supported\n");
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530337 return -EINVAL;
338 }
339 return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
340}
341
Peter Meerwald13f6eb62012-05-17 02:28:08 +0200342static int hmc5843_check_sampling_frequency(struct hmc5843_data *data,
343 const char *buf)
344{
345 const char * const *samp_freq = regval_to_samp_freq;
346 int i;
347
348 for (i = 0; i < HMC5843_RATE_NOT_USED; i++) {
349 if (strncmp(buf, samp_freq[i],
350 strlen(samp_freq[i])) == 0)
351 return i;
352 }
353
354 return -EINVAL;
355}
356
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530357static ssize_t set_sampling_frequency(struct device *dev,
358 struct device_attribute *attr,
359 const char *buf, size_t count)
360{
361
Lars-Peter Clausen527cf712012-05-12 15:39:52 +0200362 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530363 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100364 struct hmc5843_data *data = iio_priv(indio_dev);
Peter Meerwald13f6eb62012-05-17 02:28:08 +0200365 int rate;
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530366
Peter Meerwald13f6eb62012-05-17 02:28:08 +0200367 rate = hmc5843_check_sampling_frequency(data, buf);
368 if (rate < 0) {
369 dev_err(&client->dev,
370 "sampling frequency is not supported\n");
371 return rate;
372 }
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530373
374 mutex_lock(&data->lock);
Peter Meerwald13f6eb62012-05-17 02:28:08 +0200375 dev_dbg(dev, "set rate to %d\n", rate);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530376 if (hmc5843_set_rate(client, rate)) {
377 count = -EINVAL;
378 goto exit;
379 }
380 data->rate = rate;
381
382exit:
383 mutex_unlock(&data->lock);
384 return count;
385}
386
387static ssize_t show_sampling_frequency(struct device *dev,
388 struct device_attribute *attr, char *buf)
389{
Lars-Peter Clausen527cf712012-05-12 15:39:52 +0200390 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530391 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
392 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
Dan Carpenter213fd222010-08-10 07:37:33 +0200393 s32 rate;
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530394
395 rate = i2c_smbus_read_byte_data(client, this_attr->address);
396 if (rate < 0)
Dan Carpenter213fd222010-08-10 07:37:33 +0200397 return rate;
Peter Meerwald16b91a42012-05-16 18:22:05 +0200398 rate = (rate & HMC5843_RATE_BITMASK) >> HMC5843_RATE_OFFSET;
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530399 return sprintf(buf, "%s\n", regval_to_samp_freq[rate]);
400}
401static IIO_DEVICE_ATTR(sampling_frequency,
402 S_IWUSR | S_IRUGO,
403 show_sampling_frequency,
404 set_sampling_frequency,
405 HMC5843_CONFIG_REG_A);
406
407/*
408 * From Datasheet
409 * Nominal gain settings
410 * Value | Sensor Input Field Range(Ga) | Gain(counts/ milli-gauss)
411 *0 |(+-)0.7 |1620
412 *1 |(+-)1.0 |1300
413 *2 |(+-)1.5 |970
414 *3 |(+-)2.0 |780
415 *4 |(+-)3.2 |530
416 *5 |(+-)3.8 |460
417 *6 |(+-)4.5 |390
418 *7 |(+-)6.5 |280
419 */
420static ssize_t show_range(struct device *dev,
421 struct device_attribute *attr,
422 char *buf)
423{
424 u8 range;
Lars-Peter Clausen527cf712012-05-12 15:39:52 +0200425 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100426 struct hmc5843_data *data = iio_priv(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530427
428 range = data->range;
429 return sprintf(buf, "%d\n", regval_to_input_field_mg[range]);
430}
431
432static ssize_t set_range(struct device *dev,
433 struct device_attribute *attr,
434 const char *buf,
435 size_t count)
436{
Lars-Peter Clausen527cf712012-05-12 15:39:52 +0200437 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530438 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
439 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100440 struct hmc5843_data *data = iio_priv(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530441 unsigned long range = 0;
442 int error;
443 mutex_lock(&data->lock);
Peter Meerwaldd32ec552012-05-16 18:22:04 +0200444 error = kstrtoul(buf, 10, &range);
Julia Lawalld1ae4da2010-08-04 21:54:26 +0200445 if (error) {
446 count = error;
447 goto exit;
448 }
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530449 dev_dbg(dev, "set range to %lu\n", range);
450
Peter Meerwald16b91a42012-05-16 18:22:05 +0200451 if (range > HMC5843_RANGE_GAIN_MAX) {
Julia Lawalld1ae4da2010-08-04 21:54:26 +0200452 count = -EINVAL;
453 goto exit;
454 }
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530455
456 data->range = range;
Peter Meerwald16b91a42012-05-16 18:22:05 +0200457 range = range << HMC5843_RANGE_GAIN_OFFSET;
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530458 if (i2c_smbus_write_byte_data(client, this_attr->address, range))
459 count = -EINVAL;
460
Julia Lawalld1ae4da2010-08-04 21:54:26 +0200461exit:
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530462 mutex_unlock(&data->lock);
463 return count;
464
465}
Jonathan Cameron322c9562011-09-14 13:01:23 +0100466static IIO_DEVICE_ATTR(in_magn_range,
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530467 S_IWUSR | S_IRUGO,
468 show_range,
469 set_range,
470 HMC5843_CONFIG_REG_B);
471
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100472static int hmc5843_read_raw(struct iio_dev *indio_dev,
473 struct iio_chan_spec const *chan,
474 int *val, int *val2,
475 long mask)
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530476{
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100477 struct hmc5843_data *data = iio_priv(indio_dev);
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100478
479 switch (mask) {
Jonathan Cameron4d9948b2012-04-15 17:41:23 +0100480 case IIO_CHAN_INFO_RAW:
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100481 return hmc5843_read_measurement(indio_dev,
482 chan->address,
483 val);
Jonathan Cameronc8a9f802011-10-26 17:41:36 +0100484 case IIO_CHAN_INFO_SCALE:
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100485 *val = 0;
486 *val2 = hmc5843_regval_to_nanoscale[data->range];
487 return IIO_VAL_INT_PLUS_NANO;
488 };
489 return -EINVAL;
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530490}
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100491
492#define HMC5843_CHANNEL(axis, add) \
493 { \
494 .type = IIO_MAGN, \
495 .modified = 1, \
496 .channel2 = IIO_MOD_##axis, \
Jonathan Cameron4d9948b2012-04-15 17:41:23 +0100497 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
498 IIO_CHAN_INFO_SCALE_SHARED_BIT, \
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100499 .address = add \
500 }
501
502static const struct iio_chan_spec hmc5843_channels[] = {
503 HMC5843_CHANNEL(X, HMC5843_DATA_OUT_X_MSB_REG),
504 HMC5843_CHANNEL(Y, HMC5843_DATA_OUT_Y_MSB_REG),
505 HMC5843_CHANNEL(Z, HMC5843_DATA_OUT_Z_MSB_REG),
506};
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530507
508static struct attribute *hmc5843_attributes[] = {
509 &iio_dev_attr_meas_conf.dev_attr.attr,
510 &iio_dev_attr_operating_mode.dev_attr.attr,
511 &iio_dev_attr_sampling_frequency.dev_attr.attr,
Jonathan Cameron322c9562011-09-14 13:01:23 +0100512 &iio_dev_attr_in_magn_range.dev_attr.attr,
Manuel Stahl11f05c72010-08-31 14:27:33 +0200513 &iio_const_attr_sampling_frequency_available.dev_attr.attr,
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530514 NULL
515};
516
517static const struct attribute_group hmc5843_group = {
518 .attrs = hmc5843_attributes,
519};
520
521static int hmc5843_detect(struct i2c_client *client,
522 struct i2c_board_info *info)
523{
524 unsigned char id_str[HMC5843_ID_REG_LENGTH];
525
526 if (client->addr != HMC5843_I2C_ADDRESS)
527 return -ENODEV;
528
529 if (i2c_smbus_read_i2c_block_data(client, HMC5843_ID_REG_A,
530 HMC5843_ID_REG_LENGTH, id_str)
531 != HMC5843_ID_REG_LENGTH)
532 return -ENODEV;
533
534 if (0 != strncmp(id_str, HMC5843_ID_STRING, HMC5843_ID_REG_LENGTH))
535 return -ENODEV;
536
537 return 0;
538}
539
540/* Called when we have found a new HMC5843. */
541static void hmc5843_init_client(struct i2c_client *client)
542{
Marek Belisko62d2feb2012-04-12 21:48:03 +0200543 struct iio_dev *indio_dev = i2c_get_clientdata(client);
544 struct hmc5843_data *data = iio_priv(indio_dev);
545
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530546 hmc5843_set_meas_conf(client, data->meas_conf);
547 hmc5843_set_rate(client, data->rate);
548 hmc5843_configure(client, data->operating_mode);
549 i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_B, data->range);
550 mutex_init(&data->lock);
551 pr_info("HMC5843 initialized\n");
552}
553
Jonathan Cameron6fe81352011-05-18 14:42:37 +0100554static const struct iio_info hmc5843_info = {
555 .attrs = &hmc5843_group,
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100556 .read_raw = &hmc5843_read_raw,
Jonathan Cameron6fe81352011-05-18 14:42:37 +0100557 .driver_module = THIS_MODULE,
558};
559
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530560static int hmc5843_probe(struct i2c_client *client,
561 const struct i2c_device_id *id)
562{
563 struct hmc5843_data *data;
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100564 struct iio_dev *indio_dev;
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530565 int err = 0;
566
Lars-Peter Clausen7cbb7532012-04-26 13:35:01 +0200567 indio_dev = iio_device_alloc(sizeof(*data));
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100568 if (indio_dev == NULL) {
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530569 err = -ENOMEM;
570 goto exit;
571 }
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530572
Peter Meerwald16b91a42012-05-16 18:22:05 +0200573 /* default settings at probe */
574 data = iio_priv(indio_dev);
575 data->meas_conf = HMC5843_MEAS_CONF_NORMAL;
576 data->range = HMC5843_RANGE_GAIN_DEFAULT;
577 data->operating_mode = HMC5843_MODE_CONVERSION_CONTINUOUS;
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530578
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100579 i2c_set_clientdata(client, indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530580
581 /* Initialize the HMC5843 chip */
582 hmc5843_init_client(client);
583
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100584 indio_dev->info = &hmc5843_info;
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100585 indio_dev->name = id->name;
586 indio_dev->channels = hmc5843_channels;
587 indio_dev->num_channels = ARRAY_SIZE(hmc5843_channels);
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100588 indio_dev->dev.parent = &client->dev;
589 indio_dev->modes = INDIO_DIRECT_MODE;
590 err = iio_device_register(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530591 if (err)
592 goto exit_free2;
593 return 0;
594exit_free2:
Lars-Peter Clausen7cbb7532012-04-26 13:35:01 +0200595 iio_device_free(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530596exit:
597 return err;
598}
599
600static int hmc5843_remove(struct i2c_client *client)
601{
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100602 struct iio_dev *indio_dev = i2c_get_clientdata(client);
Jonathan Camerond2fffd62011-10-14 14:46:58 +0100603
604 iio_device_unregister(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530605 /* sleep mode to save power */
Peter Meerwald16b91a42012-05-16 18:22:05 +0200606 hmc5843_configure(client, HMC5843_MODE_SLEEP);
Lars-Peter Clausen7cbb7532012-04-26 13:35:01 +0200607 iio_device_free(indio_dev);
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100608
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530609 return 0;
610}
611
Lars-Peter Clausen01788c52012-02-20 19:37:05 +0100612#ifdef CONFIG_PM_SLEEP
613static int hmc5843_suspend(struct device *dev)
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530614{
Peter Meerwald16b91a42012-05-16 18:22:05 +0200615 hmc5843_configure(to_i2c_client(dev), HMC5843_MODE_SLEEP);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530616 return 0;
617}
618
Lars-Peter Clausen01788c52012-02-20 19:37:05 +0100619static int hmc5843_resume(struct device *dev)
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530620{
Peter Meerwald0462e2b2012-05-16 18:22:03 +0200621 struct i2c_client *client = to_i2c_client(dev);
622 struct iio_dev *indio_dev = i2c_get_clientdata(client);
623 struct hmc5843_data *data = iio_priv(indio_dev);
624
625 hmc5843_configure(client, data->operating_mode);
626
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530627 return 0;
628}
629
Lars-Peter Clausen01788c52012-02-20 19:37:05 +0100630static SIMPLE_DEV_PM_OPS(hmc5843_pm_ops, hmc5843_suspend, hmc5843_resume);
631#define HMC5843_PM_OPS (&hmc5843_pm_ops)
632#else
633#define HMC5843_PM_OPS NULL
634#endif
635
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530636static const struct i2c_device_id hmc5843_id[] = {
637 { "hmc5843", 0 },
638 { }
639};
Lars-Peter Clausen55e43902011-11-16 08:53:31 +0100640MODULE_DEVICE_TABLE(i2c, hmc5843_id);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530641
642static struct i2c_driver hmc5843_driver = {
643 .driver = {
644 .name = "hmc5843",
Lars-Peter Clausen01788c52012-02-20 19:37:05 +0100645 .pm = HMC5843_PM_OPS,
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530646 },
647 .id_table = hmc5843_id,
648 .probe = hmc5843_probe,
649 .remove = hmc5843_remove,
650 .detect = hmc5843_detect,
651 .address_list = normal_i2c,
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530652};
Lars-Peter Clausen6e5af182011-11-16 10:13:38 +0100653module_i2c_driver(hmc5843_driver);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530654
655MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com");
656MODULE_DESCRIPTION("HMC5843 driver");
657MODULE_LICENSE("GPL");