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>
28 #define HMC5843_I2C_ADDRESS 0x1E
30 #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
39 #define HMC5843_STATUS_REG 0x09
40 #define HMC5843_ID_REG_A 0x0A
41 #define HMC5843_ID_REG_B 0x0B
42 #define HMC5843_ID_REG_C 0x0C
44 #define HMC5843_ID_REG_LENGTH 0x03
45 #define HMC5843_ID_STRING "H43"
48 * Range settings in (+-)Ga
50 #define RANGE_GAIN_OFFSET 0x05
52 #define RANGE_0_7 0x00
53 #define RANGE_1_0 0x01 /* default */
54 #define RANGE_1_5 0x02
55 #define RANGE_2_0 0x03
56 #define RANGE_3_2 0x04
57 #define RANGE_3_8 0x05
58 #define RANGE_4_5 0x06
59 #define RANGE_6_5 0x07 /* Not recommended */
64 #define DATA_READY 0x01
65 #define DATA_OUTPUT_LOCK 0x02
66 #define VOLTAGE_REGULATOR_ENABLED 0x04
69 * Mode register configuration
71 #define MODE_CONVERSION_CONTINUOUS 0x00
72 #define MODE_CONVERSION_SINGLE 0x01
73 #define MODE_IDLE 0x02
74 #define MODE_SLEEP 0x03
76 /* Minimum Data Output Rate in 1/10 Hz */
77 #define RATE_OFFSET 0x02
78 #define RATE_BITMASK 0x1C
86 #define RATE_NOT_USED 0x07
89 * Device Configutration
91 #define CONF_NORMAL 0x00
92 #define CONF_POSITIVE_BIAS 0x01
93 #define CONF_NEGATIVE_BIAS 0x02
94 #define CONF_NOT_USED 0x03
95 #define MEAS_CONF_MASK 0x03
97 static int hmc5843_regval_to_nanoscale
[] = {
98 6173, 7692, 10309, 12821, 18868, 21739, 25641, 35714
101 static const int regval_to_input_field_mg
[] = {
111 static const char * const regval_to_samp_freq
[] = {
121 /* Addresses to scan: 0x1E */
122 static const unsigned short normal_i2c
[] = { HMC5843_I2C_ADDRESS
,
125 /* Each client has this additional data */
126 struct hmc5843_data
{
134 static void hmc5843_init_client(struct i2c_client
*client
);
136 static s32
hmc5843_configure(struct i2c_client
*client
,
139 /* The lower two bits contain the current conversion mode */
140 return i2c_smbus_write_byte_data(client
,
142 (operating_mode
& 0x03));
145 /* Return the measurement value from the specified channel */
146 static int hmc5843_read_measurement(struct iio_dev
*indio_dev
,
150 struct i2c_client
*client
= to_i2c_client(indio_dev
->dev
.parent
);
151 struct hmc5843_data
*data
= iio_priv(indio_dev
);
154 mutex_lock(&data
->lock
);
155 result
= i2c_smbus_read_byte_data(client
, HMC5843_STATUS_REG
);
156 while (!(result
& DATA_READY
))
157 result
= i2c_smbus_read_byte_data(client
, HMC5843_STATUS_REG
);
159 result
= i2c_smbus_read_word_data(client
, address
);
160 mutex_unlock(&data
->lock
);
164 *val
= (s16
)swab16((u16
)result
);
171 * 0 - Continuous-Conversion Mode: In continuous-conversion mode, the
172 * device continuously performs conversions an places the result in the
175 * 1 - Single-Conversion Mode : device performs a single measurement,
176 * sets RDY high and returned to sleep mode
178 * 2 - Idle Mode : Device is placed in idle mode.
180 * 3 - Sleep Mode. Device is placed in sleep mode.
183 static ssize_t
hmc5843_show_operating_mode(struct device
*dev
,
184 struct device_attribute
*attr
,
187 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
188 struct hmc5843_data
*data
= iio_priv(indio_dev
);
189 return sprintf(buf
, "%d\n", data
->operating_mode
);
192 static ssize_t
hmc5843_set_operating_mode(struct device
*dev
,
193 struct device_attribute
*attr
,
197 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
198 struct i2c_client
*client
= to_i2c_client(indio_dev
->dev
.parent
);
199 struct hmc5843_data
*data
= iio_priv(indio_dev
);
200 struct iio_dev_attr
*this_attr
= to_iio_dev_attr(attr
);
201 unsigned long operating_mode
= 0;
204 mutex_lock(&data
->lock
);
205 error
= strict_strtoul(buf
, 10, &operating_mode
);
210 dev_dbg(dev
, "set Conversion mode to %lu\n", operating_mode
);
211 if (operating_mode
> MODE_SLEEP
) {
216 status
= i2c_smbus_write_byte_data(client
, this_attr
->address
,
222 data
->operating_mode
= operating_mode
;
225 mutex_unlock(&data
->lock
);
228 static IIO_DEVICE_ATTR(operating_mode
,
230 hmc5843_show_operating_mode
,
231 hmc5843_set_operating_mode
,
235 * API for setting the measurement configuration to
236 * Normal, Positive bias and Negative bias
239 * Normal measurement configuration (default): In normal measurement
240 * configuration the device follows normal measurement flow. Pins BP and BN
241 * are left floating and high impedance.
243 * Positive bias configuration: In positive bias configuration, a positive
244 * current is forced across the resistive load on pins BP and BN.
246 * Negative bias configuration. In negative bias configuration, a negative
247 * current is forced across the resistive load on pins BP and BN.
250 static s32
hmc5843_set_meas_conf(struct i2c_client
*client
,
253 struct hmc5843_data
*data
= i2c_get_clientdata(client
);
255 reg_val
= (meas_conf
& MEAS_CONF_MASK
) | (data
->rate
<< RATE_OFFSET
);
256 return i2c_smbus_write_byte_data(client
, HMC5843_CONFIG_REG_A
, reg_val
);
259 static ssize_t
hmc5843_show_measurement_configuration(struct device
*dev
,
260 struct device_attribute
*attr
,
263 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
264 struct hmc5843_data
*data
= iio_priv(indio_dev
);
265 return sprintf(buf
, "%d\n", data
->meas_conf
);
268 static ssize_t
hmc5843_set_measurement_configuration(struct device
*dev
,
269 struct device_attribute
*attr
,
273 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
274 struct i2c_client
*client
= to_i2c_client(indio_dev
->dev
.parent
);
275 struct hmc5843_data
*data
= i2c_get_clientdata(client
);
276 unsigned long meas_conf
= 0;
277 int error
= strict_strtoul(buf
, 10, &meas_conf
);
280 mutex_lock(&data
->lock
);
282 dev_dbg(dev
, "set mode to %lu\n", meas_conf
);
283 if (hmc5843_set_meas_conf(client
, meas_conf
)) {
287 data
->meas_conf
= meas_conf
;
290 mutex_unlock(&data
->lock
);
293 static IIO_DEVICE_ATTR(meas_conf
,
295 hmc5843_show_measurement_configuration
,
296 hmc5843_set_measurement_configuration
,
301 * The table shows the minimum data output
302 * Value | Minimum data output rate(Hz)
312 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("0.5 1 2 5 10 20 50");
314 static s32
hmc5843_set_rate(struct i2c_client
*client
,
317 struct hmc5843_data
*data
= i2c_get_clientdata(client
);
320 reg_val
= (data
->meas_conf
) | (rate
<< RATE_OFFSET
);
321 if (rate
>= RATE_NOT_USED
) {
322 dev_err(&client
->dev
,
323 "This data output rate is not supported\n");
326 return i2c_smbus_write_byte_data(client
, HMC5843_CONFIG_REG_A
, reg_val
);
329 static ssize_t
set_sampling_frequency(struct device
*dev
,
330 struct device_attribute
*attr
,
331 const char *buf
, size_t count
)
334 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
335 struct i2c_client
*client
= to_i2c_client(indio_dev
->dev
.parent
);
336 struct hmc5843_data
*data
= iio_priv(indio_dev
);
337 unsigned long rate
= 0;
339 if (strncmp(buf
, "0.5" , 3) == 0)
341 else if (strncmp(buf
, "1" , 1) == 0)
343 else if (strncmp(buf
, "2", 1) == 0)
345 else if (strncmp(buf
, "5", 1) == 0)
347 else if (strncmp(buf
, "10", 2) == 0)
349 else if (strncmp(buf
, "20" , 2) == 0)
351 else if (strncmp(buf
, "50" , 2) == 0)
356 mutex_lock(&data
->lock
);
357 dev_dbg(dev
, "set rate to %lu\n", rate
);
358 if (hmc5843_set_rate(client
, rate
)) {
365 mutex_unlock(&data
->lock
);
369 static ssize_t
show_sampling_frequency(struct device
*dev
,
370 struct device_attribute
*attr
, char *buf
)
372 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
373 struct i2c_client
*client
= to_i2c_client(indio_dev
->dev
.parent
);
374 struct iio_dev_attr
*this_attr
= to_iio_dev_attr(attr
);
377 rate
= i2c_smbus_read_byte_data(client
, this_attr
->address
);
380 rate
= (rate
& RATE_BITMASK
) >> RATE_OFFSET
;
381 return sprintf(buf
, "%s\n", regval_to_samp_freq
[rate
]);
383 static IIO_DEVICE_ATTR(sampling_frequency
,
385 show_sampling_frequency
,
386 set_sampling_frequency
,
387 HMC5843_CONFIG_REG_A
);
391 * Nominal gain settings
392 * Value | Sensor Input Field Range(Ga) | Gain(counts/ milli-gauss)
402 static ssize_t
show_range(struct device
*dev
,
403 struct device_attribute
*attr
,
407 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
408 struct hmc5843_data
*data
= iio_priv(indio_dev
);
411 return sprintf(buf
, "%d\n", regval_to_input_field_mg
[range
]);
414 static ssize_t
set_range(struct device
*dev
,
415 struct device_attribute
*attr
,
419 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
420 struct i2c_client
*client
= to_i2c_client(indio_dev
->dev
.parent
);
421 struct iio_dev_attr
*this_attr
= to_iio_dev_attr(attr
);
422 struct hmc5843_data
*data
= iio_priv(indio_dev
);
423 unsigned long range
= 0;
425 mutex_lock(&data
->lock
);
426 error
= strict_strtoul(buf
, 10, &range
);
431 dev_dbg(dev
, "set range to %lu\n", range
);
433 if (range
> RANGE_6_5
) {
439 range
= range
<< RANGE_GAIN_OFFSET
;
440 if (i2c_smbus_write_byte_data(client
, this_attr
->address
, range
))
444 mutex_unlock(&data
->lock
);
448 static IIO_DEVICE_ATTR(in_magn_range
,
452 HMC5843_CONFIG_REG_B
);
454 static int hmc5843_read_raw(struct iio_dev
*indio_dev
,
455 struct iio_chan_spec
const *chan
,
459 struct hmc5843_data
*data
= iio_priv(indio_dev
);
463 return hmc5843_read_measurement(indio_dev
,
466 case (1 << IIO_CHAN_INFO_SCALE_SHARED
):
468 *val2
= hmc5843_regval_to_nanoscale
[data
->range
];
469 return IIO_VAL_INT_PLUS_NANO
;
474 #define HMC5843_CHANNEL(axis, add) \
478 .channel2 = IIO_MOD_##axis, \
479 .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED), \
483 static const struct iio_chan_spec hmc5843_channels
[] = {
484 HMC5843_CHANNEL(X
, HMC5843_DATA_OUT_X_MSB_REG
),
485 HMC5843_CHANNEL(Y
, HMC5843_DATA_OUT_Y_MSB_REG
),
486 HMC5843_CHANNEL(Z
, HMC5843_DATA_OUT_Z_MSB_REG
),
489 static struct attribute
*hmc5843_attributes
[] = {
490 &iio_dev_attr_meas_conf
.dev_attr
.attr
,
491 &iio_dev_attr_operating_mode
.dev_attr
.attr
,
492 &iio_dev_attr_sampling_frequency
.dev_attr
.attr
,
493 &iio_dev_attr_in_magn_range
.dev_attr
.attr
,
494 &iio_const_attr_sampling_frequency_available
.dev_attr
.attr
,
498 static const struct attribute_group hmc5843_group
= {
499 .attrs
= hmc5843_attributes
,
502 static int hmc5843_detect(struct i2c_client
*client
,
503 struct i2c_board_info
*info
)
505 unsigned char id_str
[HMC5843_ID_REG_LENGTH
];
507 if (client
->addr
!= HMC5843_I2C_ADDRESS
)
510 if (i2c_smbus_read_i2c_block_data(client
, HMC5843_ID_REG_A
,
511 HMC5843_ID_REG_LENGTH
, id_str
)
512 != HMC5843_ID_REG_LENGTH
)
515 if (0 != strncmp(id_str
, HMC5843_ID_STRING
, HMC5843_ID_REG_LENGTH
))
521 /* Called when we have found a new HMC5843. */
522 static void hmc5843_init_client(struct i2c_client
*client
)
524 struct hmc5843_data
*data
= i2c_get_clientdata(client
);
525 hmc5843_set_meas_conf(client
, data
->meas_conf
);
526 hmc5843_set_rate(client
, data
->rate
);
527 hmc5843_configure(client
, data
->operating_mode
);
528 i2c_smbus_write_byte_data(client
, HMC5843_CONFIG_REG_B
, data
->range
);
529 mutex_init(&data
->lock
);
530 pr_info("HMC5843 initialized\n");
533 static const struct iio_info hmc5843_info
= {
534 .attrs
= &hmc5843_group
,
535 .read_raw
= &hmc5843_read_raw
,
536 .driver_module
= THIS_MODULE
,
539 static int hmc5843_probe(struct i2c_client
*client
,
540 const struct i2c_device_id
*id
)
542 struct hmc5843_data
*data
;
543 struct iio_dev
*indio_dev
;
546 indio_dev
= iio_allocate_device(sizeof(*data
));
547 if (indio_dev
== NULL
) {
551 data
= iio_priv(indio_dev
);
552 /* default settings at probe */
554 data
->meas_conf
= CONF_NORMAL
;
555 data
->range
= RANGE_1_0
;
556 data
->operating_mode
= MODE_CONVERSION_CONTINUOUS
;
558 i2c_set_clientdata(client
, indio_dev
);
560 /* Initialize the HMC5843 chip */
561 hmc5843_init_client(client
);
563 indio_dev
->info
= &hmc5843_info
;
564 indio_dev
->name
= id
->name
;
565 indio_dev
->channels
= hmc5843_channels
;
566 indio_dev
->num_channels
= ARRAY_SIZE(hmc5843_channels
);
567 indio_dev
->dev
.parent
= &client
->dev
;
568 indio_dev
->modes
= INDIO_DIRECT_MODE
;
569 err
= iio_device_register(indio_dev
);
574 iio_free_device(indio_dev
);
579 static int hmc5843_remove(struct i2c_client
*client
)
581 struct iio_dev
*indio_dev
= i2c_get_clientdata(client
);
583 iio_device_unregister(indio_dev
);
584 /* sleep mode to save power */
585 hmc5843_configure(client
, MODE_SLEEP
);
586 iio_free_device(indio_dev
);
591 static int hmc5843_suspend(struct i2c_client
*client
, pm_message_t mesg
)
593 hmc5843_configure(client
, MODE_SLEEP
);
597 static int hmc5843_resume(struct i2c_client
*client
)
599 struct hmc5843_data
*data
= i2c_get_clientdata(client
);
600 hmc5843_configure(client
, data
->operating_mode
);
604 static const struct i2c_device_id hmc5843_id
[] = {
609 static struct i2c_driver hmc5843_driver
= {
613 .id_table
= hmc5843_id
,
614 .probe
= hmc5843_probe
,
615 .remove
= hmc5843_remove
,
616 .detect
= hmc5843_detect
,
617 .address_list
= normal_i2c
,
618 .suspend
= hmc5843_suspend
,
619 .resume
= hmc5843_resume
,
622 static int __init
hmc5843_init(void)
624 return i2c_add_driver(&hmc5843_driver
);
627 static void __exit
hmc5843_exit(void)
629 i2c_del_driver(&hmc5843_driver
);
632 MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com");
633 MODULE_DESCRIPTION("HMC5843 driver");
634 MODULE_LICENSE("GPL");
636 module_init(hmc5843_init
);
637 module_exit(hmc5843_exit
);