1 /* Copyright (C) 2010 Texas Instruments
2 Author: Shubhrajyoti Datta <shubhrajyoti@ti.com>
3 Acknowledgement: Jonathan Cameron <jic23@cam.ac.uk> for valuable inputs.
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.
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.
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.
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>
29 #define HMC5843_I2C_ADDRESS 0x1E
31 #define HMC5843_CONFIG_REG_A 0x00
32 #define HMC5843_CONFIG_REG_B 0x01
33 #define HMC5843_MODE_REG 0x02
34 #define HMC5843_DATA_OUT_X_MSB_REG 0x03
35 #define HMC5843_DATA_OUT_X_LSB_REG 0x04
36 #define HMC5843_DATA_OUT_Y_MSB_REG 0x05
37 #define HMC5843_DATA_OUT_Y_LSB_REG 0x06
38 #define HMC5843_DATA_OUT_Z_MSB_REG 0x07
39 #define HMC5843_DATA_OUT_Z_LSB_REG 0x08
40 #define HMC5843_STATUS_REG 0x09
41 #define HMC5843_ID_REG_A 0x0A
42 #define HMC5843_ID_REG_B 0x0B
43 #define HMC5843_ID_REG_C 0x0C
45 #define HMC5843_ID_REG_LENGTH 0x03
46 #define HMC5843_ID_STRING "H43"
49 * Range settings in (+-)Ga
51 #define RANGE_GAIN_OFFSET 0x05
53 #define RANGE_0_7 0x00
54 #define RANGE_1_0 0x01 /* default */
55 #define RANGE_1_5 0x02
56 #define RANGE_2_0 0x03
57 #define RANGE_3_2 0x04
58 #define RANGE_3_8 0x05
59 #define RANGE_4_5 0x06
60 #define RANGE_6_5 0x07 /* Not recommended */
65 #define DATA_READY 0x01
66 #define DATA_OUTPUT_LOCK 0x02
67 #define VOLTAGE_REGULATOR_ENABLED 0x04
70 * Mode register configuration
72 #define MODE_CONVERSION_CONTINUOUS 0x00
73 #define MODE_CONVERSION_SINGLE 0x01
74 #define MODE_IDLE 0x02
75 #define MODE_SLEEP 0x03
77 /* Minimum Data Output Rate in 1/10 Hz */
78 #define RATE_OFFSET 0x02
79 #define RATE_BITMASK 0x1C
87 #define RATE_NOT_USED 0x07
90 * Device Configutration
92 #define CONF_NORMAL 0x00
93 #define CONF_POSITIVE_BIAS 0x01
94 #define CONF_NEGATIVE_BIAS 0x02
95 #define CONF_NOT_USED 0x03
96 #define MEAS_CONF_MASK 0x03
98 static const int regval_to_counts_per_mg
[] = {
108 static const int regval_to_input_field_mg
[] = {
118 static const char *regval_to_samp_freq
[] = {
128 /* Addresses to scan: 0x1E */
129 static const unsigned short normal_i2c
[] = { HMC5843_I2C_ADDRESS
,
132 /* Each client has this additional data */
133 struct hmc5843_data
{
134 struct iio_dev
*indio_dev
;
142 static void hmc5843_init_client(struct i2c_client
*client
);
144 static s32
hmc5843_configure(struct i2c_client
*client
,
147 /* The lower two bits contain the current conversion mode */
148 return i2c_smbus_write_byte_data(client
,
150 (operating_mode
& 0x03));
153 /* Return the measurement value from the specified channel */
154 static ssize_t
hmc5843_read_measurement(struct device
*dev
,
155 struct device_attribute
*attr
,
158 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
159 struct i2c_client
*client
= to_i2c_client(indio_dev
->dev
.parent
);
161 struct iio_dev_attr
*this_attr
= to_iio_dev_attr(attr
);
162 struct hmc5843_data
*data
= indio_dev
->dev_data
;
165 mutex_lock(&data
->lock
);
167 result
= i2c_smbus_read_byte_data(client
, HMC5843_STATUS_REG
);
168 while (!(result
& DATA_READY
))
169 result
= i2c_smbus_read_byte_data(client
, HMC5843_STATUS_REG
);
171 result
= i2c_smbus_read_word_data(client
, this_attr
->address
);
172 mutex_unlock(&data
->lock
);
176 coordinate_val
= (s16
)swab16((u16
)result
);
177 return sprintf(buf
, "%d\n", coordinate_val
);
179 static IIO_DEV_ATTR_MAGN_X(hmc5843_read_measurement
,
180 HMC5843_DATA_OUT_X_MSB_REG
);
181 static IIO_DEV_ATTR_MAGN_Y(hmc5843_read_measurement
,
182 HMC5843_DATA_OUT_Y_MSB_REG
);
183 static IIO_DEV_ATTR_MAGN_Z(hmc5843_read_measurement
,
184 HMC5843_DATA_OUT_Z_MSB_REG
);
188 * 0 - Continuous-Conversion Mode: In continuous-conversion mode, the
189 * device continuously performs conversions an places the result in the
192 * 1 - Single-Conversion Mode : device performs a single measurement,
193 * sets RDY high and returned to sleep mode
195 * 2 - Idle Mode : Device is placed in idle mode.
197 * 3 - Sleep Mode. Device is placed in sleep mode.
200 static ssize_t
hmc5843_show_operating_mode(struct device
*dev
,
201 struct device_attribute
*attr
,
204 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
205 struct hmc5843_data
*data
= indio_dev
->dev_data
;
206 return sprintf(buf
, "%d\n", data
->operating_mode
);
209 static ssize_t
hmc5843_set_operating_mode(struct device
*dev
,
210 struct device_attribute
*attr
,
214 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
215 struct i2c_client
*client
= to_i2c_client(indio_dev
->dev
.parent
);
216 struct hmc5843_data
*data
= indio_dev
->dev_data
;
217 struct iio_dev_attr
*this_attr
= to_iio_dev_attr(attr
);
218 unsigned long operating_mode
= 0;
221 mutex_lock(&data
->lock
);
222 error
= strict_strtoul(buf
, 10, &operating_mode
);
225 dev_dbg(dev
, "set Conversion mode to %lu\n", operating_mode
);
226 if (operating_mode
> MODE_SLEEP
)
229 status
= i2c_smbus_write_byte_data(client
, this_attr
->address
,
235 data
->operating_mode
= operating_mode
;
238 mutex_unlock(&data
->lock
);
241 static IIO_DEVICE_ATTR(operating_mode
,
243 hmc5843_show_operating_mode
,
244 hmc5843_set_operating_mode
,
248 * API for setting the measurement configuration to
249 * Normal, Positive bias and Negative bias
252 * Normal measurement configuration (default): In normal measurement
253 * configuration the device follows normal measurement flow. Pins BP and BN
254 * are left floating and high impedance.
256 * Positive bias configuration: In positive bias configuration, a positive
257 * current is forced across the resistive load on pins BP and BN.
259 * Negative bias configuration. In negative bias configuration, a negative
260 * current is forced across the resistive load on pins BP and BN.
263 static s32
hmc5843_set_meas_conf(struct i2c_client
*client
,
266 struct hmc5843_data
*data
= i2c_get_clientdata(client
);
268 reg_val
= (meas_conf
& MEAS_CONF_MASK
) | (data
->rate
<< RATE_OFFSET
);
269 return i2c_smbus_write_byte_data(client
, HMC5843_CONFIG_REG_A
, reg_val
);
272 static ssize_t
hmc5843_show_measurement_configuration(struct device
*dev
,
273 struct device_attribute
*attr
,
276 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
277 struct hmc5843_data
*data
= indio_dev
->dev_data
;
278 return sprintf(buf
, "%d\n", data
->meas_conf
);
281 static ssize_t
hmc5843_set_measurement_configuration(struct device
*dev
,
282 struct device_attribute
*attr
,
286 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
287 struct i2c_client
*client
= to_i2c_client(indio_dev
->dev
.parent
);
288 struct hmc5843_data
*data
= i2c_get_clientdata(client
);
289 unsigned long meas_conf
= 0;
290 int error
= strict_strtoul(buf
, 10, &meas_conf
);
293 mutex_lock(&data
->lock
);
295 dev_dbg(dev
, "set mode to %lu\n", meas_conf
);
296 if (hmc5843_set_meas_conf(client
, meas_conf
)) {
300 data
->meas_conf
= meas_conf
;
303 mutex_unlock(&data
->lock
);
306 static IIO_DEVICE_ATTR(meas_conf
,
308 hmc5843_show_measurement_configuration
,
309 hmc5843_set_measurement_configuration
,
314 * The table shows the minimum data output
315 * Value | Minimum data output rate(Hz)
325 static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("0.5 1 2 5 10 20 50");
327 static s32
hmc5843_set_rate(struct i2c_client
*client
,
330 struct hmc5843_data
*data
= i2c_get_clientdata(client
);
333 reg_val
= (data
->meas_conf
) | (rate
<< RATE_OFFSET
);
334 if (rate
>= RATE_NOT_USED
) {
335 dev_err(&client
->dev
,
336 "This data output rate is not supported \n");
339 return i2c_smbus_write_byte_data(client
, HMC5843_CONFIG_REG_A
, reg_val
);
342 static ssize_t
set_sampling_frequency(struct device
*dev
,
343 struct device_attribute
*attr
,
344 const char *buf
, size_t count
)
347 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
348 struct i2c_client
*client
= to_i2c_client(indio_dev
->dev
.parent
);
349 struct hmc5843_data
*data
= indio_dev
->dev_data
;
350 unsigned long rate
= 0;
352 if (strncmp(buf
, "0.5" , 3) == 0)
354 else if (strncmp(buf
, "1" , 1) == 0)
356 else if (strncmp(buf
, "2", 1) == 0)
358 else if (strncmp(buf
, "5", 1) == 0)
360 else if (strncmp(buf
, "10", 2) == 0)
362 else if (strncmp(buf
, "20" , 2) == 0)
364 else if (strncmp(buf
, "50" , 2) == 0)
369 mutex_lock(&data
->lock
);
370 dev_dbg(dev
, "set rate to %lu\n", rate
);
371 if (hmc5843_set_rate(client
, rate
)) {
378 mutex_unlock(&data
->lock
);
382 static ssize_t
show_sampling_frequency(struct device
*dev
,
383 struct device_attribute
*attr
, char *buf
)
385 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
386 struct i2c_client
*client
= to_i2c_client(indio_dev
->dev
.parent
);
387 struct iio_dev_attr
*this_attr
= to_iio_dev_attr(attr
);
390 rate
= i2c_smbus_read_byte_data(client
, this_attr
->address
);
393 rate
= (rate
& RATE_BITMASK
) >> RATE_OFFSET
;
394 return sprintf(buf
, "%s\n", regval_to_samp_freq
[rate
]);
396 static IIO_DEVICE_ATTR(sampling_frequency
,
398 show_sampling_frequency
,
399 set_sampling_frequency
,
400 HMC5843_CONFIG_REG_A
);
404 * Nominal gain settings
405 * Value | Sensor Input Field Range(Ga) | Gain(counts/ milli-gauss)
415 static ssize_t
show_range(struct device
*dev
,
416 struct device_attribute
*attr
,
420 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
421 struct hmc5843_data
*data
= indio_dev
->dev_data
;
424 return sprintf(buf
, "%d\n", regval_to_input_field_mg
[range
]);
427 static ssize_t
set_range(struct device
*dev
,
428 struct device_attribute
*attr
,
432 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
433 struct i2c_client
*client
= to_i2c_client(indio_dev
->dev
.parent
);
434 struct iio_dev_attr
*this_attr
= to_iio_dev_attr(attr
);
435 struct hmc5843_data
*data
= indio_dev
->dev_data
;
436 unsigned long range
= 0;
438 mutex_lock(&data
->lock
);
439 error
= strict_strtoul(buf
, 10, &range
);
442 dev_dbg(dev
, "set range to %lu\n", range
);
444 if (range
> RANGE_6_5
)
448 range
= range
<< RANGE_GAIN_OFFSET
;
449 if (i2c_smbus_write_byte_data(client
, this_attr
->address
, range
))
452 mutex_unlock(&data
->lock
);
456 static IIO_DEVICE_ATTR(magn_range
,
460 HMC5843_CONFIG_REG_B
);
462 static ssize_t
show_gain(struct device
*dev
,
463 struct device_attribute
*attr
,
466 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
467 struct hmc5843_data
*data
= indio_dev
->dev_data
;
468 return sprintf(buf
, "%d\n", regval_to_counts_per_mg
[data
->range
]);
470 static IIO_DEVICE_ATTR(magn_gain
,
475 static struct attribute
*hmc5843_attributes
[] = {
476 &iio_dev_attr_meas_conf
.dev_attr
.attr
,
477 &iio_dev_attr_operating_mode
.dev_attr
.attr
,
478 &iio_dev_attr_sampling_frequency
.dev_attr
.attr
,
479 &iio_dev_attr_magn_range
.dev_attr
.attr
,
480 &iio_dev_attr_magn_gain
.dev_attr
.attr
,
481 &iio_dev_attr_magn_x_raw
.dev_attr
.attr
,
482 &iio_dev_attr_magn_y_raw
.dev_attr
.attr
,
483 &iio_dev_attr_magn_z_raw
.dev_attr
.attr
,
484 &iio_const_attr_available_sampling_frequency
.dev_attr
.attr
,
488 static const struct attribute_group hmc5843_group
= {
489 .attrs
= hmc5843_attributes
,
492 static int hmc5843_detect(struct i2c_client
*client
,
493 struct i2c_board_info
*info
)
495 unsigned char id_str
[HMC5843_ID_REG_LENGTH
];
497 if (client
->addr
!= HMC5843_I2C_ADDRESS
)
500 if (i2c_smbus_read_i2c_block_data(client
, HMC5843_ID_REG_A
,
501 HMC5843_ID_REG_LENGTH
, id_str
)
502 != HMC5843_ID_REG_LENGTH
)
505 if (0 != strncmp(id_str
, HMC5843_ID_STRING
, HMC5843_ID_REG_LENGTH
))
511 /* Called when we have found a new HMC5843. */
512 static void hmc5843_init_client(struct i2c_client
*client
)
514 struct hmc5843_data
*data
= i2c_get_clientdata(client
);
515 hmc5843_set_meas_conf(client
, data
->meas_conf
);
516 hmc5843_set_rate(client
, data
->rate
);
517 hmc5843_configure(client
, data
->operating_mode
);
518 i2c_smbus_write_byte_data(client
, HMC5843_CONFIG_REG_B
, data
->range
);
519 mutex_init(&data
->lock
);
520 pr_info("HMC5843 initialized\n");
523 static int hmc5843_probe(struct i2c_client
*client
,
524 const struct i2c_device_id
*id
)
526 struct hmc5843_data
*data
;
529 data
= kzalloc(sizeof(struct hmc5843_data
), GFP_KERNEL
);
535 /* default settings at probe */
537 data
->meas_conf
= CONF_NORMAL
;
538 data
->range
= RANGE_1_0
;
539 data
->operating_mode
= MODE_CONVERSION_CONTINUOUS
;
541 i2c_set_clientdata(client
, data
);
543 /* Initialize the HMC5843 chip */
544 hmc5843_init_client(client
);
546 data
->indio_dev
= iio_allocate_device();
547 if (!data
->indio_dev
) {
551 data
->indio_dev
->attrs
= &hmc5843_group
;
552 data
->indio_dev
->dev
.parent
= &client
->dev
;
553 data
->indio_dev
->dev_data
= (void *)(data
);
554 data
->indio_dev
->driver_module
= THIS_MODULE
;
555 data
->indio_dev
->modes
= INDIO_DIRECT_MODE
;
556 err
= iio_device_register(data
->indio_dev
);
561 iio_free_device(data
->indio_dev
);
568 static int hmc5843_remove(struct i2c_client
*client
)
570 struct hmc5843_data
*data
= i2c_get_clientdata(client
);
571 /* sleep mode to save power */
572 hmc5843_configure(client
, MODE_SLEEP
);
573 iio_device_unregister(data
->indio_dev
);
574 kfree(i2c_get_clientdata(client
));
578 static int hmc5843_suspend(struct i2c_client
*client
, pm_message_t mesg
)
580 hmc5843_configure(client
, MODE_SLEEP
);
584 static int hmc5843_resume(struct i2c_client
*client
)
586 struct hmc5843_data
*data
= i2c_get_clientdata(client
);
587 hmc5843_configure(client
, data
->operating_mode
);
591 static const struct i2c_device_id hmc5843_id
[] = {
596 static struct i2c_driver hmc5843_driver
= {
600 .id_table
= hmc5843_id
,
601 .probe
= hmc5843_probe
,
602 .remove
= hmc5843_remove
,
603 .detect
= hmc5843_detect
,
604 .address_list
= normal_i2c
,
605 .suspend
= hmc5843_suspend
,
606 .resume
= hmc5843_resume
,
609 static int __init
hmc5843_init(void)
611 return i2c_add_driver(&hmc5843_driver
);
614 static void __exit
hmc5843_exit(void)
616 i2c_del_driver(&hmc5843_driver
);
619 MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com");
620 MODULE_DESCRIPTION("HMC5843 driver");
621 MODULE_LICENSE("GPL");
623 module_init(hmc5843_init
);
624 module_exit(hmc5843_exit
);