aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/iio/magnetometer/Kconfig8
-rw-r--r--drivers/staging/iio/magnetometer/hmc5843.c186
2 files changed, 149 insertions, 45 deletions
diff --git a/drivers/staging/iio/magnetometer/Kconfig b/drivers/staging/iio/magnetometer/Kconfig
index 722c4e13f713..b9d932595ba9 100644
--- a/drivers/staging/iio/magnetometer/Kconfig
+++ b/drivers/staging/iio/magnetometer/Kconfig
@@ -15,13 +15,13 @@ config SENSORS_AK8975
15 will be called ak8975. 15 will be called ak8975.
16 16
17config SENSORS_HMC5843 17config SENSORS_HMC5843
18 tristate "Honeywell HMC5843 3-Axis Magnetometer" 18 tristate "Honeywell HMC5843/5883/5883L 3-Axis Magnetometer"
19 depends on I2C 19 depends on I2C
20 help 20 help
21 Say Y here to add support for the Honeywell HMC 5843 3-Axis 21 Say Y here to add support for the Honeywell HMC5843, HMC5883 and
22 Magnetometer (digital compass). 22 HMC5883L 3-Axis Magnetometer (digital compass).
23 23
24 To compile this driver as a module, choose M here: the module 24 To compile this driver as a module, choose M here: the module
25 will be called hmc5843 25 will be called hmc5843.
26 26
27endmenu 27endmenu
diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c
index 32f19b7493d9..c1fa09f07625 100644
--- a/drivers/staging/iio/magnetometer/hmc5843.c
+++ b/drivers/staging/iio/magnetometer/hmc5843.c
@@ -2,6 +2,8 @@
2 Author: Shubhrajyoti Datta <shubhrajyoti@ti.com> 2 Author: Shubhrajyoti Datta <shubhrajyoti@ti.com>
3 Acknowledgement: Jonathan Cameron <jic23@cam.ac.uk> for valuable inputs. 3 Acknowledgement: Jonathan Cameron <jic23@cam.ac.uk> for valuable inputs.
4 4
5 Support for HMC5883 and HMC5883L by Peter Meerwald <pmeerw@pmeerw.net>.
6
5 This program is free software; you can redistribute it and/or modify 7 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 8 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 9 the Free Software Foundation; either version 2 of the License, or
@@ -44,6 +46,11 @@
44#define HMC5843_ID_REG_B 0x0B 46#define HMC5843_ID_REG_B 0x0B
45#define HMC5843_ID_REG_C 0x0C 47#define HMC5843_ID_REG_C 0x0C
46 48
49enum hmc5843_ids {
50 HMC5843_ID,
51 HMC5883_ID,
52 HMC5883L_ID,
53};
47 54
48/* 55/*
49 * Beware: identification of the HMC5883 is still "H43"; 56 * Beware: identification of the HMC5883 is still "H43";
@@ -103,8 +110,16 @@ static const int hmc5843_regval_to_nanoscale[] = {
103 6173, 7692, 10309, 12821, 18868, 21739, 25641, 35714 110 6173, 7692, 10309, 12821, 18868, 21739, 25641, 35714
104}; 111};
105 112
113static 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
106/* 121/*
107 * From the datasheet: 122 * From the HMC5843 datasheet:
108 * Value | Sensor input field range (Ga) | Gain (counts/milli-Gauss) 123 * Value | Sensor input field range (Ga) | Gain (counts/milli-Gauss)
109 * 0 | (+-)0.7 | 1620 124 * 0 | (+-)0.7 | 1620
110 * 1 | (+-)1.0 | 1300 125 * 1 | (+-)1.0 | 1300
@@ -114,44 +129,75 @@ static const int hmc5843_regval_to_nanoscale[] = {
114 * 5 | (+-)3.8 | 460 129 * 5 | (+-)3.8 | 460
115 * 6 | (+-)4.5 | 390 130 * 6 | (+-)4.5 | 390
116 * 7 | (+-)6.5 | 280 131 * 7 | (+-)6.5 | 280
132 *
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
117 */ 154 */
118static const int hmc5843_regval_to_input_field_mga[] = { 155static const int hmc5843_regval_to_input_field_mga[] = {
119 700, 156 700, 1000, 1500, 2000, 3200, 3800, 4500, 6500
120 1000, 157};
121 1500, 158
122 2000, 159static const int hmc5883_regval_to_input_field_mga[] = {
123 3200, 160 900, 1200, 1900, 2500, 4000, 4600, 5500, 7900
124 3800, 161};
125 4500, 162
126 6500 163static const int hmc5883l_regval_to_input_field_mga[] = {
164 880, 1300, 1900, 2500, 4000, 4700, 5600, 8100
127}; 165};
128 166
129/* 167/*
130 * From the datasheet: 168 * From the datasheet:
131 * Value | Data output rate (Hz) 169 * Value | HMC5843 | HMC5883/HMC5883L
132 * 0 | 0.5 170 * | Data output rate (Hz) | Data output rate (Hz)
133 * 1 | 1 171 * 0 | 0.5 | 0.75
134 * 2 | 2 172 * 1 | 1 | 1.5
135 * 3 | 5 173 * 2 | 2 | 3
136 * 4 | 10 (default) 174 * 3 | 5 | 7.5
137 * 5 | 20 175 * 4 | 10 (default) | 15
138 * 6 | 50 176 * 5 | 20 | 30
139 * 7 | Not used 177 * 6 | 50 | 75
178 * 7 | Not used | Not used
140 */ 179 */
141static const char * const hmc5843_regval_to_sample_freq[] = { 180static const char * const hmc5843_regval_to_sample_freq[] = {
142 "0.5", 181 "0.5", "1", "2", "5", "10", "20", "50",
143 "1", 182};
144 "2", 183
145 "5", 184static const char * const hmc5883_regval_to_sample_freq[] = {
146 "10", 185 "0.75", "1.5", "3", "7.5", "15", "30", "75",
147 "20",
148 "50",
149}; 186};
150 187
151/* Addresses to scan: 0x1E */ 188/* Addresses to scan: 0x1E */
152static const unsigned short normal_i2c[] = { HMC5843_I2C_ADDRESS, 189static const unsigned short normal_i2c[] = { HMC5843_I2C_ADDRESS,
153 I2C_CLIENT_END }; 190 I2C_CLIENT_END };
154 191
192/* 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
155/* Each client has this additional data */ 201/* Each client has this additional data */
156struct hmc5843_data { 202struct hmc5843_data {
157 struct mutex lock; 203 struct mutex lock;
@@ -159,6 +205,7 @@ struct hmc5843_data {
159 u8 meas_conf; 205 u8 meas_conf;
160 u8 operating_mode; 206 u8 operating_mode;
161 u8 range; 207 u8 range;
208 const struct hmc5843_chip_info *variant;
162}; 209};
163 210
164/* The lower two bits contain the current conversion mode */ 211/* The lower two bits contain the current conversion mode */
@@ -334,7 +381,27 @@ static IIO_DEVICE_ATTR(meas_conf,
334 hmc5843_set_measurement_configuration, 381 hmc5843_set_measurement_configuration,
335 0); 382 0);
336 383
337static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("0.5 1 2 5 10 20 50"); 384static 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);
338 405
339static s32 hmc5843_set_rate(struct i2c_client *client, 406static s32 hmc5843_set_rate(struct i2c_client *client,
340 u8 rate) 407 u8 rate)
@@ -356,12 +423,11 @@ static s32 hmc5843_set_rate(struct i2c_client *client,
356static int hmc5843_check_sampling_frequency(struct hmc5843_data *data, 423static int hmc5843_check_sampling_frequency(struct hmc5843_data *data,
357 const char *buf) 424 const char *buf)
358{ 425{
359 const char * const *samp_freq = hmc5843_regval_to_sample_freq; 426 const char * const *samp_freq = data->variant->regval_to_sample_freq;
360 int i; 427 int i;
361 428
362 for (i = 0; i < HMC5843_RATE_NOT_USED; i++) { 429 for (i = 0; i < HMC5843_RATE_NOT_USED; i++) {
363 if (strncmp(buf, samp_freq[i], 430 if (sysfs_streq(buf, samp_freq[i]))
364 strlen(samp_freq[i])) == 0)
365 return i; 431 return i;
366 } 432 }
367 433
@@ -404,13 +470,14 @@ static ssize_t hmc5843_show_sampling_frequency(struct device *dev,
404 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 470 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
405 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent); 471 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
406 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); 472 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
473 struct hmc5843_data *data = iio_priv(indio_dev);
407 s32 rate; 474 s32 rate;
408 475
409 rate = i2c_smbus_read_byte_data(client, this_attr->address); 476 rate = i2c_smbus_read_byte_data(client, this_attr->address);
410 if (rate < 0) 477 if (rate < 0)
411 return rate; 478 return rate;
412 rate = (rate & HMC5843_RATE_BITMASK) >> HMC5843_RATE_OFFSET; 479 rate = (rate & HMC5843_RATE_BITMASK) >> HMC5843_RATE_OFFSET;
413 return sprintf(buf, "%s\n", hmc5843_regval_to_sample_freq[rate]); 480 return sprintf(buf, "%s\n", data->variant->regval_to_sample_freq[rate]);
414} 481}
415 482
416static IIO_DEVICE_ATTR(sampling_frequency, 483static IIO_DEVICE_ATTR(sampling_frequency,
@@ -428,7 +495,7 @@ static ssize_t hmc5843_show_range_gain(struct device *dev,
428 struct hmc5843_data *data = iio_priv(indio_dev); 495 struct hmc5843_data *data = iio_priv(indio_dev);
429 496
430 range = data->range; 497 range = data->range;
431 return sprintf(buf, "%d\n", hmc5843_regval_to_input_field_mga[range]); 498 return sprintf(buf, "%d\n", data->variant->regval_to_input_field_mga[range]);
432} 499}
433 500
434static ssize_t hmc5843_set_range_gain(struct device *dev, 501static ssize_t hmc5843_set_range_gain(struct device *dev,
@@ -486,7 +553,7 @@ static int hmc5843_read_raw(struct iio_dev *indio_dev,
486 val); 553 val);
487 case IIO_CHAN_INFO_SCALE: 554 case IIO_CHAN_INFO_SCALE:
488 *val = 0; 555 *val = 0;
489 *val2 = hmc5843_regval_to_nanoscale[data->range]; 556 *val2 = data->variant->regval_to_nanoscale[data->range];
490 return IIO_VAL_INT_PLUS_NANO; 557 return IIO_VAL_INT_PLUS_NANO;
491 }; 558 };
492 return -EINVAL; 559 return -EINVAL;
@@ -508,12 +575,18 @@ static const struct iio_chan_spec hmc5843_channels[] = {
508 HMC5843_CHANNEL(Z, HMC5843_DATA_OUT_Z_MSB_REG), 575 HMC5843_CHANNEL(Z, HMC5843_DATA_OUT_Z_MSB_REG),
509}; 576};
510 577
578static 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
511static struct attribute *hmc5843_attributes[] = { 584static struct attribute *hmc5843_attributes[] = {
512 &iio_dev_attr_meas_conf.dev_attr.attr, 585 &iio_dev_attr_meas_conf.dev_attr.attr,
513 &iio_dev_attr_operating_mode.dev_attr.attr, 586 &iio_dev_attr_operating_mode.dev_attr.attr,
514 &iio_dev_attr_sampling_frequency.dev_attr.attr, 587 &iio_dev_attr_sampling_frequency.dev_attr.attr,
515 &iio_dev_attr_in_magn_range.dev_attr.attr, 588 &iio_dev_attr_in_magn_range.dev_attr.attr,
516 &iio_const_attr_sampling_frequency_available.dev_attr.attr, 589 &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
517 NULL 590 NULL
518}; 591};
519 592
@@ -521,6 +594,33 @@ static const struct attribute_group hmc5843_group = {
521 .attrs = hmc5843_attributes, 594 .attrs = hmc5843_attributes,
522}; 595};
523 596
597static 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
524static int hmc5843_detect(struct i2c_client *client, 624static int hmc5843_detect(struct i2c_client *client,
525 struct i2c_board_info *info) 625 struct i2c_board_info *info)
526{ 626{
@@ -540,19 +640,23 @@ static int hmc5843_detect(struct i2c_client *client,
540 return 0; 640 return 0;
541} 641}
542 642
543/* Called when we have found a new HMC5843 */ 643/* Called when we have found a new HMC58X3 */
544static void hmc5843_init_client(struct i2c_client *client) 644static void hmc5843_init_client(struct i2c_client *client,
645 const struct i2c_device_id *id)
545{ 646{
546 struct iio_dev *indio_dev = i2c_get_clientdata(client); 647 struct iio_dev *indio_dev = i2c_get_clientdata(client);
547 struct hmc5843_data *data = iio_priv(indio_dev); 648 struct hmc5843_data *data = iio_priv(indio_dev);
548 649
650 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;
549 hmc5843_set_meas_conf(client, data->meas_conf); 653 hmc5843_set_meas_conf(client, data->meas_conf);
550 hmc5843_set_rate(client, data->rate); 654 hmc5843_set_rate(client, data->rate);
551 hmc5843_configure(client, data->operating_mode); 655 hmc5843_configure(client, data->operating_mode);
552 i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_B, data->range); 656 i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_B, data->range);
553 mutex_init(&data->lock); 657 mutex_init(&data->lock);
554 658
555 pr_info("HMC5843 initialized\n"); 659 pr_info("%s initialized\n", id->name);
556} 660}
557 661
558static const struct iio_info hmc5843_info = { 662static const struct iio_info hmc5843_info = {
@@ -581,12 +685,10 @@ static int hmc5843_probe(struct i2c_client *client,
581 data->operating_mode = HMC5843_MODE_CONVERSION_CONTINUOUS; 685 data->operating_mode = HMC5843_MODE_CONVERSION_CONTINUOUS;
582 686
583 i2c_set_clientdata(client, indio_dev); 687 i2c_set_clientdata(client, indio_dev);
584 hmc5843_init_client(client); 688 hmc5843_init_client(client, id);
585 689
586 indio_dev->info = &hmc5843_info; 690 indio_dev->info = &hmc5843_info;
587 indio_dev->name = id->name; 691 indio_dev->name = id->name;
588 indio_dev->channels = hmc5843_channels;
589 indio_dev->num_channels = ARRAY_SIZE(hmc5843_channels);
590 indio_dev->dev.parent = &client->dev; 692 indio_dev->dev.parent = &client->dev;
591 indio_dev->modes = INDIO_DIRECT_MODE; 693 indio_dev->modes = INDIO_DIRECT_MODE;
592 694
@@ -639,7 +741,9 @@ static SIMPLE_DEV_PM_OPS(hmc5843_pm_ops, hmc5843_suspend, hmc5843_resume);
639#endif 741#endif
640 742
641static const struct i2c_device_id hmc5843_id[] = { 743static const struct i2c_device_id hmc5843_id[] = {
642 { "hmc5843", 0 }, 744 { "hmc5843", HMC5843_ID },
745 { "hmc5883", HMC5883_ID },
746 { "hmc5883l", HMC5883L_ID },
643 { } 747 { }
644}; 748};
645MODULE_DEVICE_TABLE(i2c, hmc5843_id); 749MODULE_DEVICE_TABLE(i2c, hmc5843_id);
@@ -658,5 +762,5 @@ static struct i2c_driver hmc5843_driver = {
658module_i2c_driver(hmc5843_driver); 762module_i2c_driver(hmc5843_driver);
659 763
660MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com"); 764MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com");
661MODULE_DESCRIPTION("HMC5843 driver"); 765MODULE_DESCRIPTION("HMC5843/5883/5883L driver");
662MODULE_LICENSE("GPL"); 766MODULE_LICENSE("GPL");