From: Peter Meerwald <pmeerw@pmeerw.net>
To: linux-iio@vger.kernel.org
Cc: jic23@kernel.org, lars@metafoo.de, Peter Meerwald <pmeerw@pmeerw.net>
Subject: [PATCH 8/8] iio: add support for hmc5883/hmc5883l to hmc5843 magnetometer driver
Date: Wed, 9 May 2012 00:20:06 +0200 [thread overview]
Message-ID: <1336515606-12364-9-git-send-email-pmeerw@pmeerw.net> (raw)
In-Reply-To: <1336515606-12364-1-git-send-email-pmeerw@pmeerw.net>
From: Peter Meerwald <p.meerwald@bct-electronic.com>
v2 addresses review comments:
* fixes and cleanups have been split out (Jonathan Cameron)
* constants are generally prefixed HMC5843_, except when related
specifically to hmc5883 (Jonathan Cameron)
* simplify code and avoid temp buffer in
hmc5843_show_sampling_frequencies_available() (Lars-Peter Clausen)
* use sysfs_streq() instead of strncmp()/strlen() in
hmc5843_check_sampling_frequency() (Lars-Peter Clausen)
Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net>
---
drivers/staging/iio/magnetometer/Kconfig | 8 +-
drivers/staging/iio/magnetometer/hmc5843.c | 181 +++++++++++++++++++++++----
2 files changed, 158 insertions(+), 31 deletions(-)
diff --git a/drivers/staging/iio/magnetometer/Kconfig b/drivers/staging/iio/magnetometer/Kconfig
index 722c4e1..b9d9325 100644
--- a/drivers/staging/iio/magnetometer/Kconfig
+++ b/drivers/staging/iio/magnetometer/Kconfig
@@ -15,13 +15,13 @@ config SENSORS_AK8975
will be called ak8975.
config SENSORS_HMC5843
- tristate "Honeywell HMC5843 3-Axis Magnetometer"
+ tristate "Honeywell HMC5843/5883/5883L 3-Axis Magnetometer"
depends on I2C
help
- Say Y here to add support for the Honeywell HMC 5843 3-Axis
- Magnetometer (digital compass).
+ Say Y here to add support for the Honeywell HMC5843, HMC5883 and
+ HMC5883L 3-Axis Magnetometer (digital compass).
To compile this driver as a module, choose M here: the module
- will be called hmc5843
+ will be called hmc5843.
endmenu
diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c
index 2e1bc6c..8321a77 100644
--- a/drivers/staging/iio/magnetometer/hmc5843.c
+++ b/drivers/staging/iio/magnetometer/hmc5843.c
@@ -2,6 +2,8 @@
Author: Shubhrajyoti Datta <shubhrajyoti@ti.com>
Acknowledgement: Jonathan Cameron <jic23@cam.ac.uk> for valuable inputs.
+ Support for HMC5883 and HMC5883L by Peter Meerwald <pmeerw@pmeerw.net>.
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
@@ -44,6 +46,11 @@
#define HMC5843_ID_REG_B 0x0B
#define HMC5843_ID_REG_C 0x0C
+enum hmc5843_ids {
+ HMC5843_ID,
+ HMC5883_ID,
+ HMC5883L_ID,
+};
/*
* Beware: identification of the HMC5883 is still "H43";
@@ -103,8 +110,16 @@ static const int hmc5843_regval_to_nanoscale[] = {
6173, 7692, 10309, 12821, 18868, 21739, 25641, 35714
};
+static const int hmc5883_regval_to_nanoscale[] = {
+ 7812, 9766, 13021, 16287, 24096, 27701, 32573, 45662
+};
+
+static const int hmc5883l_regval_to_nanoscale[] = {
+ 7299, 9174, 12195, 15152, 22727, 25641, 30303, 43478
+};
+
/*
- * From the datasheet:
+ * From the HMC5843 datasheet:
* Value | Sensor input field range (Ga) | Gain (counts/milli-Gauss)
* 0 | (+-)0.7 | 1620
* 1 | (+-)1.0 | 1300
@@ -114,6 +129,28 @@ static const int hmc5843_regval_to_nanoscale[] = {
* 5 | (+-)3.8 | 460
* 6 | (+-)4.5 | 390
* 7 | (+-)6.5 | 280
+ *
+ * From the HMC5883 datasheet:
+ * Value | Recommended sensor field range (Ga) | Gain (counts/Gauss)
+ * 0 | (+-)0.9 | 1280
+ * 1 | (+-)1.2 | 1024
+ * 2 | (+-)1.9 | 768
+ * 3 | (+-)2.5 | 614
+ * 4 | (+-)4.0 | 415
+ * 5 | (+-)4.6 | 361
+ * 6 | (+-)5.5 | 307
+ * 7 | (+-)7.9 | 219
+ *
+ * From the HMC5883L datasheet:
+ * Value | Recommended sensor field range (Ga) | Gain (LSB/Gauss)
+ * 0 | (+-)0.88 | 1370
+ * 1 | (+-)1.3 | 1090
+ * 2 | (+-)1.9 | 820
+ * 3 | (+-)2.5 | 660
+ * 4 | (+-)4.0 | 440
+ * 5 | (+-)4.7 | 390
+ * 6 | (+-)5.6 | 330
+ * 7 | (+-)8.1 | 230
*/
static const int hmc5843_regval_to_input_field_mga[] = {
700,
@@ -126,17 +163,41 @@ static const int hmc5843_regval_to_input_field_mga[] = {
6500
};
+static const int hmc5883_regval_to_input_field_mga[] = {
+ 900,
+ 1200,
+ 1900,
+ 2500,
+ 4000,
+ 4600,
+ 5500,
+ 7900
+};
+
+static const int hmc5883l_regval_to_input_field_mga[] = {
+ 880,
+ 1300,
+ 1900,
+ 2500,
+ 4000,
+ 4700,
+ 5600,
+ 8100
+};
+
+
/*
* From the datasheet:
- * Value | Data output rate (Hz)
- * 0 | 0.5
- * 1 | 1
- * 2 | 2
- * 3 | 5
- * 4 | 10 (default)
- * 5 | 20
- * 6 | 50
- * 7 | Not used
+ * Value | HMC5843 | HMC5883/HMC5883L
+ * | Data output rate (Hz) | Data output rate (Hz)
+ * 0 | 0.5 | 0.75
+ * 1 | 1 | 1.5
+ * 2 | 2 | 3
+ * 3 | 5 | 7.5
+ * 4 | 10 (default) | 15
+ * 5 | 20 | 30
+ * 6 | 50 | 75
+ * 7 | Not used | Not used
*/
static const char * const hmc5843_regval_to_sample_freq[] = {
"0.5",
@@ -148,6 +209,16 @@ static const char * const hmc5843_regval_to_sample_freq[] = {
"50",
};
+static const char * const hmc5883_regval_to_sample_freq[] = {
+ "0.75",
+ "1.5",
+ "3",
+ "7.5",
+ "15",
+ "30",
+ "75",
+};
+
/* Addresses to scan: 0x1E */
static const unsigned short normal_i2c[] = { HMC5843_I2C_ADDRESS,
I2C_CLIENT_END };
@@ -159,6 +230,9 @@ struct hmc5843_data {
u8 meas_conf;
u8 operating_mode;
u8 range;
+ const char * const *regval_to_sample_freq;
+ const int *regval_to_input_field_mga;
+ const int *regval_to_nanoscale;
};
/* The lower two bits contain the current conversion mode */
@@ -334,7 +408,25 @@ static IIO_DEVICE_ATTR(meas_conf,
hmc5843_set_measurement_configuration,
0);
-static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("0.5 1 2 5 10 20 50");
+static ssize_t hmc5843_show_sampling_frequencies_available(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct hmc5843_data *data = iio_priv(indio_dev);
+ ssize_t total_n = 0;
+ int i;
+
+ for (i = 0; i < HMC5843_RATE_NOT_USED; i++) {
+ ssize_t n = sprintf(buf, "%s ", data->regval_to_sample_freq[i]);
+ buf += n;
+ total_n += n;
+ }
+
+ return total_n;
+}
+
+static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hmc5843_show_sampling_frequencies_available);
static s32 hmc5843_set_rate(struct i2c_client *client,
u8 rate)
@@ -343,24 +435,23 @@ static s32 hmc5843_set_rate(struct i2c_client *client,
struct hmc5843_data *data = iio_priv(indio_dev);
u8 reg_val;
- reg_val = (data->meas_conf) | (rate << HMC5843_RATE_OFFSET);
if (rate >= HMC5843_RATE_NOT_USED) {
dev_err(&client->dev,
"data output rate is not supported\n");
return -EINVAL;
}
+ reg_val = data->meas_conf | (rate << HMC5843_RATE_OFFSET);
return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
}
static int hmc5843_check_sampling_frequency(struct hmc5843_data *data,
const char *buf)
{
- const char * const *samp_freq = hmc5843_regval_to_sample_freq;
+ const char * const *samp_freq = data->regval_to_sample_freq;
int i;
for (i = 0; i < HMC5843_RATE_NOT_USED; i++) {
- if (strncmp(buf, samp_freq[i],
- strlen(samp_freq[i])) == 0)
+ if (sysfs_streq(buf, samp_freq[i]))
return i;
}
@@ -403,13 +494,14 @@ static ssize_t hmc5843_show_sampling_frequency(struct device *dev,
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+ struct hmc5843_data *data = iio_priv(indio_dev);
s32 rate;
rate = i2c_smbus_read_byte_data(client, this_attr->address);
if (rate < 0)
return rate;
rate = (rate & HMC5843_RATE_BITMASK) >> HMC5843_RATE_OFFSET;
- return sprintf(buf, "%s\n", hmc5843_regval_to_sample_freq[rate]);
+ return sprintf(buf, "%s\n", data->regval_to_sample_freq[rate]);
}
static IIO_DEVICE_ATTR(sampling_frequency,
@@ -427,7 +519,7 @@ static ssize_t hmc5843_show_range_gain(struct device *dev,
struct hmc5843_data *data = iio_priv(indio_dev);
range = data->range;
- return sprintf(buf, "%d\n", hmc5843_regval_to_input_field_mga[range]);
+ return sprintf(buf, "%d\n", data->regval_to_input_field_mga[range]);
}
static ssize_t hmc5843_set_range_gain(struct device *dev,
@@ -485,7 +577,7 @@ static int hmc5843_read_raw(struct iio_dev *indio_dev,
val);
case IIO_CHAN_INFO_SCALE:
*val = 0;
- *val2 = hmc5843_regval_to_nanoscale[data->range];
+ *val2 = data->regval_to_nanoscale[data->range];
return IIO_VAL_INT_PLUS_NANO;
};
return -EINVAL;
@@ -507,12 +599,19 @@ static const struct iio_chan_spec hmc5843_channels[] = {
HMC5843_CHANNEL(Z, HMC5843_DATA_OUT_Z_MSB_REG),
};
+static const struct iio_chan_spec hmc5883_channels[] = {
+ HMC5843_CHANNEL(X, HMC5843_DATA_OUT_X_MSB_REG),
+ HMC5843_CHANNEL(Y, HMC5883_DATA_OUT_Y_MSB_REG),
+ HMC5843_CHANNEL(Z, HMC5883_DATA_OUT_Z_MSB_REG),
+};
+
+
static struct attribute *hmc5843_attributes[] = {
&iio_dev_attr_meas_conf.dev_attr.attr,
&iio_dev_attr_operating_mode.dev_attr.attr,
&iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_dev_attr_in_magn_range.dev_attr.attr,
- &iio_const_attr_sampling_frequency_available.dev_attr.attr,
+ &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
NULL
};
@@ -539,19 +638,47 @@ static int hmc5843_detect(struct i2c_client *client,
return 0;
}
-/* Called when we have found a new HMC5843 */
-static void hmc5843_init_client(struct i2c_client *client)
+/* Called when we have found a new HMC58X3 */
+static void hmc5843_init_client(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct hmc5843_data *data = iio_priv(indio_dev);
+ switch (id->driver_data) {
+ case HMC5843_ID:
+ data->regval_to_sample_freq = hmc5843_regval_to_sample_freq;
+ data->regval_to_input_field_mga =
+ hmc5843_regval_to_input_field_mga;
+ data->regval_to_nanoscale = hmc5843_regval_to_nanoscale;
+ indio_dev->channels = hmc5843_channels;
+ indio_dev->num_channels = ARRAY_SIZE(hmc5843_channels);
+ break;
+ case HMC5883_ID:
+ data->regval_to_sample_freq = hmc5883_regval_to_sample_freq;
+ data->regval_to_input_field_mga =
+ hmc5883_regval_to_input_field_mga;
+ data->regval_to_nanoscale = hmc5883_regval_to_nanoscale;
+ indio_dev->channels = hmc5883_channels;
+ indio_dev->num_channels = ARRAY_SIZE(hmc5883_channels);
+ break;
+ case HMC5883L_ID:
+ data->regval_to_sample_freq = hmc5883_regval_to_sample_freq;
+ data->regval_to_input_field_mga =
+ hmc5883l_regval_to_input_field_mga;
+ data->regval_to_nanoscale = hmc5883l_regval_to_nanoscale;
+ indio_dev->channels = hmc5883_channels;
+ indio_dev->num_channels = ARRAY_SIZE(hmc5883_channels);
+ break;
+ }
+
hmc5843_set_meas_conf(client, data->meas_conf);
hmc5843_set_rate(client, data->rate);
hmc5843_configure(client, data->operating_mode);
i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_B, data->range);
mutex_init(&data->lock);
- pr_info("HMC5843 initialized\n");
+ pr_info("%s initialized\n", id->name);
}
static const struct iio_info hmc5843_info = {
@@ -580,12 +707,10 @@ static int hmc5843_probe(struct i2c_client *client,
data->operating_mode = HMC5843_MODE_CONVERSION_CONTINUOUS;
i2c_set_clientdata(client, indio_dev);
- hmc5843_init_client(client);
+ hmc5843_init_client(client, id);
indio_dev->info = &hmc5843_info;
indio_dev->name = id->name;
- indio_dev->channels = hmc5843_channels;
- indio_dev->num_channels = ARRAY_SIZE(hmc5843_channels);
indio_dev->dev.parent = &client->dev;
indio_dev->modes = INDIO_DIRECT_MODE;
@@ -636,7 +761,9 @@ static SIMPLE_DEV_PM_OPS(hmc5843_pm_ops, hmc5843_suspend, hmc5843_resume);
#endif
static const struct i2c_device_id hmc5843_id[] = {
- { "hmc5843", 0 },
+ { "hmc5843", HMC5843_ID },
+ { "hmc5883", HMC5883_ID },
+ { "hmc5883l", HMC5883L_ID },
{ }
};
MODULE_DEVICE_TABLE(i2c, hmc5843_id);
@@ -655,5 +782,5 @@ static struct i2c_driver hmc5843_driver = {
module_i2c_driver(hmc5843_driver);
MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com");
-MODULE_DESCRIPTION("HMC5843 driver");
+MODULE_DESCRIPTION("HMC5843/5883/5883L driver");
MODULE_LICENSE("GPL");
--
1.7.5.4
next prev parent reply other threads:[~2012-05-08 22:21 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-05-08 22:19 iio: v2, add support for HMC5883/HMC5883L to HMC5843 driver Peter Meerwald
2012-05-08 22:19 ` [PATCH 1/8] iio: fix access to hmc5843 private data Peter Meerwald
2012-05-09 9:59 ` Shubhrajyoti Datta
2012-05-10 14:19 ` Shubhrajyoti Datta
2012-05-10 9:10 ` Jonathan Cameron
2012-05-10 13:18 ` Peter Meerwald
2012-05-08 22:20 ` [PATCH 2/8] iio: change strict_strtoul() to kstrtoul() in hmc5843 Peter Meerwald
2012-05-10 9:11 ` Jonathan Cameron
2012-05-08 22:20 ` [PATCH 3/8] iio: rename and prefix CONSTANTs to distinguish between HMC5843 and HMC5883 Peter Meerwald
2012-05-10 12:11 ` Jonathan Cameron
2012-05-08 22:20 ` [PATCH 4/8] iio: rework sampling rate setting in hmc5843 Peter Meerwald
2012-05-10 12:13 ` Jonathan Cameron
2012-05-08 22:20 ` [PATCH 5/8] iio: add check for measurement configuration value passed to hmc5843 Peter Meerwald
2012-05-10 12:15 ` Jonathan Cameron
2012-05-08 22:20 ` [PATCH 6/8] iio: cleanup and move comments in hmc5843 Peter Meerwald
2012-05-10 12:18 ` Jonathan Cameron
2012-05-08 22:20 ` [PATCH 7/8] iio: rename function/data to consistently start with hmc5843_ Peter Meerwald
2012-05-10 12:18 ` Jonathan Cameron
2012-05-08 22:20 ` Peter Meerwald [this message]
2012-05-10 12:29 ` [PATCH 8/8] iio: add support for hmc5883/hmc5883l to hmc5843 magnetometer driver Jonathan Cameron
2012-05-09 9:55 ` iio: v2, add support for HMC5883/HMC5883L to HMC5843 driver Shubhrajyoti Datta
2012-05-09 13:33 ` Peter Meerwald
2012-05-09 14:20 ` Jonathan Cameron
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1336515606-12364-9-git-send-email-pmeerw@pmeerw.net \
--to=pmeerw@pmeerw.net \
--cc=jic23@kernel.org \
--cc=lars@metafoo.de \
--cc=linux-iio@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).