summaryrefslogtreecommitdiff
path: root/drivers/iio/accel/fxls8962af-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio/accel/fxls8962af-core.c')
-rw-r--r--drivers/iio/accel/fxls8962af-core.c109
1 files changed, 67 insertions, 42 deletions
diff --git a/drivers/iio/accel/fxls8962af-core.c b/drivers/iio/accel/fxls8962af-core.c
index be8a15cb945f..8763e91c63d2 100644
--- a/drivers/iio/accel/fxls8962af-core.c
+++ b/drivers/iio/accel/fxls8962af-core.c
@@ -15,11 +15,15 @@
#include <linux/bits.h>
#include <linux/bitfield.h>
#include <linux/i2c.h>
+#include <linux/irq.h>
#include <linux/module.h>
-#include <linux/of_irq.h>
+#include <linux/mod_devicetable.h>
#include <linux/pm_runtime.h>
+#include <linux/property.h>
#include <linux/regulator/consumer.h>
#include <linux/regmap.h>
+#include <linux/types.h>
+#include <linux/units.h>
#include <linux/iio/buffer.h>
#include <linux/iio/events.h>
@@ -126,6 +130,8 @@
#define FXLS8962AF_DEVICE_ID 0x62
#define FXLS8964AF_DEVICE_ID 0x84
+#define FXLS8974CF_DEVICE_ID 0x86
+#define FXLS8967AF_DEVICE_ID 0x87
/* Raw temp channel offset */
#define FXLS8962AF_TEMP_CENTER_VAL 25
@@ -161,7 +167,7 @@ struct fxls8962af_data {
const struct fxls8962af_chip_info *chip_info;
struct {
__le16 channels[3];
- s64 ts __aligned(8);
+ aligned_s64 ts;
} scan;
int64_t timestamp, old_timestamp; /* Only used in hw fifo mode. */
struct iio_mount_matrix orientation;
@@ -177,7 +183,7 @@ const struct regmap_config fxls8962af_i2c_regmap_conf = {
.val_bits = 8,
.max_register = FXLS8962AF_MAX_REG,
};
-EXPORT_SYMBOL_NS_GPL(fxls8962af_i2c_regmap_conf, IIO_FXLS8962AF);
+EXPORT_SYMBOL_NS_GPL(fxls8962af_i2c_regmap_conf, "IIO_FXLS8962AF");
const struct regmap_config fxls8962af_spi_regmap_conf = {
.reg_bits = 8,
@@ -185,7 +191,7 @@ const struct regmap_config fxls8962af_spi_regmap_conf = {
.val_bits = 8,
.max_register = FXLS8962AF_MAX_REG,
};
-EXPORT_SYMBOL_NS_GPL(fxls8962af_spi_regmap_conf, IIO_FXLS8962AF);
+EXPORT_SYMBOL_NS_GPL(fxls8962af_spi_regmap_conf, "IIO_FXLS8962AF");
enum {
fxls8962af_idx_x,
@@ -216,7 +222,6 @@ static int fxls8962af_power_off(struct fxls8962af_data *data)
struct device *dev = regmap_get_device(data->regmap);
int ret;
- pm_runtime_mark_last_busy(dev);
ret = pm_runtime_put_autosuspend(dev);
if (ret)
dev_err(dev, "failed to power off\n");
@@ -226,8 +231,8 @@ static int fxls8962af_power_off(struct fxls8962af_data *data)
static int fxls8962af_standby(struct fxls8962af_data *data)
{
- return regmap_update_bits(data->regmap, FXLS8962AF_SENS_CONFIG1,
- FXLS8962AF_SENS_CONFIG1_ACTIVE, 0);
+ return regmap_clear_bits(data->regmap, FXLS8962AF_SENS_CONFIG1,
+ FXLS8962AF_SENS_CONFIG1_ACTIVE);
}
static int fxls8962af_active(struct fxls8962af_data *data)
@@ -434,8 +439,16 @@ static int fxls8962af_read_raw(struct iio_dev *indio_dev,
*val = FXLS8962AF_TEMP_CENTER_VAL;
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
- *val = 0;
- return fxls8962af_read_full_scale(data, val2);
+ switch (chan->type) {
+ case IIO_TEMP:
+ *val = MILLIDEGREE_PER_DEGREE;
+ return IIO_VAL_INT;
+ case IIO_ACCEL:
+ *val = 0;
+ return fxls8962af_read_full_scale(data, val2);
+ default:
+ return -EINVAL;
+ }
case IIO_CHAN_INFO_SAMP_FREQ:
return fxls8962af_read_samp_freq(data, val, val2);
default:
@@ -455,22 +468,20 @@ static int fxls8962af_write_raw(struct iio_dev *indio_dev,
if (val != 0)
return -EINVAL;
- ret = iio_device_claim_direct_mode(indio_dev);
- if (ret)
- return ret;
+ if (!iio_device_claim_direct(indio_dev))
+ return -EBUSY;
ret = fxls8962af_set_full_scale(data, val2);
- iio_device_release_direct_mode(indio_dev);
+ iio_device_release_direct(indio_dev);
return ret;
case IIO_CHAN_INFO_SAMP_FREQ:
- ret = iio_device_claim_direct_mode(indio_dev);
- if (ret)
- return ret;
+ if (!iio_device_claim_direct(indio_dev))
+ return -EBUSY;
ret = fxls8962af_set_samp_freq(data, val, val2);
- iio_device_release_direct_mode(indio_dev);
+ iio_device_release_direct(indio_dev);
return ret;
default:
return -EINVAL;
@@ -614,7 +625,7 @@ static int
fxls8962af_write_event_config(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan,
enum iio_event_type type,
- enum iio_event_direction dir, int state)
+ enum iio_event_direction dir, bool state)
{
struct fxls8962af_data *data = iio_priv(indio_dev);
u8 enable_event, enable_bits;
@@ -678,14 +689,13 @@ fxls8962af_write_event_config(struct iio_dev *indio_dev,
fxls8962af_active(data);
ret = fxls8962af_power_on(data);
} else {
- ret = iio_device_claim_direct_mode(indio_dev);
- if (ret)
- return ret;
+ if (!iio_device_claim_direct(indio_dev))
+ return -EBUSY;
/* Not in buffered mode so disable power */
ret = fxls8962af_power_off(data);
- iio_device_release_direct_mode(indio_dev);
+ iio_device_release_direct(indio_dev);
}
return ret;
@@ -734,9 +744,11 @@ static const struct iio_event_spec fxls8962af_event[] = {
.type = IIO_TEMP, \
.address = FXLS8962AF_TEMP_OUT, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE) | \
BIT(IIO_CHAN_INFO_OFFSET),\
.scan_index = -1, \
.scan_type = { \
+ .sign = 's', \
.realbits = 8, \
.storagebits = 8, \
}, \
@@ -763,6 +775,18 @@ static const struct fxls8962af_chip_info fxls_chip_info_table[] = {
.channels = fxls8962af_channels,
.num_channels = ARRAY_SIZE(fxls8962af_channels),
},
+ [fxls8967af] = {
+ .chip_id = FXLS8967AF_DEVICE_ID,
+ .name = "fxls8967af",
+ .channels = fxls8962af_channels,
+ .num_channels = ARRAY_SIZE(fxls8962af_channels),
+ },
+ [fxls8974cf] = {
+ .chip_id = FXLS8974CF_DEVICE_ID,
+ .name = "fxls8974cf",
+ .channels = fxls8962af_channels,
+ .num_channels = ARRAY_SIZE(fxls8962af_channels),
+ },
};
static const struct iio_info fxls8962af_info = {
@@ -783,9 +807,8 @@ static int fxls8962af_reset(struct fxls8962af_data *data)
unsigned int reg;
int ret;
- ret = regmap_update_bits(data->regmap, FXLS8962AF_SENS_CONFIG1,
- FXLS8962AF_SENS_CONFIG1_RST,
- FXLS8962AF_SENS_CONFIG1_RST);
+ ret = regmap_set_bits(data->regmap, FXLS8962AF_SENS_CONFIG1,
+ FXLS8962AF_SENS_CONFIG1_RST);
if (ret)
return ret;
@@ -828,9 +851,8 @@ static int fxls8962af_buffer_postenable(struct iio_dev *indio_dev)
fxls8962af_standby(data);
/* Enable buffer interrupt */
- ret = regmap_update_bits(data->regmap, FXLS8962AF_INT_EN,
- FXLS8962AF_INT_EN_BUF_EN,
- FXLS8962AF_INT_EN_BUF_EN);
+ ret = regmap_set_bits(data->regmap, FXLS8962AF_INT_EN,
+ FXLS8962AF_INT_EN_BUF_EN);
if (ret)
return ret;
@@ -849,11 +871,13 @@ static int fxls8962af_buffer_predisable(struct iio_dev *indio_dev)
fxls8962af_standby(data);
/* Disable buffer interrupt */
- ret = regmap_update_bits(data->regmap, FXLS8962AF_INT_EN,
- FXLS8962AF_INT_EN_BUF_EN, 0);
+ ret = regmap_clear_bits(data->regmap, FXLS8962AF_INT_EN,
+ FXLS8962AF_INT_EN_BUF_EN);
if (ret)
return ret;
+ synchronize_irq(data->irq);
+
ret = __fxls8962af_fifo_set_mode(data, false);
if (data->enable_event)
@@ -966,14 +990,13 @@ static int fxls8962af_fifo_flush(struct iio_dev *indio_dev)
int j, bit;
j = 0;
- for_each_set_bit(bit, indio_dev->active_scan_mask,
- indio_dev->masklength) {
+ iio_for_each_active_channel(indio_dev, bit) {
memcpy(&data->scan.channels[j++], &buffer[i * 3 + bit],
sizeof(data->scan.channels[0]));
}
- iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
- tstamp);
+ iio_push_to_buffers_with_ts(indio_dev, &data->scan,
+ sizeof(data->scan), tstamp);
tstamp += sample_period;
}
@@ -1062,12 +1085,12 @@ static void fxls8962af_pm_disable(void *dev_ptr)
fxls8962af_standby(iio_priv(indio_dev));
}
-static void fxls8962af_get_irq(struct device_node *of_node,
+static void fxls8962af_get_irq(struct device *dev,
enum fxls8962af_int_pin *pin)
{
int irq;
- irq = of_irq_get_byname(of_node, "INT2");
+ irq = fwnode_irq_get_byname(dev_fwnode(dev), "INT2");
if (irq > 0) {
*pin = FXLS8962AF_PIN_INT2;
return;
@@ -1086,7 +1109,7 @@ static int fxls8962af_irq_setup(struct iio_dev *indio_dev, int irq)
u8 int_pin_sel;
int ret;
- fxls8962af_get_irq(dev->of_node, &int_pin);
+ fxls8962af_get_irq(dev, &int_pin);
switch (int_pin) {
case FXLS8962AF_PIN_INT1:
int_pin_sel = FXLS8962AF_INT_PIN_SEL_INT1;
@@ -1104,8 +1127,7 @@ static int fxls8962af_irq_setup(struct iio_dev *indio_dev, int irq)
if (ret)
return ret;
- irq_type = irqd_get_trigger_type(irq_get_irq_data(irq));
-
+ irq_type = irq_get_trigger_type(irq);
switch (irq_type) {
case IRQF_TRIGGER_HIGH:
case IRQF_TRIGGER_RISING:
@@ -1216,12 +1238,15 @@ int fxls8962af_core_probe(struct device *dev, struct regmap *regmap, int irq)
if (ret)
return ret;
- if (device_property_read_bool(dev, "wakeup-source"))
- device_init_wakeup(dev, true);
+ if (device_property_read_bool(dev, "wakeup-source")) {
+ ret = devm_device_init_wakeup(dev);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to init wakeup\n");
+ }
return devm_iio_device_register(dev, indio_dev);
}
-EXPORT_SYMBOL_NS_GPL(fxls8962af_core_probe, IIO_FXLS8962AF);
+EXPORT_SYMBOL_NS_GPL(fxls8962af_core_probe, "IIO_FXLS8962AF");
static int fxls8962af_runtime_suspend(struct device *dev)
{