blob: 86c6bf9d5dd89c7207edb015534e0cf5c08b0289 [file] [log] [blame]
Shubhrajyoti Db4e17822010-07-17 18:32:52 +05301/* Copyright (C) 2010 Texas Instruments
2 Author: Shubhrajyoti Datta <shubhrajyoti@ti.com>
Jonathan Cameron0f8c9622012-09-02 21:34:59 +01003 Acknowledgement: Jonathan Cameron <jic23@kernel.org> for valuable inputs.
Shubhrajyoti Db4e17822010-07-17 18:32:52 +05304
Peter Meerwald357fcff2012-05-17 02:28:13 +02005 Support for HMC5883 and HMC5883L by Peter Meerwald <pmeerw@pmeerw.net>.
6
Shubhrajyoti Db4e17822010-07-17 18:32:52 +05307 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#include <linux/module.h>
23#include <linux/init.h>
24#include <linux/i2c.h>
25#include <linux/slab.h>
26#include <linux/types.h>
Jonathan Cameron06458e22012-04-25 15:54:58 +010027#include <linux/iio/iio.h>
28#include <linux/iio/sysfs.h>
Shubhrajyoti Db4e17822010-07-17 18:32:52 +053029
Shubhrajyoti Db4e17822010-07-17 18:32:52 +053030#define HMC5843_CONFIG_REG_A 0x00
31#define HMC5843_CONFIG_REG_B 0x01
32#define HMC5843_MODE_REG 0x02
33#define HMC5843_DATA_OUT_X_MSB_REG 0x03
34#define HMC5843_DATA_OUT_X_LSB_REG 0x04
35#define HMC5843_DATA_OUT_Y_MSB_REG 0x05
36#define HMC5843_DATA_OUT_Y_LSB_REG 0x06
37#define HMC5843_DATA_OUT_Z_MSB_REG 0x07
38#define HMC5843_DATA_OUT_Z_LSB_REG 0x08
Peter Meerwald16b91a42012-05-16 18:22:05 +020039/* Beware: Y and Z are exchanged on HMC5883 */
40#define HMC5883_DATA_OUT_Z_MSB_REG 0x05
41#define HMC5883_DATA_OUT_Z_LSB_REG 0x06
42#define HMC5883_DATA_OUT_Y_MSB_REG 0x07
43#define HMC5883_DATA_OUT_Y_LSB_REG 0x08
Shubhrajyoti Db4e17822010-07-17 18:32:52 +053044#define HMC5843_STATUS_REG 0x09
45#define HMC5843_ID_REG_A 0x0A
46#define HMC5843_ID_REG_B 0x0B
47#define HMC5843_ID_REG_C 0x0C
48
Peter Meerwald357fcff2012-05-17 02:28:13 +020049enum hmc5843_ids {
50 HMC5843_ID,
51 HMC5883_ID,
52 HMC5883L_ID,
53};
Shubhrajyoti Db4e17822010-07-17 18:32:52 +053054
55/*
Peter Meerwald16b91a42012-05-16 18:22:05 +020056 * Beware: identification of the HMC5883 is still "H43";
57 * I2C address is also unchanged
58 */
59#define HMC5843_ID_REG_LENGTH 0x03
60#define HMC5843_ID_STRING "H43"
61#define HMC5843_I2C_ADDRESS 0x1E
Shubhrajyoti Db4e17822010-07-17 18:32:52 +053062
Peter Meerwald16b91a42012-05-16 18:22:05 +020063/*
64 * Range gain settings in (+-)Ga
65 * Beware: HMC5843 and HMC5883 have different recommended sensor field
66 * ranges; default corresponds to +-1.0 Ga and +-1.3 Ga, respectively
67 */
68#define HMC5843_RANGE_GAIN_OFFSET 0x05
69#define HMC5843_RANGE_GAIN_DEFAULT 0x01
70#define HMC5843_RANGE_GAIN_MAX 0x07
Shubhrajyoti Db4e17822010-07-17 18:32:52 +053071
72/*
73 * Device status
74 */
Peter Meerwald16b91a42012-05-16 18:22:05 +020075#define HMC5843_DATA_READY 0x01
76#define HMC5843_DATA_OUTPUT_LOCK 0x02
77/* Does not exist on HMC5883, not used */
78#define HMC5843_VOLTAGE_REGULATOR_ENABLED 0x04
Shubhrajyoti Db4e17822010-07-17 18:32:52 +053079
80/*
81 * Mode register configuration
82 */
Peter Meerwald16b91a42012-05-16 18:22:05 +020083#define HMC5843_MODE_CONVERSION_CONTINUOUS 0x00
84#define HMC5843_MODE_CONVERSION_SINGLE 0x01
85#define HMC5843_MODE_IDLE 0x02
86#define HMC5843_MODE_SLEEP 0x03
87#define HMC5843_MODE_MASK 0x03
Shubhrajyoti Db4e17822010-07-17 18:32:52 +053088
89/*
Peter Meerwald16b91a42012-05-16 18:22:05 +020090 * HMC5843: Minimum data output rate
91 * HMC5883: Typical data output rate
Shubhrajyoti Db4e17822010-07-17 18:32:52 +053092 */
Peter Meerwald16b91a42012-05-16 18:22:05 +020093#define HMC5843_RATE_OFFSET 0x02
94#define HMC5843_RATE_BITMASK 0x1C
Peter Meerwald16b91a42012-05-16 18:22:05 +020095#define HMC5843_RATE_NOT_USED 0x07
96
97/*
98 * Device measurement configuration
99 */
100#define HMC5843_MEAS_CONF_NORMAL 0x00
101#define HMC5843_MEAS_CONF_POSITIVE_BIAS 0x01
102#define HMC5843_MEAS_CONF_NEGATIVE_BIAS 0x02
103#define HMC5843_MEAS_CONF_NOT_USED 0x03
104#define HMC5843_MEAS_CONF_MASK 0x03
105
106/*
107 * Scaling factors: 10000000/Gain
108 */
109static const int hmc5843_regval_to_nanoscale[] = {
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100110 6173, 7692, 10309, 12821, 18868, 21739, 25641, 35714
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530111};
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100112
Peter Meerwald357fcff2012-05-17 02:28:13 +0200113static const int hmc5883_regval_to_nanoscale[] = {
114 7812, 9766, 13021, 16287, 24096, 27701, 32573, 45662
115};
116
117static const int hmc5883l_regval_to_nanoscale[] = {
118 7299, 9174, 12195, 15152, 22727, 25641, 30303, 43478
119};
120
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200121/*
Peter Meerwald357fcff2012-05-17 02:28:13 +0200122 * From the HMC5843 datasheet:
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200123 * Value | Sensor input field range (Ga) | Gain (counts/milli-Gauss)
124 * 0 | (+-)0.7 | 1620
125 * 1 | (+-)1.0 | 1300
126 * 2 | (+-)1.5 | 970
127 * 3 | (+-)2.0 | 780
128 * 4 | (+-)3.2 | 530
129 * 5 | (+-)3.8 | 460
130 * 6 | (+-)4.5 | 390
131 * 7 | (+-)6.5 | 280
Peter Meerwald357fcff2012-05-17 02:28:13 +0200132 *
133 * From the HMC5883 datasheet:
134 * Value | Recommended sensor field range (Ga) | Gain (counts/Gauss)
135 * 0 | (+-)0.9 | 1280
136 * 1 | (+-)1.2 | 1024
137 * 2 | (+-)1.9 | 768
138 * 3 | (+-)2.5 | 614
139 * 4 | (+-)4.0 | 415
140 * 5 | (+-)4.6 | 361
141 * 6 | (+-)5.5 | 307
142 * 7 | (+-)7.9 | 219
143 *
144 * From the HMC5883L datasheet:
145 * Value | Recommended sensor field range (Ga) | Gain (LSB/Gauss)
146 * 0 | (+-)0.88 | 1370
147 * 1 | (+-)1.3 | 1090
148 * 2 | (+-)1.9 | 820
149 * 3 | (+-)2.5 | 660
150 * 4 | (+-)4.0 | 440
151 * 5 | (+-)4.7 | 390
152 * 6 | (+-)5.6 | 330
153 * 7 | (+-)8.1 | 230
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200154 */
Peter Meerwald4906a152012-05-17 02:28:11 +0200155static const int hmc5843_regval_to_input_field_mga[] = {
Peter Meerwald357fcff2012-05-17 02:28:13 +0200156 700, 1000, 1500, 2000, 3200, 3800, 4500, 6500
157};
158
159static const int hmc5883_regval_to_input_field_mga[] = {
160 900, 1200, 1900, 2500, 4000, 4600, 5500, 7900
161};
162
163static const int hmc5883l_regval_to_input_field_mga[] = {
164 880, 1300, 1900, 2500, 4000, 4700, 5600, 8100
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530165};
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200166
167/*
168 * From the datasheet:
Peter Meerwald357fcff2012-05-17 02:28:13 +0200169 * Value | HMC5843 | HMC5883/HMC5883L
170 * | Data output rate (Hz) | Data output rate (Hz)
171 * 0 | 0.5 | 0.75
172 * 1 | 1 | 1.5
173 * 2 | 2 | 3
174 * 3 | 5 | 7.5
175 * 4 | 10 (default) | 15
176 * 5 | 20 | 30
177 * 6 | 50 | 75
178 * 7 | Not used | Not used
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200179 */
Peter Meerwald4906a152012-05-17 02:28:11 +0200180static const char * const hmc5843_regval_to_sample_freq[] = {
Peter Meerwald357fcff2012-05-17 02:28:13 +0200181 "0.5", "1", "2", "5", "10", "20", "50",
182};
183
184static const char * const hmc5883_regval_to_sample_freq[] = {
185 "0.75", "1.5", "3", "7.5", "15", "30", "75",
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530186};
187
188/* Addresses to scan: 0x1E */
189static const unsigned short normal_i2c[] = { HMC5843_I2C_ADDRESS,
Peter Meerwald16b91a42012-05-16 18:22:05 +0200190 I2C_CLIENT_END };
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530191
Peter Meerwald357fcff2012-05-17 02:28:13 +0200192/* Describe chip variants */
193struct hmc5843_chip_info {
194 const struct iio_chan_spec *channels;
195 int num_channels;
196 const char * const *regval_to_sample_freq;
197 const int *regval_to_input_field_mga;
198 const int *regval_to_nanoscale;
199};
200
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530201/* Each client has this additional data */
202struct hmc5843_data {
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530203 struct mutex lock;
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200204 u8 rate;
205 u8 meas_conf;
206 u8 operating_mode;
207 u8 range;
Peter Meerwald357fcff2012-05-17 02:28:13 +0200208 const struct hmc5843_chip_info *variant;
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530209};
210
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200211/* The lower two bits contain the current conversion mode */
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530212static s32 hmc5843_configure(struct i2c_client *client,
213 u8 operating_mode)
214{
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530215 return i2c_smbus_write_byte_data(client,
216 HMC5843_MODE_REG,
Peter Meerwald16b91a42012-05-16 18:22:05 +0200217 operating_mode & HMC5843_MODE_MASK);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530218}
219
Justin P. Mattock4abf6f82012-02-29 22:00:38 -0800220/* Return the measurement value from the specified channel */
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100221static int hmc5843_read_measurement(struct iio_dev *indio_dev,
222 int address,
223 int *val)
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530224{
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530225 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100226 struct hmc5843_data *data = iio_priv(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530227 s32 result;
228
229 mutex_lock(&data->lock);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530230 result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
Peter Meerwald16b91a42012-05-16 18:22:05 +0200231 while (!(result & HMC5843_DATA_READY))
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530232 result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
233
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100234 result = i2c_smbus_read_word_data(client, address);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530235 mutex_unlock(&data->lock);
236 if (result < 0)
237 return -EINVAL;
238
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200239 *val = (s16)swab16((u16)result);
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100240 return IIO_VAL_INT;
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530241}
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100242
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530243/*
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200244 * From the datasheet:
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530245 * 0 - Continuous-Conversion Mode: In continuous-conversion mode, the
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200246 * device continuously performs conversions and places the result in
247 * the data register.
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530248 *
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200249 * 1 - Single-Conversion Mode : Device performs a single measurement,
250 * sets RDY high and returns to sleep mode.
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530251 *
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200252 * 2 - Idle Mode : Device is placed in idle mode.
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530253 *
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200254 * 3 - Sleep Mode : Device is placed in sleep mode.
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530255 *
256 */
257static ssize_t hmc5843_show_operating_mode(struct device *dev,
258 struct device_attribute *attr,
259 char *buf)
260{
Lars-Peter Clausen527cf712012-05-12 15:39:52 +0200261 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100262 struct hmc5843_data *data = iio_priv(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530263 return sprintf(buf, "%d\n", data->operating_mode);
264}
265
266static ssize_t hmc5843_set_operating_mode(struct device *dev,
267 struct device_attribute *attr,
268 const char *buf,
269 size_t count)
270{
Lars-Peter Clausen527cf712012-05-12 15:39:52 +0200271 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530272 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100273 struct hmc5843_data *data = iio_priv(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530274 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
275 unsigned long operating_mode = 0;
276 s32 status;
277 int error;
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200278
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530279 mutex_lock(&data->lock);
Peter Meerwaldd32ec552012-05-16 18:22:04 +0200280 error = kstrtoul(buf, 10, &operating_mode);
Julia Lawalld1ae4da2010-08-04 21:54:26 +0200281 if (error) {
282 count = error;
283 goto exit;
284 }
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200285 dev_dbg(dev, "set conversion mode to %lu\n", operating_mode);
Peter Meerwald16b91a42012-05-16 18:22:05 +0200286 if (operating_mode > HMC5843_MODE_SLEEP) {
Julia Lawalld1ae4da2010-08-04 21:54:26 +0200287 count = -EINVAL;
288 goto exit;
289 }
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530290
291 status = i2c_smbus_write_byte_data(client, this_attr->address,
292 operating_mode);
293 if (status) {
294 count = -EINVAL;
295 goto exit;
296 }
297 data->operating_mode = operating_mode;
298
299exit:
300 mutex_unlock(&data->lock);
301 return count;
302}
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200303
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530304static IIO_DEVICE_ATTR(operating_mode,
305 S_IWUSR | S_IRUGO,
306 hmc5843_show_operating_mode,
307 hmc5843_set_operating_mode,
308 HMC5843_MODE_REG);
309
310/*
311 * API for setting the measurement configuration to
312 * Normal, Positive bias and Negative bias
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530313 *
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200314 * From the datasheet:
315 * 0 - Normal measurement configuration (default): In normal measurement
316 * configuration the device follows normal measurement flow. Pins BP
317 * and BN are left floating and high impedance.
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530318 *
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200319 * 1 - Positive bias configuration: In positive bias configuration, a
320 * positive current is forced across the resistive load on pins BP
321 * and BN.
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530322 *
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200323 * 2 - Negative bias configuration. In negative bias configuration, a
324 * negative current is forced across the resistive load on pins BP
325 * and BN.
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530326 *
327 */
328static s32 hmc5843_set_meas_conf(struct i2c_client *client,
329 u8 meas_conf)
330{
Peter Meerwald0462e2b2012-05-16 18:22:03 +0200331 struct iio_dev *indio_dev = i2c_get_clientdata(client);
332 struct hmc5843_data *data = iio_priv(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530333 u8 reg_val;
Peter Meerwald16b91a42012-05-16 18:22:05 +0200334 reg_val = (meas_conf & HMC5843_MEAS_CONF_MASK) |
335 (data->rate << HMC5843_RATE_OFFSET);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530336 return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
337}
338
339static ssize_t hmc5843_show_measurement_configuration(struct device *dev,
340 struct device_attribute *attr,
341 char *buf)
342{
Lars-Peter Clausen527cf712012-05-12 15:39:52 +0200343 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100344 struct hmc5843_data *data = iio_priv(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530345 return sprintf(buf, "%d\n", data->meas_conf);
346}
347
348static ssize_t hmc5843_set_measurement_configuration(struct device *dev,
349 struct device_attribute *attr,
350 const char *buf,
351 size_t count)
352{
Lars-Peter Clausen527cf712012-05-12 15:39:52 +0200353 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530354 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
Peter Meerwald0462e2b2012-05-16 18:22:03 +0200355 struct hmc5843_data *data = iio_priv(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530356 unsigned long meas_conf = 0;
Peter Meerwalde278df12012-05-17 02:28:09 +0200357 int error;
358
359 error = kstrtoul(buf, 10, &meas_conf);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530360 if (error)
361 return error;
Peter Meerwalde278df12012-05-17 02:28:09 +0200362 if (meas_conf >= HMC5843_MEAS_CONF_NOT_USED)
363 return -EINVAL;
364
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530365 mutex_lock(&data->lock);
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200366 dev_dbg(dev, "set measurement configuration to %lu\n", meas_conf);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530367 if (hmc5843_set_meas_conf(client, meas_conf)) {
368 count = -EINVAL;
369 goto exit;
370 }
371 data->meas_conf = meas_conf;
372
373exit:
374 mutex_unlock(&data->lock);
375 return count;
376}
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200377
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530378static IIO_DEVICE_ATTR(meas_conf,
379 S_IWUSR | S_IRUGO,
380 hmc5843_show_measurement_configuration,
381 hmc5843_set_measurement_configuration,
382 0);
383
Peter Meerwald357fcff2012-05-17 02:28:13 +0200384static ssize_t hmc5843_show_sampling_frequencies_available(struct device *dev,
385 struct device_attribute *attr,
386 char *buf)
387{
388 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
389 struct hmc5843_data *data = iio_priv(indio_dev);
390 ssize_t total_n = 0;
391 int i;
392
393 for (i = 0; i < HMC5843_RATE_NOT_USED; i++) {
394 ssize_t n = sprintf(buf, "%s ", data->variant->regval_to_sample_freq[i]);
395 buf += n;
396 total_n += n;
397 }
398 /* replace trailing space by newline */
399 buf[-1] = '\n';
400
401 return total_n;
402}
403
404static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hmc5843_show_sampling_frequencies_available);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530405
406static s32 hmc5843_set_rate(struct i2c_client *client,
407 u8 rate)
408{
Peter Meerwald0462e2b2012-05-16 18:22:03 +0200409 struct iio_dev *indio_dev = i2c_get_clientdata(client);
410 struct hmc5843_data *data = iio_priv(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530411 u8 reg_val;
412
Peter Meerwald16b91a42012-05-16 18:22:05 +0200413 if (rate >= HMC5843_RATE_NOT_USED) {
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530414 dev_err(&client->dev,
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200415 "data output rate is not supported\n");
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530416 return -EINVAL;
417 }
Peter Meerwald4fd4d7d2012-05-17 02:28:12 +0200418
419 reg_val = data->meas_conf | (rate << HMC5843_RATE_OFFSET);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530420 return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
421}
422
Peter Meerwald13f6eb62012-05-17 02:28:08 +0200423static int hmc5843_check_sampling_frequency(struct hmc5843_data *data,
424 const char *buf)
425{
Peter Meerwald357fcff2012-05-17 02:28:13 +0200426 const char * const *samp_freq = data->variant->regval_to_sample_freq;
Peter Meerwald13f6eb62012-05-17 02:28:08 +0200427 int i;
428
429 for (i = 0; i < HMC5843_RATE_NOT_USED; i++) {
Peter Meerwald357fcff2012-05-17 02:28:13 +0200430 if (sysfs_streq(buf, samp_freq[i]))
Peter Meerwald13f6eb62012-05-17 02:28:08 +0200431 return i;
432 }
433
434 return -EINVAL;
435}
436
Peter Meerwald4906a152012-05-17 02:28:11 +0200437static ssize_t hmc5843_set_sampling_frequency(struct device *dev,
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530438 struct device_attribute *attr,
439 const char *buf, size_t count)
440{
441
Lars-Peter Clausen527cf712012-05-12 15:39:52 +0200442 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530443 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100444 struct hmc5843_data *data = iio_priv(indio_dev);
Peter Meerwald13f6eb62012-05-17 02:28:08 +0200445 int rate;
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530446
Peter Meerwald13f6eb62012-05-17 02:28:08 +0200447 rate = hmc5843_check_sampling_frequency(data, buf);
448 if (rate < 0) {
449 dev_err(&client->dev,
450 "sampling frequency is not supported\n");
451 return rate;
452 }
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530453
454 mutex_lock(&data->lock);
Peter Meerwald13f6eb62012-05-17 02:28:08 +0200455 dev_dbg(dev, "set rate to %d\n", rate);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530456 if (hmc5843_set_rate(client, rate)) {
457 count = -EINVAL;
458 goto exit;
459 }
460 data->rate = rate;
461
462exit:
463 mutex_unlock(&data->lock);
464 return count;
465}
466
Peter Meerwald4906a152012-05-17 02:28:11 +0200467static ssize_t hmc5843_show_sampling_frequency(struct device *dev,
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530468 struct device_attribute *attr, char *buf)
469{
Lars-Peter Clausen527cf712012-05-12 15:39:52 +0200470 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530471 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
472 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
Peter Meerwald357fcff2012-05-17 02:28:13 +0200473 struct hmc5843_data *data = iio_priv(indio_dev);
Dan Carpenter213fd222010-08-10 07:37:33 +0200474 s32 rate;
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530475
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200476 rate = i2c_smbus_read_byte_data(client, this_attr->address);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530477 if (rate < 0)
Dan Carpenter213fd222010-08-10 07:37:33 +0200478 return rate;
Peter Meerwald16b91a42012-05-16 18:22:05 +0200479 rate = (rate & HMC5843_RATE_BITMASK) >> HMC5843_RATE_OFFSET;
Peter Meerwald357fcff2012-05-17 02:28:13 +0200480 return sprintf(buf, "%s\n", data->variant->regval_to_sample_freq[rate]);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530481}
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200482
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530483static IIO_DEVICE_ATTR(sampling_frequency,
484 S_IWUSR | S_IRUGO,
Peter Meerwald4906a152012-05-17 02:28:11 +0200485 hmc5843_show_sampling_frequency,
486 hmc5843_set_sampling_frequency,
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530487 HMC5843_CONFIG_REG_A);
488
Peter Meerwald4906a152012-05-17 02:28:11 +0200489static ssize_t hmc5843_show_range_gain(struct device *dev,
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530490 struct device_attribute *attr,
491 char *buf)
492{
493 u8 range;
Lars-Peter Clausen527cf712012-05-12 15:39:52 +0200494 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100495 struct hmc5843_data *data = iio_priv(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530496
497 range = data->range;
Peter Meerwald357fcff2012-05-17 02:28:13 +0200498 return sprintf(buf, "%d\n", data->variant->regval_to_input_field_mga[range]);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530499}
500
Peter Meerwald4906a152012-05-17 02:28:11 +0200501static ssize_t hmc5843_set_range_gain(struct device *dev,
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530502 struct device_attribute *attr,
503 const char *buf,
504 size_t count)
505{
Lars-Peter Clausen527cf712012-05-12 15:39:52 +0200506 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530507 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
508 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100509 struct hmc5843_data *data = iio_priv(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530510 unsigned long range = 0;
511 int error;
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200512
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530513 mutex_lock(&data->lock);
Peter Meerwaldd32ec552012-05-16 18:22:04 +0200514 error = kstrtoul(buf, 10, &range);
Julia Lawalld1ae4da2010-08-04 21:54:26 +0200515 if (error) {
516 count = error;
517 goto exit;
518 }
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530519 dev_dbg(dev, "set range to %lu\n", range);
520
Peter Meerwald16b91a42012-05-16 18:22:05 +0200521 if (range > HMC5843_RANGE_GAIN_MAX) {
Julia Lawalld1ae4da2010-08-04 21:54:26 +0200522 count = -EINVAL;
523 goto exit;
524 }
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530525
526 data->range = range;
Peter Meerwald16b91a42012-05-16 18:22:05 +0200527 range = range << HMC5843_RANGE_GAIN_OFFSET;
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530528 if (i2c_smbus_write_byte_data(client, this_attr->address, range))
529 count = -EINVAL;
530
Julia Lawalld1ae4da2010-08-04 21:54:26 +0200531exit:
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530532 mutex_unlock(&data->lock);
533 return count;
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530534}
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200535
Jonathan Cameron322c9562011-09-14 13:01:23 +0100536static IIO_DEVICE_ATTR(in_magn_range,
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530537 S_IWUSR | S_IRUGO,
Peter Meerwald4906a152012-05-17 02:28:11 +0200538 hmc5843_show_range_gain,
539 hmc5843_set_range_gain,
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530540 HMC5843_CONFIG_REG_B);
541
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100542static int hmc5843_read_raw(struct iio_dev *indio_dev,
543 struct iio_chan_spec const *chan,
544 int *val, int *val2,
545 long mask)
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530546{
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100547 struct hmc5843_data *data = iio_priv(indio_dev);
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100548
549 switch (mask) {
Jonathan Cameron4d9948b2012-04-15 17:41:23 +0100550 case IIO_CHAN_INFO_RAW:
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100551 return hmc5843_read_measurement(indio_dev,
552 chan->address,
553 val);
Jonathan Cameronc8a9f802011-10-26 17:41:36 +0100554 case IIO_CHAN_INFO_SCALE:
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100555 *val = 0;
Peter Meerwald357fcff2012-05-17 02:28:13 +0200556 *val2 = data->variant->regval_to_nanoscale[data->range];
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100557 return IIO_VAL_INT_PLUS_NANO;
Peter Senna Tschudin73327b42012-09-28 10:57:00 +0100558 }
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100559 return -EINVAL;
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530560}
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100561
562#define HMC5843_CHANNEL(axis, add) \
563 { \
564 .type = IIO_MAGN, \
565 .modified = 1, \
566 .channel2 = IIO_MOD_##axis, \
Jonathan Cameronb3700972013-02-27 19:40:58 +0000567 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
568 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100569 .address = add \
570 }
571
572static const struct iio_chan_spec hmc5843_channels[] = {
573 HMC5843_CHANNEL(X, HMC5843_DATA_OUT_X_MSB_REG),
574 HMC5843_CHANNEL(Y, HMC5843_DATA_OUT_Y_MSB_REG),
575 HMC5843_CHANNEL(Z, HMC5843_DATA_OUT_Z_MSB_REG),
576};
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530577
Peter Meerwald357fcff2012-05-17 02:28:13 +0200578static const struct iio_chan_spec hmc5883_channels[] = {
579 HMC5843_CHANNEL(X, HMC5843_DATA_OUT_X_MSB_REG),
580 HMC5843_CHANNEL(Y, HMC5883_DATA_OUT_Y_MSB_REG),
581 HMC5843_CHANNEL(Z, HMC5883_DATA_OUT_Z_MSB_REG),
582};
583
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530584static struct attribute *hmc5843_attributes[] = {
585 &iio_dev_attr_meas_conf.dev_attr.attr,
586 &iio_dev_attr_operating_mode.dev_attr.attr,
587 &iio_dev_attr_sampling_frequency.dev_attr.attr,
Jonathan Cameron322c9562011-09-14 13:01:23 +0100588 &iio_dev_attr_in_magn_range.dev_attr.attr,
Peter Meerwald357fcff2012-05-17 02:28:13 +0200589 &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530590 NULL
591};
592
593static const struct attribute_group hmc5843_group = {
594 .attrs = hmc5843_attributes,
595};
596
Peter Meerwald357fcff2012-05-17 02:28:13 +0200597static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = {
598 [HMC5843_ID] = {
599 .channels = hmc5843_channels,
600 .num_channels = ARRAY_SIZE(hmc5843_channels),
601 .regval_to_sample_freq = hmc5843_regval_to_sample_freq,
602 .regval_to_input_field_mga =
603 hmc5843_regval_to_input_field_mga,
604 .regval_to_nanoscale = hmc5843_regval_to_nanoscale,
605 },
606 [HMC5883_ID] = {
607 .channels = hmc5883_channels,
608 .num_channels = ARRAY_SIZE(hmc5883_channels),
609 .regval_to_sample_freq = hmc5883_regval_to_sample_freq,
610 .regval_to_input_field_mga =
611 hmc5883_regval_to_input_field_mga,
612 .regval_to_nanoscale = hmc5883_regval_to_nanoscale,
613 },
614 [HMC5883L_ID] = {
615 .channels = hmc5883_channels,
616 .num_channels = ARRAY_SIZE(hmc5883_channels),
617 .regval_to_sample_freq = hmc5883_regval_to_sample_freq,
618 .regval_to_input_field_mga =
619 hmc5883l_regval_to_input_field_mga,
620 .regval_to_nanoscale = hmc5883l_regval_to_nanoscale,
621 },
622};
623
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530624static int hmc5843_detect(struct i2c_client *client,
625 struct i2c_board_info *info)
626{
627 unsigned char id_str[HMC5843_ID_REG_LENGTH];
628
629 if (client->addr != HMC5843_I2C_ADDRESS)
630 return -ENODEV;
631
632 if (i2c_smbus_read_i2c_block_data(client, HMC5843_ID_REG_A,
633 HMC5843_ID_REG_LENGTH, id_str)
634 != HMC5843_ID_REG_LENGTH)
635 return -ENODEV;
636
637 if (0 != strncmp(id_str, HMC5843_ID_STRING, HMC5843_ID_REG_LENGTH))
638 return -ENODEV;
639
640 return 0;
641}
642
Peter Meerwald357fcff2012-05-17 02:28:13 +0200643/* Called when we have found a new HMC58X3 */
644static void hmc5843_init_client(struct i2c_client *client,
645 const struct i2c_device_id *id)
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530646{
Marek Belisko62d2feb2012-04-12 21:48:03 +0200647 struct iio_dev *indio_dev = i2c_get_clientdata(client);
648 struct hmc5843_data *data = iio_priv(indio_dev);
649
Peter Meerwald357fcff2012-05-17 02:28:13 +0200650 data->variant = &hmc5843_chip_info_tbl[id->driver_data];
651 indio_dev->channels = data->variant->channels;
652 indio_dev->num_channels = data->variant->num_channels;
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530653 hmc5843_set_meas_conf(client, data->meas_conf);
654 hmc5843_set_rate(client, data->rate);
655 hmc5843_configure(client, data->operating_mode);
656 i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_B, data->range);
657 mutex_init(&data->lock);
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200658
Peter Meerwald357fcff2012-05-17 02:28:13 +0200659 pr_info("%s initialized\n", id->name);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530660}
661
Jonathan Cameron6fe81352011-05-18 14:42:37 +0100662static const struct iio_info hmc5843_info = {
663 .attrs = &hmc5843_group,
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100664 .read_raw = &hmc5843_read_raw,
Jonathan Cameron6fe81352011-05-18 14:42:37 +0100665 .driver_module = THIS_MODULE,
666};
667
Bill Pemberton4ae1c612012-11-19 13:21:57 -0500668static int hmc5843_probe(struct i2c_client *client,
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530669 const struct i2c_device_id *id)
670{
671 struct hmc5843_data *data;
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100672 struct iio_dev *indio_dev;
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530673 int err = 0;
674
Lars-Peter Clausen7cbb7532012-04-26 13:35:01 +0200675 indio_dev = iio_device_alloc(sizeof(*data));
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100676 if (indio_dev == NULL) {
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530677 err = -ENOMEM;
678 goto exit;
679 }
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530680
Peter Meerwald16b91a42012-05-16 18:22:05 +0200681 /* default settings at probe */
682 data = iio_priv(indio_dev);
683 data->meas_conf = HMC5843_MEAS_CONF_NORMAL;
684 data->range = HMC5843_RANGE_GAIN_DEFAULT;
685 data->operating_mode = HMC5843_MODE_CONVERSION_CONTINUOUS;
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530686
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100687 i2c_set_clientdata(client, indio_dev);
Peter Meerwald357fcff2012-05-17 02:28:13 +0200688 hmc5843_init_client(client, id);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530689
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100690 indio_dev->info = &hmc5843_info;
Jonathan Cameron494c6b12011-08-12 17:47:58 +0100691 indio_dev->name = id->name;
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100692 indio_dev->dev.parent = &client->dev;
693 indio_dev->modes = INDIO_DIRECT_MODE;
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200694
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100695 err = iio_device_register(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530696 if (err)
697 goto exit_free2;
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200698
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530699 return 0;
Peter Meerwaldc7c34af2012-05-17 02:28:10 +0200700
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530701exit_free2:
Lars-Peter Clausen7cbb7532012-04-26 13:35:01 +0200702 iio_device_free(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530703exit:
704 return err;
705}
706
Bill Pemberton447d4f22012-11-19 13:26:37 -0500707static int hmc5843_remove(struct i2c_client *client)
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530708{
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100709 struct iio_dev *indio_dev = i2c_get_clientdata(client);
Jonathan Camerond2fffd62011-10-14 14:46:58 +0100710
711 iio_device_unregister(indio_dev);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530712 /* sleep mode to save power */
Peter Meerwald16b91a42012-05-16 18:22:05 +0200713 hmc5843_configure(client, HMC5843_MODE_SLEEP);
Lars-Peter Clausen7cbb7532012-04-26 13:35:01 +0200714 iio_device_free(indio_dev);
Jonathan Cameron88fa4de2011-06-27 13:07:56 +0100715
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530716 return 0;
717}
718
Lars-Peter Clausen01788c52012-02-20 19:37:05 +0100719#ifdef CONFIG_PM_SLEEP
720static int hmc5843_suspend(struct device *dev)
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530721{
Peter Meerwald16b91a42012-05-16 18:22:05 +0200722 hmc5843_configure(to_i2c_client(dev), HMC5843_MODE_SLEEP);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530723 return 0;
724}
725
Lars-Peter Clausen01788c52012-02-20 19:37:05 +0100726static int hmc5843_resume(struct device *dev)
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530727{
Peter Meerwald0462e2b2012-05-16 18:22:03 +0200728 struct i2c_client *client = to_i2c_client(dev);
729 struct iio_dev *indio_dev = i2c_get_clientdata(client);
730 struct hmc5843_data *data = iio_priv(indio_dev);
731
732 hmc5843_configure(client, data->operating_mode);
733
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530734 return 0;
735}
736
Lars-Peter Clausen01788c52012-02-20 19:37:05 +0100737static SIMPLE_DEV_PM_OPS(hmc5843_pm_ops, hmc5843_suspend, hmc5843_resume);
738#define HMC5843_PM_OPS (&hmc5843_pm_ops)
739#else
740#define HMC5843_PM_OPS NULL
741#endif
742
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530743static const struct i2c_device_id hmc5843_id[] = {
Peter Meerwald357fcff2012-05-17 02:28:13 +0200744 { "hmc5843", HMC5843_ID },
745 { "hmc5883", HMC5883_ID },
746 { "hmc5883l", HMC5883L_ID },
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530747 { }
748};
Lars-Peter Clausen55e43902011-11-16 08:53:31 +0100749MODULE_DEVICE_TABLE(i2c, hmc5843_id);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530750
751static struct i2c_driver hmc5843_driver = {
752 .driver = {
753 .name = "hmc5843",
Lars-Peter Clausen01788c52012-02-20 19:37:05 +0100754 .pm = HMC5843_PM_OPS,
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530755 },
756 .id_table = hmc5843_id,
757 .probe = hmc5843_probe,
Bill Pembertone543acf2012-11-19 13:21:38 -0500758 .remove = hmc5843_remove,
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530759 .detect = hmc5843_detect,
760 .address_list = normal_i2c,
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530761};
Lars-Peter Clausen6e5af182011-11-16 10:13:38 +0100762module_i2c_driver(hmc5843_driver);
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530763
764MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com");
Peter Meerwald357fcff2012-05-17 02:28:13 +0200765MODULE_DESCRIPTION("HMC5843/5883/5883L driver");
Shubhrajyoti Db4e17822010-07-17 18:32:52 +0530766MODULE_LICENSE("GPL");