From: Josef Gajdusek <atx@atalax.net>
To: linux-iio@vger.kernel.org
Cc: devel@driverdev.osuosl.org, gregkh@linuxfoundation.org,
jic23@kernel.org, linux-kernel@vger.kernel.org,
pmeerw@pmeerw.net, dan.carpenter@oracle.com
Subject: [PATCH v3 1/5] staging:iio:hmc5843: Added regmap support
Date: Tue, 8 Jul 2014 15:38:33 +0200 [thread overview]
Message-ID: <20140708133833.GC14393@dashie> (raw)
In-Reply-To: <20140708133711.GB14393@dashie>
This patch changes hmc5843.c to use regmap. This provides transparent caching
to the code as well as abstraction necessary to add support for SPI-based
hmc5983.
Signed-off-by: Josef Gajdusek <atx@atx.name>
---
drivers/staging/iio/magnetometer/Kconfig | 1 +
drivers/staging/iio/magnetometer/hmc5843.c | 140 +++++++++++++++++++----------
2 files changed, 96 insertions(+), 45 deletions(-)
diff --git a/drivers/staging/iio/magnetometer/Kconfig b/drivers/staging/iio/magnetometer/Kconfig
index 34634da..ad88d61 100644
--- a/drivers/staging/iio/magnetometer/Kconfig
+++ b/drivers/staging/iio/magnetometer/Kconfig
@@ -8,6 +8,7 @@ config SENSORS_HMC5843
depends on I2C
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
+ select REGMAP_I2C
help
Say Y here to add support for the Honeywell HMC5843, HMC5883 and
HMC5883L 3-Axis Magnetometer (digital compass).
diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c
index d4f4dd9..a458160 100644
--- a/drivers/staging/iio/magnetometer/hmc5843.c
+++ b/drivers/staging/iio/magnetometer/hmc5843.c
@@ -21,6 +21,7 @@
#include <linux/module.h>
#include <linux/i2c.h>
+#include <linux/regmap.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/trigger_consumer.h>
@@ -34,6 +35,7 @@
#define HMC5843_DATA_OUT_MSB_REGS 0x03
#define HMC5843_STATUS_REG 0x09
#define HMC5843_ID_REG 0x0a
+#define HMC5843_ID_END 0x0c
enum hmc5843_ids {
HMC5843_ID,
@@ -49,6 +51,7 @@ enum hmc5843_ids {
#define HMC5843_RANGE_GAIN_OFFSET 0x05
#define HMC5843_RANGE_GAIN_DEFAULT 0x01
#define HMC5843_RANGE_GAINS 8
+#define HMC5843_RANGE_GAIN_MASK 0xe0
/* Device status */
#define HMC5843_DATA_READY 0x01
@@ -68,6 +71,7 @@ enum hmc5843_ids {
#define HMC5843_RATE_OFFSET 0x02
#define HMC5843_RATE_DEFAULT 0x04
#define HMC5843_RATES 7
+#define HMC5843_RATE_MASK 0x1c
/* Device measurement configuration */
#define HMC5843_MEAS_CONF_NORMAL 0x00
@@ -121,10 +125,7 @@ struct hmc5843_chip_info {
struct hmc5843_data {
struct i2c_client *client;
struct mutex lock;
- u8 rate;
- u8 meas_conf;
- u8 operating_mode;
- u8 range;
+ struct regmap *regmap;
const struct hmc5843_chip_info *variant;
__be16 buffer[8]; /* 3x 16-bit channels + padding + 64-bit timestamp */
};
@@ -135,10 +136,8 @@ static s32 hmc5843_set_mode(struct hmc5843_data *data, u8 operating_mode)
int ret;
mutex_lock(&data->lock);
- ret = i2c_smbus_write_byte_data(data->client, HMC5843_MODE_REG,
- operating_mode & HMC5843_MODE_MASK);
- if (ret >= 0)
- data->operating_mode = operating_mode;
+ ret = regmap_update_bits(data->regmap, HMC5843_MODE_REG,
+ HMC5843_MODE_MASK, operating_mode);
mutex_unlock(&data->lock);
return ret;
@@ -146,15 +145,15 @@ static s32 hmc5843_set_mode(struct hmc5843_data *data, u8 operating_mode)
static int hmc5843_wait_measurement(struct hmc5843_data *data)
{
- s32 result;
int tries = 150;
+ int val;
+ int ret;
while (tries-- > 0) {
- result = i2c_smbus_read_byte_data(data->client,
- HMC5843_STATUS_REG);
- if (result < 0)
- return result;
- if (result & HMC5843_DATA_READY)
+ ret = regmap_read(data->regmap, HMC5843_STATUS_REG, &val);
+ if (ret < 0)
+ return ret;
+ if (val & HMC5843_DATA_READY)
break;
msleep(20);
}
@@ -171,20 +170,20 @@ static int hmc5843_wait_measurement(struct hmc5843_data *data)
static int hmc5843_read_measurement(struct hmc5843_data *data,
int idx, int *val)
{
- s32 result;
__be16 values[3];
+ int ret;
mutex_lock(&data->lock);
- result = hmc5843_wait_measurement(data);
- if (result < 0) {
+ ret = hmc5843_wait_measurement(data);
+ if (ret < 0) {
mutex_unlock(&data->lock);
- return result;
+ return ret;
}
- result = i2c_smbus_read_i2c_block_data(data->client,
- HMC5843_DATA_OUT_MSB_REGS, sizeof(values), (u8 *) values);
+ ret = regmap_bulk_read(data->regmap, HMC5843_DATA_OUT_MSB_REGS,
+ values, sizeof(values));
mutex_unlock(&data->lock);
- if (result < 0)
- return -EINVAL;
+ if (ret < 0)
+ return ret;
*val = sign_extend32(be16_to_cpu(values[idx]), 15);
return IIO_VAL_INT;
@@ -208,16 +207,13 @@ static int hmc5843_read_measurement(struct hmc5843_data *data,
* and BN.
*
*/
-static s32 hmc5843_set_meas_conf(struct hmc5843_data *data, u8 meas_conf)
+static int hmc5843_set_meas_conf(struct hmc5843_data *data, u8 meas_conf)
{
int ret;
mutex_lock(&data->lock);
- ret = i2c_smbus_write_byte_data(data->client, HMC5843_CONFIG_REG_A,
- (meas_conf & HMC5843_MEAS_CONF_MASK) |
- (data->rate << HMC5843_RATE_OFFSET));
- if (ret >= 0)
- data->meas_conf = meas_conf;
+ ret = regmap_update_bits(data->regmap, HMC5843_CONFIG_REG_A,
+ HMC5843_MEAS_CONF_MASK, meas_conf);
mutex_unlock(&data->lock);
return ret;
@@ -228,7 +224,15 @@ static ssize_t hmc5843_show_measurement_configuration(struct device *dev,
char *buf)
{
struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
- return sprintf(buf, "%d\n", data->meas_conf);
+ int val;
+ int ret;
+
+ ret = regmap_read(data->regmap, HMC5843_CONFIG_REG_A, &val);
+ if (ret)
+ return ret;
+ val &= HMC5843_MEAS_CONF_MASK;
+
+ return sprintf(buf, "%d\n", val);
}
static ssize_t hmc5843_set_measurement_configuration(struct device *dev,
@@ -282,10 +286,8 @@ static int hmc5843_set_samp_freq(struct hmc5843_data *data, u8 rate)
int ret;
mutex_lock(&data->lock);
- ret = i2c_smbus_write_byte_data(data->client, HMC5843_CONFIG_REG_A,
- data->meas_conf | (rate << HMC5843_RATE_OFFSET));
- if (ret >= 0)
- data->rate = rate;
+ ret = regmap_update_bits(data->regmap, HMC5843_CONFIG_REG_A,
+ HMC5843_RATE_MASK, rate << HMC5843_RATE_OFFSET);
mutex_unlock(&data->lock);
return ret;
@@ -309,10 +311,9 @@ static int hmc5843_set_range_gain(struct hmc5843_data *data, u8 range)
int ret;
mutex_lock(&data->lock);
- ret = i2c_smbus_write_byte_data(data->client, HMC5843_CONFIG_REG_B,
- range << HMC5843_RANGE_GAIN_OFFSET);
- if (ret >= 0)
- data->range = range;
+ ret = regmap_update_bits(data->regmap, HMC5843_CONFIG_REG_B,
+ HMC5843_RANGE_GAIN_MASK,
+ range << HMC5843_RANGE_GAIN_OFFSET);
mutex_unlock(&data->lock);
return ret;
@@ -358,17 +359,27 @@ static int hmc5843_read_raw(struct iio_dev *indio_dev,
int *val, int *val2, long mask)
{
struct hmc5843_data *data = iio_priv(indio_dev);
+ int rval;
+ int ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
return hmc5843_read_measurement(data, chan->scan_index, val);
case IIO_CHAN_INFO_SCALE:
+ ret = regmap_read(data->regmap, HMC5843_CONFIG_REG_B, &rval);
+ if (ret < 0)
+ return ret;
+ rval >>= HMC5843_RANGE_GAIN_OFFSET;
*val = 0;
- *val2 = data->variant->regval_to_nanoscale[data->range];
+ *val2 = data->variant->regval_to_nanoscale[rval];
return IIO_VAL_INT_PLUS_NANO;
case IIO_CHAN_INFO_SAMP_FREQ:
- *val = data->variant->regval_to_samp_freq[data->rate][0];
- *val2 = data->variant->regval_to_samp_freq[data->rate][1];
+ ret = regmap_read(data->regmap, HMC5843_CONFIG_REG_A, &rval);
+ if (ret < 0)
+ return ret;
+ rval >>= HMC5843_RATE_OFFSET;
+ *val = data->variant->regval_to_samp_freq[rval][0];
+ *val2 = data->variant->regval_to_samp_freq[rval][1];
return IIO_VAL_INT_PLUS_MICRO;
}
return -EINVAL;
@@ -426,9 +437,9 @@ static irqreturn_t hmc5843_trigger_handler(int irq, void *p)
goto done;
}
- ret = i2c_smbus_read_i2c_block_data(data->client,
- HMC5843_DATA_OUT_MSB_REGS, 3 * sizeof(__be16),
- (u8 *) data->buffer);
+ ret = regmap_bulk_read(data->regmap, HMC5843_DATA_OUT_MSB_REGS,
+ data->buffer, 3 * sizeof(__be16));
+
mutex_unlock(&data->lock);
if (ret < 0)
goto done;
@@ -508,8 +519,8 @@ static int hmc5843_init(struct hmc5843_data *data)
int ret;
u8 id[3];
- ret = i2c_smbus_read_i2c_block_data(data->client, HMC5843_ID_REG,
- sizeof(id), id);
+ ret = regmap_bulk_read(data->regmap, HMC5843_ID_REG,
+ id, ARRAY_SIZE(id));
if (ret < 0)
return ret;
if (id[0] != 'H' || id[1] != '4' || id[2] != '3') {
@@ -539,6 +550,44 @@ static const struct iio_info hmc5843_info = {
static const unsigned long hmc5843_scan_masks[] = {0x7, 0};
+static const struct regmap_range hmc5843_readable_ranges[] = {
+ regmap_reg_range(0, HMC5843_ID_END),
+};
+
+static struct regmap_access_table hmc5843_readable_table = {
+ .yes_ranges = hmc5843_readable_ranges,
+ .n_yes_ranges = ARRAY_SIZE(hmc5843_readable_ranges),
+};
+
+static const struct regmap_range hmc5843_writable_ranges[] = {
+ regmap_reg_range(0, HMC5843_MODE_REG),
+};
+
+static struct regmap_access_table hmc5843_writable_table = {
+ .yes_ranges = hmc5843_writable_ranges,
+ .n_yes_ranges = ARRAY_SIZE(hmc5843_writable_ranges),
+};
+
+static const struct regmap_range hmc5843_volatile_ranges[] = {
+ regmap_reg_range(HMC5843_DATA_OUT_MSB_REGS, HMC5843_STATUS_REG),
+};
+
+static struct regmap_access_table hmc5843_volatile_table = {
+ .yes_ranges = hmc5843_volatile_ranges,
+ .n_yes_ranges = ARRAY_SIZE(hmc5843_volatile_ranges),
+};
+
+static struct regmap_config hmc5843_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .rd_table = &hmc5843_readable_table,
+ .wr_table = &hmc5843_writable_table,
+ .volatile_table = &hmc5843_volatile_table,
+
+ .cache_type = REGCACHE_RBTREE,
+};
+
static int hmc5843_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -554,6 +603,7 @@ static int hmc5843_probe(struct i2c_client *client,
data = iio_priv(indio_dev);
data->client = client;
data->variant = &hmc5843_chip_info_tbl[id->driver_data];
+ data->regmap = devm_regmap_init_i2c(client, &hmc5843_regmap_config);
mutex_init(&data->lock);
i2c_set_clientdata(client, indio_dev);
--
1.8.5.5
next prev parent reply other threads:[~2014-07-08 13:38 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-08 13:37 [PATCH v3 0/5] staging:iio:hmc5843: Few adjustments and support for hmc5983 Josef Gajdusek
2014-07-08 13:38 ` Josef Gajdusek [this message]
2014-07-13 18:18 ` [PATCH v3 1/5] staging:iio:hmc5843: Added regmap support Jonathan Cameron
2014-07-08 13:39 ` [PATCH v3 2/5] staging:iio:hmc5843: Split hmc5843.c to multiple files Josef Gajdusek
2014-07-13 18:41 ` Jonathan Cameron
2014-07-14 16:31 ` Lars-Peter Clausen
2014-07-08 13:39 ` [PATCH v3 3/5] staging:iio:hmc5843: register <-> value arrays now can have different lengths Josef Gajdusek
2014-07-08 13:41 ` [PATCH v3 4/5] staging:iio:hmc5843: Add support for i2c hmc5983 Josef Gajdusek
2014-07-08 13:42 ` [PATCH v3 5/5] staging:iio:hmc5843: Add support for spi hmc5983 Josef Gajdusek
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=20140708133833.GC14393@dashie \
--to=atx@atalax.net \
--cc=dan.carpenter@oracle.com \
--cc=devel@driverdev.osuosl.org \
--cc=gregkh@linuxfoundation.org \
--cc=jic23@kernel.org \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pmeerw@pmeerw.net \
/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).