summaryrefslogtreecommitdiff
path: root/drivers/iio/magnetometer
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio/magnetometer')
-rw-r--r--drivers/iio/magnetometer/Kconfig11
-rw-r--r--drivers/iio/magnetometer/Makefile2
-rw-r--r--drivers/iio/magnetometer/af8133j.c4
-rw-r--r--drivers/iio/magnetometer/ak8974.c14
-rw-r--r--drivers/iio/magnetometer/ak8975.c8
-rw-r--r--drivers/iio/magnetometer/als31300.c7
-rw-r--r--drivers/iio/magnetometer/bmc150_magn.c4
-rw-r--r--drivers/iio/magnetometer/bmc150_magn_i2c.c2
-rw-r--r--drivers/iio/magnetometer/bmc150_magn_spi.c2
-rw-r--r--drivers/iio/magnetometer/hid-sensor-magn-3d.c2
-rw-r--r--drivers/iio/magnetometer/hmc5843.h2
-rw-r--r--drivers/iio/magnetometer/hmc5843_core.c4
-rw-r--r--drivers/iio/magnetometer/hmc5843_i2c.c2
-rw-r--r--drivers/iio/magnetometer/hmc5843_spi.c1
-rw-r--r--drivers/iio/magnetometer/mag3110.c165
-rw-r--r--drivers/iio/magnetometer/mmc35240.c4
-rw-r--r--drivers/iio/magnetometer/rm3100-core.c11
-rw-r--r--drivers/iio/magnetometer/rm3100-spi.c1
-rw-r--r--drivers/iio/magnetometer/si7210.c446
-rw-r--r--drivers/iio/magnetometer/st_magn_i2c.c4
-rw-r--r--drivers/iio/magnetometer/st_magn_spi.c4
-rw-r--r--drivers/iio/magnetometer/tmag5273.c4
-rw-r--r--drivers/iio/magnetometer/yamaha-yas530.c8
23 files changed, 581 insertions, 131 deletions
diff --git a/drivers/iio/magnetometer/Kconfig b/drivers/iio/magnetometer/Kconfig
index 7177cd1d67cb..3debf1320ad1 100644
--- a/drivers/iio/magnetometer/Kconfig
+++ b/drivers/iio/magnetometer/Kconfig
@@ -235,6 +235,17 @@ config SENSORS_RM3100_SPI
To compile this driver as a module, choose M here: the module
will be called rm3100-spi.
+config SI7210
+ tristate "SI7210 Hall effect sensor"
+ depends on I2C
+ select REGMAP_I2C
+ help
+ Say Y here to add support for the SI7210 Hall effect sensor.
+
+ This driver can also be compiled as a module.
+ To compile this driver as a module, choose M here: the module
+ will be called si7210.
+
config TI_TMAG5273
tristate "TI TMAG5273 Low-Power Linear 3D Hall-Effect Sensor"
depends on I2C
diff --git a/drivers/iio/magnetometer/Makefile b/drivers/iio/magnetometer/Makefile
index 3e4c2ecd9adf..9297723a97d8 100644
--- a/drivers/iio/magnetometer/Makefile
+++ b/drivers/iio/magnetometer/Makefile
@@ -31,6 +31,8 @@ obj-$(CONFIG_SENSORS_RM3100) += rm3100-core.o
obj-$(CONFIG_SENSORS_RM3100_I2C) += rm3100-i2c.o
obj-$(CONFIG_SENSORS_RM3100_SPI) += rm3100-spi.o
+obj-$(CONFIG_SI7210) += si7210.o
+
obj-$(CONFIG_TI_TMAG5273) += tmag5273.o
obj-$(CONFIG_YAMAHA_YAS530) += yamaha-yas530.o
diff --git a/drivers/iio/magnetometer/af8133j.c b/drivers/iio/magnetometer/af8133j.c
index a70bf8a3c73b..192ba2da94e2 100644
--- a/drivers/iio/magnetometer/af8133j.c
+++ b/drivers/iio/magnetometer/af8133j.c
@@ -370,7 +370,8 @@ static irqreturn_t af8133j_trigger_handler(int irq, void *p)
if (ret)
goto out_done;
- iio_push_to_buffers_with_timestamp(indio_dev, &sample, timestamp);
+ iio_push_to_buffers_with_ts(indio_dev, &sample, sizeof(sample),
+ timestamp);
out_done:
iio_trigger_notify_done(indio_dev->trig);
@@ -383,7 +384,6 @@ static const struct regmap_config af8133j_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = AF8133J_REG_SWR,
- .cache_type = REGCACHE_NONE,
};
static void af8133j_power_down_action(void *ptr)
diff --git a/drivers/iio/magnetometer/ak8974.c b/drivers/iio/magnetometer/ak8974.c
index 08975c60e325..947fe8a475f2 100644
--- a/drivers/iio/magnetometer/ak8974.c
+++ b/drivers/iio/magnetometer/ak8974.c
@@ -535,8 +535,8 @@ static int ak8974_detect(struct ak8974 *ak8974)
fab_data2, sizeof(fab_data2));
for (i = 0; i < 3; ++i) {
- static const char axis[3] = "XYZ";
- static const char pgaxis[6] = "ZYZXYX";
+ static const char axis[] = "XYZ";
+ static const char pgaxis[] = "ZYZXYX";
unsigned offz = le16_to_cpu(fab_data2[i]) & 0x7F;
unsigned fine = le16_to_cpu(fab_data1[i]);
unsigned sens = le16_to_cpu(fab_data1[i + 3]);
@@ -673,8 +673,8 @@ static void ak8974_fill_buffer(struct iio_dev *indio_dev)
goto out_unlock;
}
- iio_push_to_buffers_with_timestamp(indio_dev, &ak8974->scan,
- iio_get_time_ns(indio_dev));
+ iio_push_to_buffers_with_ts(indio_dev, &ak8974->scan, sizeof(ak8974->scan),
+ iio_get_time_ns(indio_dev));
out_unlock:
mutex_unlock(&ak8974->lock);
@@ -704,7 +704,7 @@ ak8974_get_mount_matrix(const struct iio_dev *indio_dev,
static const struct iio_chan_spec_ext_info ak8974_ext_info[] = {
IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, ak8974_get_mount_matrix),
- { },
+ { }
};
#define AK8974_AXIS_CHANNEL(axis, index, bits) \
@@ -1023,14 +1023,14 @@ static const struct i2c_device_id ak8974_id[] = {
{ "ami306" },
{ "ak8974" },
{ "hscdtd008a" },
- {}
+ { }
};
MODULE_DEVICE_TABLE(i2c, ak8974_id);
static const struct of_device_id ak8974_of_match[] = {
{ .compatible = "asahi-kasei,ak8974", },
{ .compatible = "alps,hscdtd008a", },
- {}
+ { }
};
MODULE_DEVICE_TABLE(of, ak8974_of_match);
diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c
index ef1363126cc2..a1e92b2abffd 100644
--- a/drivers/iio/magnetometer/ak8975.c
+++ b/drivers/iio/magnetometer/ak8975.c
@@ -882,8 +882,8 @@ static void ak8975_fill_buffer(struct iio_dev *indio_dev)
data->scan.channels[1] = clamp_t(s16, le16_to_cpu(fval[1]), -def->range, def->range);
data->scan.channels[2] = clamp_t(s16, le16_to_cpu(fval[2]), -def->range, def->range);
- iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
- iio_get_time_ns(indio_dev));
+ iio_push_to_buffers_with_ts(indio_dev, &data->scan, sizeof(data->scan),
+ iio_get_time_ns(indio_dev));
return;
@@ -1107,7 +1107,7 @@ static const struct i2c_device_id ak8975_id[] = {
{"ak09912", (kernel_ulong_t)&ak_def_array[AK09912] },
{"ak09916", (kernel_ulong_t)&ak_def_array[AK09916] },
{"ak09918", (kernel_ulong_t)&ak_def_array[AK09918] },
- {}
+ { }
};
MODULE_DEVICE_TABLE(i2c, ak8975_id);
@@ -1122,7 +1122,7 @@ static const struct of_device_id ak8975_of_match[] = {
{ .compatible = "ak09912", .data = &ak_def_array[AK09912] },
{ .compatible = "asahi-kasei,ak09916", .data = &ak_def_array[AK09916] },
{ .compatible = "asahi-kasei,ak09918", .data = &ak_def_array[AK09918] },
- {}
+ { }
};
MODULE_DEVICE_TABLE(of, ak8975_of_match);
diff --git a/drivers/iio/magnetometer/als31300.c b/drivers/iio/magnetometer/als31300.c
index 87b60c4e81fa..f72af829715f 100644
--- a/drivers/iio/magnetometer/als31300.c
+++ b/drivers/iio/magnetometer/als31300.c
@@ -245,8 +245,7 @@ static irqreturn_t als31300_trigger_handler(int irq, void *p)
scan.channels[0] = x;
scan.channels[1] = y;
scan.channels[2] = z;
- iio_push_to_buffers_with_timestamp(indio_dev, &scan,
- pf->timestamp);
+ iio_push_to_buffers_with_ts(indio_dev, &scan, sizeof(scan), pf->timestamp);
trigger_out:
iio_trigger_notify_done(indio_dev->trig);
@@ -457,7 +456,7 @@ static const struct i2c_device_id als31300_id[] = {
.name = "als31300-2000",
.driver_data = (kernel_ulong_t)&al31300_variant_2000,
},
- { /* sentinel */ }
+ { }
};
MODULE_DEVICE_TABLE(i2c, als31300_id);
@@ -474,7 +473,7 @@ static const struct of_device_id als31300_of_match[] = {
.compatible = "allegromicro,als31300-2000",
.data = &al31300_variant_2000,
},
- { /* sentinel */ }
+ { }
};
MODULE_DEVICE_TABLE(of, als31300_of_match);
diff --git a/drivers/iio/magnetometer/bmc150_magn.c b/drivers/iio/magnetometer/bmc150_magn.c
index 88bb673e40d8..f9c51ceae011 100644
--- a/drivers/iio/magnetometer/bmc150_magn.c
+++ b/drivers/iio/magnetometer/bmc150_magn.c
@@ -678,8 +678,8 @@ static irqreturn_t bmc150_magn_trigger_handler(int irq, void *p)
if (ret < 0)
goto err;
- iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
- pf->timestamp);
+ iio_push_to_buffers_with_ts(indio_dev, &data->scan, sizeof(data->scan),
+ pf->timestamp);
err:
mutex_unlock(&data->mutex);
diff --git a/drivers/iio/magnetometer/bmc150_magn_i2c.c b/drivers/iio/magnetometer/bmc150_magn_i2c.c
index 8cbeda924bda..b110791f688a 100644
--- a/drivers/iio/magnetometer/bmc150_magn_i2c.c
+++ b/drivers/iio/magnetometer/bmc150_magn_i2c.c
@@ -42,7 +42,7 @@ static const struct i2c_device_id bmc150_magn_i2c_id[] = {
{ "bmc150_magn" },
{ "bmc156_magn" },
{ "bmm150_magn" },
- {}
+ { }
};
MODULE_DEVICE_TABLE(i2c, bmc150_magn_i2c_id);
diff --git a/drivers/iio/magnetometer/bmc150_magn_spi.c b/drivers/iio/magnetometer/bmc150_magn_spi.c
index 2d4b8cba32f1..896b1d280731 100644
--- a/drivers/iio/magnetometer/bmc150_magn_spi.c
+++ b/drivers/iio/magnetometer/bmc150_magn_spi.c
@@ -37,7 +37,7 @@ static const struct spi_device_id bmc150_magn_spi_id[] = {
{"bmc150_magn", 0},
{"bmc156_magn", 0},
{"bmm150_magn", 0},
- {}
+ { }
};
MODULE_DEVICE_TABLE(spi, bmc150_magn_spi_id);
diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index 97ddaa2a03f6..c673f9323e47 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -563,7 +563,7 @@ static const struct platform_device_id hid_magn_3d_ids[] = {
/* Format: HID-SENSOR-usage_id_in_hex_lowercase */
.name = "HID-SENSOR-200083",
},
- { /* sentinel */ }
+ { }
};
MODULE_DEVICE_TABLE(platform, hid_magn_3d_ids);
diff --git a/drivers/iio/magnetometer/hmc5843.h b/drivers/iio/magnetometer/hmc5843.h
index ffd669b1ee7c..7a3faf7ffed4 100644
--- a/drivers/iio/magnetometer/hmc5843.h
+++ b/drivers/iio/magnetometer/hmc5843.h
@@ -34,7 +34,7 @@ enum hmc5843_ids {
* @regmap: hardware access register maps
* @variant: describe chip variants
* @scan: buffer to pack data for passing to
- * iio_push_to_buffers_with_timestamp()
+ * iio_push_to_buffers_with_ts()
*/
struct hmc5843_data {
struct device *dev;
diff --git a/drivers/iio/magnetometer/hmc5843_core.c b/drivers/iio/magnetometer/hmc5843_core.c
index 2fc84310e2cc..fc16ebd314f7 100644
--- a/drivers/iio/magnetometer/hmc5843_core.c
+++ b/drivers/iio/magnetometer/hmc5843_core.c
@@ -452,8 +452,8 @@ static irqreturn_t hmc5843_trigger_handler(int irq, void *p)
if (ret < 0)
goto done;
- iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
- iio_get_time_ns(indio_dev));
+ iio_push_to_buffers_with_ts(indio_dev, &data->scan, sizeof(data->scan),
+ iio_get_time_ns(indio_dev));
done:
iio_trigger_notify_done(indio_dev->trig);
diff --git a/drivers/iio/magnetometer/hmc5843_i2c.c b/drivers/iio/magnetometer/hmc5843_i2c.c
index 657a309e2bd5..b41709959e2b 100644
--- a/drivers/iio/magnetometer/hmc5843_i2c.c
+++ b/drivers/iio/magnetometer/hmc5843_i2c.c
@@ -84,7 +84,7 @@ static const struct of_device_id hmc5843_of_match[] = {
{ .compatible = "honeywell,hmc5883", .data = (void *)HMC5883_ID },
{ .compatible = "honeywell,hmc5883l", .data = (void *)HMC5883L_ID },
{ .compatible = "honeywell,hmc5983", .data = (void *)HMC5983_ID },
- {}
+ { }
};
MODULE_DEVICE_TABLE(of, hmc5843_of_match);
diff --git a/drivers/iio/magnetometer/hmc5843_spi.c b/drivers/iio/magnetometer/hmc5843_spi.c
index b7fde331069d..6a55c1559b0d 100644
--- a/drivers/iio/magnetometer/hmc5843_spi.c
+++ b/drivers/iio/magnetometer/hmc5843_spi.c
@@ -60,7 +60,6 @@ static int hmc5843_spi_probe(struct spi_device *spi)
spi->mode = SPI_MODE_3;
spi->max_speed_hz = 8000000;
- spi->bits_per_word = 8;
ret = spi_setup(spi);
if (ret)
return ret;
diff --git a/drivers/iio/magnetometer/mag3110.c b/drivers/iio/magnetometer/mag3110.c
index 2fe8e97f2cf8..ff09250a06e7 100644
--- a/drivers/iio/magnetometer/mag3110.c
+++ b/drivers/iio/magnetometer/mag3110.c
@@ -9,6 +9,7 @@
* TODO: irq, user offset, oversampling, continuous mode
*/
+#include <linux/cleanup.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/iio/iio.h>
@@ -102,17 +103,12 @@ static int mag3110_read(struct mag3110_data *data, __be16 buf[3])
{
int ret;
- mutex_lock(&data->lock);
+ guard(mutex)(&data->lock);
ret = mag3110_request(data);
- if (ret < 0) {
- mutex_unlock(&data->lock);
+ if (ret < 0)
return ret;
- }
- ret = i2c_smbus_read_i2c_block_data(data->client,
- MAG3110_OUT_X, 3 * sizeof(__be16), (u8 *) buf);
- mutex_unlock(&data->lock);
-
- return ret;
+ return i2c_smbus_read_i2c_block_data(data->client, MAG3110_OUT_X,
+ 3 * sizeof(__be16), (u8 *) buf);
}
static ssize_t mag3110_show_int_plus_micros(char *buf,
@@ -231,19 +227,17 @@ static int mag3110_change_config(struct mag3110_data *data, u8 reg, u8 val)
int ret;
int is_active;
- mutex_lock(&data->lock);
+ guard(mutex)(&data->lock);
is_active = mag3110_is_active(data);
- if (is_active < 0) {
- ret = is_active;
- goto fail;
- }
+ if (is_active < 0)
+ return is_active;
/* config can only be changed when in standby */
if (is_active > 0) {
ret = mag3110_standby(data);
if (ret < 0)
- goto fail;
+ return ret;
}
/*
@@ -252,23 +246,52 @@ static int mag3110_change_config(struct mag3110_data *data, u8 reg, u8 val)
*/
ret = mag3110_wait_standby(data);
if (ret < 0)
- goto fail;
+ return ret;
ret = i2c_smbus_write_byte_data(data->client, reg, val);
if (ret < 0)
- goto fail;
+ return ret;
if (is_active > 0) {
ret = mag3110_active(data);
if (ret < 0)
- goto fail;
+ return ret;
}
- ret = 0;
-fail:
- mutex_unlock(&data->lock);
+ return 0;
+}
- return ret;
+static int __mag3110_read_info_raw(struct mag3110_data *data,
+ struct iio_chan_spec const *chan,
+ int *val)
+{
+ __be16 buffer[3];
+ int ret;
+
+ switch (chan->type) {
+ case IIO_MAGN: /* in 0.1 uT / LSB */
+ ret = mag3110_read(data, buffer);
+ if (ret < 0)
+ return ret;
+ *val = sign_extend32(be16_to_cpu(buffer[chan->scan_index]),
+ chan->scan_type.realbits - 1);
+ return IIO_VAL_INT;
+
+ case IIO_TEMP: { /* in 1 C / LSB */
+ guard(mutex)(&data->lock);
+ ret = mag3110_request(data);
+ if (ret < 0)
+ return ret;
+ ret = i2c_smbus_read_byte_data(data->client,
+ MAG3110_DIE_TEMP);
+ if (ret < 0)
+ return ret;
+ *val = sign_extend32(ret, chan->scan_type.realbits - 1);
+ return IIO_VAL_INT;
+ }
+ default:
+ return -EINVAL;
+ }
}
static int mag3110_read_raw(struct iio_dev *indio_dev,
@@ -276,46 +299,14 @@ static int mag3110_read_raw(struct iio_dev *indio_dev,
int *val, int *val2, long mask)
{
struct mag3110_data *data = iio_priv(indio_dev);
- __be16 buffer[3];
int i, ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
- ret = iio_device_claim_direct_mode(indio_dev);
- if (ret)
- return ret;
-
- switch (chan->type) {
- case IIO_MAGN: /* in 0.1 uT / LSB */
- ret = mag3110_read(data, buffer);
- if (ret < 0)
- goto release;
- *val = sign_extend32(
- be16_to_cpu(buffer[chan->scan_index]),
- chan->scan_type.realbits - 1);
- ret = IIO_VAL_INT;
- break;
- case IIO_TEMP: /* in 1 C / LSB */
- mutex_lock(&data->lock);
- ret = mag3110_request(data);
- if (ret < 0) {
- mutex_unlock(&data->lock);
- goto release;
- }
- ret = i2c_smbus_read_byte_data(data->client,
- MAG3110_DIE_TEMP);
- mutex_unlock(&data->lock);
- if (ret < 0)
- goto release;
- *val = sign_extend32(ret,
- chan->scan_type.realbits - 1);
- ret = IIO_VAL_INT;
- break;
- default:
- ret = -EINVAL;
- }
-release:
- iio_device_release_direct_mode(indio_dev);
+ if (!iio_device_claim_direct(indio_dev))
+ return -EBUSY;
+ ret = __mag3110_read_info_raw(data, chan, val);
+ iio_device_release_direct(indio_dev);
return ret;
case IIO_CHAN_INFO_SCALE:
@@ -346,24 +337,18 @@ release:
return -EINVAL;
}
-static int mag3110_write_raw(struct iio_dev *indio_dev,
- struct iio_chan_spec const *chan,
- int val, int val2, long mask)
+static int __mag3110_write_raw(struct mag3110_data *data,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
{
- struct mag3110_data *data = iio_priv(indio_dev);
- int rate, ret;
-
- ret = iio_device_claim_direct_mode(indio_dev);
- if (ret)
- return ret;
+ int rate;
switch (mask) {
case IIO_CHAN_INFO_SAMP_FREQ:
rate = mag3110_get_samp_freq_index(data, val, val2);
- if (rate < 0) {
- ret = -EINVAL;
- break;
- }
+ if (rate < 0)
+ return -EINVAL;
+
data->ctrl_reg1 &= 0xff & ~MAG3110_CTRL_DR_MASK
& ~MAG3110_CTRL_AC;
data->ctrl_reg1 |= rate << MAG3110_CTRL_DR_SHIFT;
@@ -371,22 +356,32 @@ static int mag3110_write_raw(struct iio_dev *indio_dev,
if (data->sleep_val < 40)
data->ctrl_reg1 |= MAG3110_CTRL_AC;
- ret = mag3110_change_config(data, MAG3110_CTRL_REG1,
- data->ctrl_reg1);
- break;
+ return mag3110_change_config(data, MAG3110_CTRL_REG1,
+ data->ctrl_reg1);
+
case IIO_CHAN_INFO_CALIBBIAS:
- if (val < -10000 || val > 10000) {
- ret = -EINVAL;
- break;
- }
- ret = i2c_smbus_write_word_swapped(data->client,
+ if (val < -10000 || val > 10000)
+ return -EINVAL;
+
+ return i2c_smbus_write_word_swapped(data->client,
MAG3110_OFF_X + 2 * chan->scan_index, val << 1);
- break;
default:
- ret = -EINVAL;
- break;
+ return -EINVAL;
}
- iio_device_release_direct_mode(indio_dev);
+}
+
+static int mag3110_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
+{
+ struct mag3110_data *data = iio_priv(indio_dev);
+ int ret;
+
+ if (!iio_device_claim_direct(indio_dev))
+ return -EBUSY;
+ ret = __mag3110_write_raw(data, chan, val, val2, mask);
+ iio_device_release_direct(indio_dev);
+
return ret;
}
@@ -409,8 +404,8 @@ static irqreturn_t mag3110_trigger_handler(int irq, void *p)
data->scan.temperature = ret;
}
- iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
- iio_get_time_ns(indio_dev));
+ iio_push_to_buffers_with_ts(indio_dev, &data->scan, sizeof(data->scan),
+ iio_get_time_ns(indio_dev));
done:
iio_trigger_notify_done(indio_dev->trig);
diff --git a/drivers/iio/magnetometer/mmc35240.c b/drivers/iio/magnetometer/mmc35240.c
index dd480a4a5f98..e08a57cd6de2 100644
--- a/drivers/iio/magnetometer/mmc35240.c
+++ b/drivers/iio/magnetometer/mmc35240.c
@@ -556,13 +556,13 @@ MODULE_DEVICE_TABLE(of, mmc35240_of_match);
static const struct acpi_device_id mmc35240_acpi_match[] = {
{"MMC35240", 0},
- { },
+ { }
};
MODULE_DEVICE_TABLE(acpi, mmc35240_acpi_match);
static const struct i2c_device_id mmc35240_id[] = {
{ "mmc35240" },
- {}
+ { }
};
MODULE_DEVICE_TABLE(i2c, mmc35240_id);
diff --git a/drivers/iio/magnetometer/rm3100-core.c b/drivers/iio/magnetometer/rm3100-core.c
index c99694a77a14..2b2884425746 100644
--- a/drivers/iio/magnetometer/rm3100-core.c
+++ b/drivers/iio/magnetometer/rm3100-core.c
@@ -399,12 +399,11 @@ static int rm3100_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
- ret = iio_device_claim_direct_mode(indio_dev);
- if (ret < 0)
- return ret;
+ if (!iio_device_claim_direct(indio_dev))
+ return -EBUSY;
ret = rm3100_read_mag(data, chan->scan_index, val);
- iio_device_release_direct_mode(indio_dev);
+ iio_device_release_direct(indio_dev);
return ret;
case IIO_CHAN_INFO_SCALE:
@@ -516,8 +515,8 @@ static irqreturn_t rm3100_trigger_handler(int irq, void *p)
* Always using the same buffer so that we wouldn't need to set the
* paddings to 0 in case of leaking any data.
*/
- iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
- pf->timestamp);
+ iio_push_to_buffers_with_ts(indio_dev, data->buffer, sizeof(data->buffer),
+ pf->timestamp);
done:
iio_trigger_notify_done(indio_dev->trig);
diff --git a/drivers/iio/magnetometer/rm3100-spi.c b/drivers/iio/magnetometer/rm3100-spi.c
index dd6d48043740..2f60a41c07f7 100644
--- a/drivers/iio/magnetometer/rm3100-spi.c
+++ b/drivers/iio/magnetometer/rm3100-spi.c
@@ -32,7 +32,6 @@ static int rm3100_probe(struct spi_device *spi)
spi->mode = SPI_MODE_0;
/* Data rates cannot exceed 1Mbits. */
spi->max_speed_hz = 1000000;
- spi->bits_per_word = 8;
ret = spi_setup(spi);
if (ret)
return ret;
diff --git a/drivers/iio/magnetometer/si7210.c b/drivers/iio/magnetometer/si7210.c
new file mode 100644
index 000000000000..27e3feba7a0f
--- /dev/null
+++ b/drivers/iio/magnetometer/si7210.c
@@ -0,0 +1,446 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Silicon Labs Si7210 Hall Effect sensor driver
+ *
+ * Copyright (c) 2024 Antoni Pokusinski <apokusinski01@gmail.com>
+ *
+ * Datasheet:
+ * https://www.silabs.com/documents/public/data-sheets/si7210-datasheet.pdf
+ */
+
+#include <linux/array_size.h>
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/cleanup.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/iio/iio.h>
+#include <linux/math64.h>
+#include <linux/mod_devicetable.h>
+#include <linux/mutex.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/types.h>
+#include <linux/units.h>
+#include <asm/byteorder.h>
+
+/* Registers offsets and masks */
+#define SI7210_REG_DSPSIGM 0xC1
+#define SI7210_REG_DSPSIGL 0xC2
+
+#define SI7210_MASK_DSPSIGSEL GENMASK(2, 0)
+#define SI7210_REG_DSPSIGSEL 0xC3
+
+#define SI7210_MASK_STOP BIT(1)
+#define SI7210_MASK_ONEBURST BIT(2)
+#define SI7210_REG_POWER_CTRL 0xC4
+
+#define SI7210_MASK_ARAUTOINC BIT(0)
+#define SI7210_REG_ARAUTOINC 0xC5
+
+#define SI7210_REG_A0 0xCA
+#define SI7210_REG_A1 0xCB
+#define SI7210_REG_A2 0xCC
+#define SI7210_REG_A3 0xCE
+#define SI7210_REG_A4 0xCF
+#define SI7210_REG_A5 0xD0
+
+#define SI7210_REG_OTP_ADDR 0xE1
+#define SI7210_REG_OTP_DATA 0xE2
+
+#define SI7210_MASK_OTP_READ_EN BIT(1)
+#define SI7210_REG_OTP_CTRL 0xE3
+
+/* OTP data registers offsets */
+#define SI7210_OTPREG_TMP_OFF 0x1D
+#define SI7210_OTPREG_TMP_GAIN 0x1E
+
+#define SI7210_OTPREG_A0_20 0x21
+#define SI7210_OTPREG_A1_20 0x22
+#define SI7210_OTPREG_A2_20 0x23
+#define SI7210_OTPREG_A3_20 0x24
+#define SI7210_OTPREG_A4_20 0x25
+#define SI7210_OTPREG_A5_20 0x26
+
+#define SI7210_OTPREG_A0_200 0x27
+#define SI7210_OTPREG_A1_200 0x28
+#define SI7210_OTPREG_A2_200 0x29
+#define SI7210_OTPREG_A3_200 0x2A
+#define SI7210_OTPREG_A4_200 0x2B
+#define SI7210_OTPREG_A5_200 0x2C
+
+#define A_REGS_COUNT 6
+
+static const unsigned int a20_otp_regs[A_REGS_COUNT] = {
+ SI7210_OTPREG_A0_20, SI7210_OTPREG_A1_20, SI7210_OTPREG_A2_20,
+ SI7210_OTPREG_A3_20, SI7210_OTPREG_A4_20, SI7210_OTPREG_A5_20,
+};
+
+static const unsigned int a200_otp_regs[A_REGS_COUNT] = {
+ SI7210_OTPREG_A0_200, SI7210_OTPREG_A1_200, SI7210_OTPREG_A2_200,
+ SI7210_OTPREG_A3_200, SI7210_OTPREG_A4_200, SI7210_OTPREG_A5_200,
+};
+
+static const struct regmap_range si7210_read_reg_ranges[] = {
+ regmap_reg_range(SI7210_REG_DSPSIGM, SI7210_REG_ARAUTOINC),
+ regmap_reg_range(SI7210_REG_A0, SI7210_REG_A2),
+ regmap_reg_range(SI7210_REG_A3, SI7210_REG_A5),
+ regmap_reg_range(SI7210_REG_OTP_ADDR, SI7210_REG_OTP_CTRL),
+};
+
+static const struct regmap_access_table si7210_readable_regs = {
+ .yes_ranges = si7210_read_reg_ranges,
+ .n_yes_ranges = ARRAY_SIZE(si7210_read_reg_ranges),
+};
+
+static const struct regmap_range si7210_write_reg_ranges[] = {
+ regmap_reg_range(SI7210_REG_DSPSIGSEL, SI7210_REG_ARAUTOINC),
+ regmap_reg_range(SI7210_REG_A0, SI7210_REG_A2),
+ regmap_reg_range(SI7210_REG_A3, SI7210_REG_A5),
+ regmap_reg_range(SI7210_REG_OTP_ADDR, SI7210_REG_OTP_CTRL),
+};
+
+static const struct regmap_access_table si7210_writeable_regs = {
+ .yes_ranges = si7210_write_reg_ranges,
+ .n_yes_ranges = ARRAY_SIZE(si7210_write_reg_ranges),
+};
+
+static const struct regmap_range si7210_volatile_reg_ranges[] = {
+ regmap_reg_range(SI7210_REG_DSPSIGM, SI7210_REG_DSPSIGL),
+ regmap_reg_range(SI7210_REG_POWER_CTRL, SI7210_REG_POWER_CTRL),
+};
+
+static const struct regmap_access_table si7210_volatile_regs = {
+ .yes_ranges = si7210_volatile_reg_ranges,
+ .n_yes_ranges = ARRAY_SIZE(si7210_volatile_reg_ranges),
+};
+
+static const struct regmap_config si7210_regmap_conf = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = SI7210_REG_OTP_CTRL,
+
+ .rd_table = &si7210_readable_regs,
+ .wr_table = &si7210_writeable_regs,
+ .volatile_table = &si7210_volatile_regs,
+};
+
+struct si7210_data {
+ struct regmap *regmap;
+ struct i2c_client *client;
+ struct regulator *vdd;
+ struct mutex fetch_lock; /* lock for a single measurement fetch */
+ s8 temp_offset;
+ s8 temp_gain;
+ s8 scale_20_a[A_REGS_COUNT];
+ s8 scale_200_a[A_REGS_COUNT];
+ u8 curr_scale;
+};
+
+static const struct iio_chan_spec si7210_channels[] = {
+ {
+ .type = IIO_MAGN,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET),
+ }, {
+ .type = IIO_TEMP,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+ },
+};
+
+static int si7210_fetch_measurement(struct si7210_data *data,
+ struct iio_chan_spec const *chan,
+ u16 *buf)
+{
+ u8 dspsigsel = chan->type == IIO_MAGN ? 0 : 1;
+ int ret;
+ __be16 result;
+
+ guard(mutex)(&data->fetch_lock);
+
+ ret = regmap_update_bits(data->regmap, SI7210_REG_DSPSIGSEL,
+ SI7210_MASK_DSPSIGSEL, dspsigsel);
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(data->regmap, SI7210_REG_POWER_CTRL,
+ SI7210_MASK_ONEBURST | SI7210_MASK_STOP,
+ SI7210_MASK_ONEBURST & ~SI7210_MASK_STOP);
+ if (ret)
+ return ret;
+
+ /*
+ * Read the contents of the
+ * registers containing the result: DSPSIGM, DSPSIGL
+ */
+ ret = regmap_bulk_read(data->regmap, SI7210_REG_DSPSIGM,
+ &result, sizeof(result));
+ if (ret)
+ return ret;
+
+ *buf = be16_to_cpu(result);
+
+ return 0;
+}
+
+static int si7210_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct si7210_data *data = iio_priv(indio_dev);
+ long long temp;
+ u16 dspsig;
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ ret = si7210_fetch_measurement(data, chan, &dspsig);
+ if (ret)
+ return ret;
+
+ *val = dspsig & GENMASK(14, 0);
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ *val = 0;
+ if (data->curr_scale == 20)
+ *val2 = 12500;
+ else /* data->curr_scale == 200 */
+ *val2 = 125000;
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_OFFSET:
+ *val = -16384;
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_PROCESSED:
+ ret = si7210_fetch_measurement(data, chan, &dspsig);
+ if (ret)
+ return ret;
+
+ /* temp = 32 * Dspsigm[6:0] + (Dspsigl[7:0] >> 3) */
+ temp = FIELD_GET(GENMASK(14, 3), dspsig);
+ temp = div_s64(-383 * temp * temp, 100) + 160940 * temp - 279800000;
+ temp *= (1 + (data->temp_gain / 2048));
+ temp += (int)(MICRO / 16) * data->temp_offset;
+
+ ret = regulator_get_voltage(data->vdd);
+ if (ret < 0)
+ return ret;
+
+ /* temp -= 0.222 * VDD */
+ temp -= 222 * div_s64(ret, MILLI);
+
+ *val = div_s64(temp, MILLI);
+
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int si7210_set_scale(struct si7210_data *data, unsigned int scale)
+{
+ s8 *a_otp_values;
+ int ret;
+
+ if (scale == 20)
+ a_otp_values = data->scale_20_a;
+ else if (scale == 200)
+ a_otp_values = data->scale_200_a;
+ else
+ return -EINVAL;
+
+ guard(mutex)(&data->fetch_lock);
+
+ /* Write the registers 0xCA - 0xCC */
+ ret = regmap_bulk_write(data->regmap, SI7210_REG_A0, a_otp_values, 3);
+ if (ret)
+ return ret;
+
+ /* Write the registers 0xCE - 0xD0 */
+ ret = regmap_bulk_write(data->regmap, SI7210_REG_A3, &a_otp_values[3], 3);
+ if (ret)
+ return ret;
+
+ data->curr_scale = scale;
+
+ return 0;
+}
+
+static int si7210_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
+{
+ struct si7210_data *data = iio_priv(indio_dev);
+ unsigned int scale;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SCALE:
+ if (val == 0 && val2 == 12500)
+ scale = 20;
+ else if (val == 0 && val2 == 125000)
+ scale = 200;
+ else
+ return -EINVAL;
+
+ return si7210_set_scale(data, scale);
+ default:
+ return -EINVAL;
+ }
+}
+
+static int si7210_read_otpreg_val(struct si7210_data *data, unsigned int otpreg, u8 *val)
+{
+ int ret;
+ unsigned int otpdata;
+
+ ret = regmap_write(data->regmap, SI7210_REG_OTP_ADDR, otpreg);
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(data->regmap, SI7210_REG_OTP_CTRL,
+ SI7210_MASK_OTP_READ_EN, SI7210_MASK_OTP_READ_EN);
+ if (ret)
+ return ret;
+
+ ret = regmap_read(data->regmap, SI7210_REG_OTP_DATA, &otpdata);
+ if (ret)
+ return ret;
+
+ *val = otpdata;
+
+ return 0;
+}
+
+/*
+ * According to the datasheet, the primary method to wake up a
+ * device is to send an empty write. However this is not feasible
+ * using the current API so we use the other method i.e. read a single
+ * byte. The device should respond with 0xFF.
+ */
+static int si7210_device_wake(struct si7210_data *data)
+{
+ int ret;
+
+ ret = i2c_smbus_read_byte(data->client);
+ if (ret < 0)
+ return ret;
+
+ if (ret != 0xFF)
+ return -EIO;
+
+ return 0;
+}
+
+static int si7210_device_init(struct si7210_data *data)
+{
+ int ret;
+ unsigned int i;
+
+ ret = si7210_device_wake(data);
+ if (ret)
+ return ret;
+
+ fsleep(1000);
+
+ ret = si7210_read_otpreg_val(data, SI7210_OTPREG_TMP_GAIN, &data->temp_gain);
+ if (ret)
+ return ret;
+
+ ret = si7210_read_otpreg_val(data, SI7210_OTPREG_TMP_OFF, &data->temp_offset);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < A_REGS_COUNT; i++) {
+ ret = si7210_read_otpreg_val(data, a20_otp_regs[i], &data->scale_20_a[i]);
+ if (ret)
+ return ret;
+ }
+
+ for (i = 0; i < A_REGS_COUNT; i++) {
+ ret = si7210_read_otpreg_val(data, a200_otp_regs[i], &data->scale_200_a[i]);
+ if (ret)
+ return ret;
+ }
+
+ ret = regmap_update_bits(data->regmap, SI7210_REG_ARAUTOINC,
+ SI7210_MASK_ARAUTOINC, SI7210_MASK_ARAUTOINC);
+ if (ret)
+ return ret;
+
+ return si7210_set_scale(data, 20);
+}
+
+static const struct iio_info si7210_info = {
+ .read_raw = si7210_read_raw,
+ .write_raw = si7210_write_raw,
+};
+
+static int si7210_probe(struct i2c_client *client)
+{
+ struct si7210_data *data;
+ struct iio_dev *indio_dev;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ data = iio_priv(indio_dev);
+ data->client = client;
+
+ ret = devm_mutex_init(&client->dev, &data->fetch_lock);
+ if (ret)
+ return ret;
+
+ data->regmap = devm_regmap_init_i2c(client, &si7210_regmap_conf);
+ if (IS_ERR(data->regmap))
+ return dev_err_probe(&client->dev, PTR_ERR(data->regmap),
+ "failed to register regmap\n");
+
+ data->vdd = devm_regulator_get(&client->dev, "vdd");
+ if (IS_ERR(data->vdd))
+ return dev_err_probe(&client->dev, PTR_ERR(data->vdd),
+ "failed to get VDD regulator\n");
+
+ ret = regulator_enable(data->vdd);
+ if (ret)
+ return ret;
+
+ indio_dev->name = dev_name(&client->dev);
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->info = &si7210_info;
+ indio_dev->channels = si7210_channels;
+ indio_dev->num_channels = ARRAY_SIZE(si7210_channels);
+
+ ret = si7210_device_init(data);
+ if (ret)
+ return dev_err_probe(&client->dev, ret,
+ "device initialization failed\n");
+
+ return devm_iio_device_register(&client->dev, indio_dev);
+}
+
+static const struct i2c_device_id si7210_id[] = {
+ { "si7210" },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, si7210_id);
+
+static const struct of_device_id si7210_dt_ids[] = {
+ { .compatible = "silabs,si7210" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, si7210_dt_ids);
+
+static struct i2c_driver si7210_driver = {
+ .driver = {
+ .name = "si7210",
+ .of_match_table = si7210_dt_ids,
+ },
+ .probe = si7210_probe,
+ .id_table = si7210_id,
+};
+module_i2c_driver(si7210_driver);
+
+MODULE_AUTHOR("Antoni Pokusinski <apokusinski01@gmail.com>");
+MODULE_DESCRIPTION("Silicon Labs Si7210 Hall Effect sensor I2C driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/magnetometer/st_magn_i2c.c b/drivers/iio/magnetometer/st_magn_i2c.c
index 1672b274768d..ed70e782af5e 100644
--- a/drivers/iio/magnetometer/st_magn_i2c.c
+++ b/drivers/iio/magnetometer/st_magn_i2c.c
@@ -54,7 +54,7 @@ static const struct of_device_id st_magn_of_match[] = {
.compatible = "st,lsm303c-magn",
.data = LSM303C_MAGN_DEV_NAME,
},
- {},
+ { }
};
MODULE_DEVICE_TABLE(of, st_magn_of_match);
@@ -102,7 +102,7 @@ static const struct i2c_device_id st_magn_id_table[] = {
{ LSM9DS1_MAGN_DEV_NAME },
{ IIS2MDC_MAGN_DEV_NAME },
{ LSM303C_MAGN_DEV_NAME },
- {},
+ { }
};
MODULE_DEVICE_TABLE(i2c, st_magn_id_table);
diff --git a/drivers/iio/magnetometer/st_magn_spi.c b/drivers/iio/magnetometer/st_magn_spi.c
index fe4d0e63133c..68816362bb95 100644
--- a/drivers/iio/magnetometer/st_magn_spi.c
+++ b/drivers/iio/magnetometer/st_magn_spi.c
@@ -49,7 +49,7 @@ static const struct of_device_id st_magn_of_match[] = {
.compatible = "st,lsm303c-magn",
.data = LSM303C_MAGN_DEV_NAME,
},
- {}
+ { }
};
MODULE_DEVICE_TABLE(of, st_magn_of_match);
@@ -94,7 +94,7 @@ static const struct spi_device_id st_magn_id_table[] = {
{ LSM9DS1_MAGN_DEV_NAME },
{ IIS2MDC_MAGN_DEV_NAME },
{ LSM303C_MAGN_DEV_NAME },
- {},
+ { }
};
MODULE_DEVICE_TABLE(spi, st_magn_id_table);
diff --git a/drivers/iio/magnetometer/tmag5273.c b/drivers/iio/magnetometer/tmag5273.c
index 4187abe12784..2ca5c26f0091 100644
--- a/drivers/iio/magnetometer/tmag5273.c
+++ b/drivers/iio/magnetometer/tmag5273.c
@@ -712,13 +712,13 @@ static DEFINE_RUNTIME_DEV_PM_OPS(tmag5273_pm_ops,
static const struct i2c_device_id tmag5273_id[] = {
{ "tmag5273" },
- { /* sentinel */ }
+ { }
};
MODULE_DEVICE_TABLE(i2c, tmag5273_id);
static const struct of_device_id tmag5273_of_match[] = {
{ .compatible = "ti,tmag5273" },
- { /* sentinel */ }
+ { }
};
MODULE_DEVICE_TABLE(of, tmag5273_of_match);
diff --git a/drivers/iio/magnetometer/yamaha-yas530.c b/drivers/iio/magnetometer/yamaha-yas530.c
index 28012b20c64f..340607111d9a 100644
--- a/drivers/iio/magnetometer/yamaha-yas530.c
+++ b/drivers/iio/magnetometer/yamaha-yas530.c
@@ -674,8 +674,8 @@ static void yas5xx_fill_buffer(struct iio_dev *indio_dev)
yas5xx->scan.channels[1] = x;
yas5xx->scan.channels[2] = y;
yas5xx->scan.channels[3] = z;
- iio_push_to_buffers_with_timestamp(indio_dev, &yas5xx->scan,
- iio_get_time_ns(indio_dev));
+ iio_push_to_buffers_with_ts(indio_dev, &yas5xx->scan, sizeof(yas5xx->scan),
+ iio_get_time_ns(indio_dev));
}
static irqreturn_t yas5xx_handle_trigger(int irq, void *p)
@@ -1585,7 +1585,7 @@ static const struct i2c_device_id yas5xx_id[] = {
{"yas532", (kernel_ulong_t)&yas5xx_chip_info_tbl[yas532] },
{"yas533", (kernel_ulong_t)&yas5xx_chip_info_tbl[yas533] },
{"yas537", (kernel_ulong_t)&yas5xx_chip_info_tbl[yas537] },
- {}
+ { }
};
MODULE_DEVICE_TABLE(i2c, yas5xx_id);
@@ -1594,7 +1594,7 @@ static const struct of_device_id yas5xx_of_match[] = {
{ .compatible = "yamaha,yas532", &yas5xx_chip_info_tbl[yas532] },
{ .compatible = "yamaha,yas533", &yas5xx_chip_info_tbl[yas533] },
{ .compatible = "yamaha,yas537", &yas5xx_chip_info_tbl[yas537] },
- {}
+ { }
};
MODULE_DEVICE_TABLE(of, yas5xx_of_match);