drivers:iio:stm:pressure: Add support to ST MEMS LPS22DB pressure sensor
Added support to LPS22DB ST MEMS pressure and temperature sensor List of supported features: - Configurable ODRs [Power_Off ... 75] Hz - Sensor Event Timestamp support - Read single raw data values for pressure and temperature - FIFO: > Pressure data stored in FIFO > HW Watermark configuration > Custom Flush command / event support Signed-off-by: mario tesi <mario.tesi@st.com> Change-Id: I435b87f7377b43cd34cb766968ca6326815c186c
This commit is contained in:
parent
910e94f2d1
commit
ab983aa7de
@ -47,4 +47,23 @@ config ST_LPS22DF_SPI_IIO
|
||||
tristate
|
||||
depends on ST_LPS22DF_IIO
|
||||
|
||||
config ST_LPS22HB_IIO
|
||||
tristate "STMicroelectronics LPS22HB sensor"
|
||||
depends on (I2C || SPI_MASTER) && SYSFS
|
||||
select IIO_BUFFER
|
||||
select IIO_KFIFO_BUF
|
||||
select ST_LPS22HB_I2C_IIO if (I2C)
|
||||
select ST_LPS22HB_SPI_IIO if (SPI)
|
||||
help
|
||||
This driver supports LPS22HB pressure sensor. This driver can be
|
||||
built as a module. The module will be called st-lps22hb.
|
||||
|
||||
config ST_LPS22HB_I2C_IIO
|
||||
tristate
|
||||
depends on ST_LPS22HB_IIO
|
||||
|
||||
config ST_LPS22HB_SPI_IIO
|
||||
tristate
|
||||
depends on ST_LPS22HB_IIO
|
||||
|
||||
endmenu
|
||||
|
@ -16,3 +16,8 @@ obj-$(CONFIG_ST_LPS22DF_SPI_IIO) += st_lps22df_spi.o
|
||||
|
||||
st_lps22df-y += st_lps22df_core.o st_lps22df_buffer.o
|
||||
|
||||
obj-$(CONFIG_ST_LPS22HB_IIO) += st_lps22hb.o
|
||||
obj-$(CONFIG_ST_LPS22HB_I2C_IIO) += st_lps22hb_i2c.o
|
||||
obj-$(CONFIG_ST_LPS22HB_SPI_IIO) += st_lps22hb_spi.o
|
||||
|
||||
st_lps22hb-y += st_lps22hb_core.o st_lps22hb_buffer.o
|
||||
|
88
drivers/iio/stm/pressure/st_lps22hb.h
Normal file
88
drivers/iio/stm/pressure/st_lps22hb.h
Normal file
@ -0,0 +1,88 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* STMicroelectronics lps22hb driver
|
||||
*
|
||||
* Copyright 2017 STMicroelectronics Inc.
|
||||
*
|
||||
* Lorenzo Bianconi <lorenzo.bianconi@st.com>
|
||||
*/
|
||||
|
||||
#ifndef __ST_LPS22HB_H
|
||||
#define __ST_LPS22HB_H
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/iio/trigger.h>
|
||||
|
||||
#define ST_LPS22HB_MAX_FIFO_LENGTH 31
|
||||
|
||||
#define ST_LPS22HB_CTRL3_ADDR 0x12
|
||||
|
||||
enum st_lps22hb_sensor_type {
|
||||
ST_LPS22HB_PRESS = 0,
|
||||
ST_LPS22HB_TEMP,
|
||||
ST_LPS22HB_SENSORS_NUMB,
|
||||
};
|
||||
|
||||
enum st_lps22hb_fifo_mode {
|
||||
ST_LPS22HB_BYPASS = 0x0,
|
||||
ST_LPS22HB_STREAM = 0x6,
|
||||
};
|
||||
|
||||
#define ST_LPS22HB_TX_MAX_LENGTH 8
|
||||
#define ST_LPS22HB_RX_MAX_LENGTH 192
|
||||
|
||||
struct st_lps22hb_transfer_buffer {
|
||||
u8 rx_buf[ST_LPS22HB_RX_MAX_LENGTH];
|
||||
u8 tx_buf[ST_LPS22HB_TX_MAX_LENGTH] ____cacheline_aligned;
|
||||
};
|
||||
|
||||
struct st_lps22hb_transfer_function {
|
||||
int (*write)(struct device *dev, u8 addr, int len, u8 *data);
|
||||
int (*read)(struct device *dev, u8 addr, int len, u8 *data);
|
||||
};
|
||||
|
||||
struct st_lps22hb_hw {
|
||||
struct device *dev;
|
||||
int irq;
|
||||
|
||||
struct mutex fifo_lock;
|
||||
struct mutex lock;
|
||||
u8 watermark;
|
||||
|
||||
struct iio_dev *iio_devs[ST_LPS22HB_SENSORS_NUMB];
|
||||
u8 enable_mask;
|
||||
u8 odr;
|
||||
|
||||
s64 delta_ts;
|
||||
s64 ts_irq;
|
||||
s64 ts;
|
||||
|
||||
const struct st_lps22hb_transfer_function *tf;
|
||||
struct st_lps22hb_transfer_buffer tb;
|
||||
};
|
||||
|
||||
struct st_lps22hb_sensor {
|
||||
struct st_lps22hb_hw *hw;
|
||||
enum st_lps22hb_sensor_type type;
|
||||
char name[32];
|
||||
|
||||
u32 gain;
|
||||
u8 odr;
|
||||
};
|
||||
|
||||
int st_lps22hb_common_probe(struct device *dev, int irq, const char *name,
|
||||
const struct st_lps22hb_transfer_function *tf_ops);
|
||||
int st_lps22hb_write_with_mask(struct st_lps22hb_hw *hw, u8 addr, u8 mask,
|
||||
u8 data);
|
||||
int st_lps22hb_allocate_buffers(struct st_lps22hb_hw *hw);
|
||||
int st_lps22hb_set_enable(struct st_lps22hb_sensor *sensor, bool enable);
|
||||
ssize_t st_lps22hb_sysfs_set_hwfifo_watermark(struct device * dev,
|
||||
struct device_attribute * attr,
|
||||
const char *buf, size_t count);
|
||||
ssize_t st_lps22hb_sysfs_flush_fifo(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size);
|
||||
|
||||
#endif /* __ST_LPS22HB_H */
|
278
drivers/iio/stm/pressure/st_lps22hb_buffer.c
Normal file
278
drivers/iio/stm/pressure/st_lps22hb_buffer.c
Normal file
@ -0,0 +1,278 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* STMicroelectronics lps22hb buffer driver
|
||||
*
|
||||
* Copyright 2017 STMicroelectronics Inc.
|
||||
*
|
||||
* Lorenzo Bianconi <lorenzo.bianconi@st.com>
|
||||
*/
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/iio/buffer.h>
|
||||
#include <linux/iio/kfifo_buf.h>
|
||||
#include <linux/iio/events.h>
|
||||
|
||||
#include "st_lps22hb.h"
|
||||
|
||||
#define ST_LPS22HB_FIFO_CTRL_ADDR 0x14
|
||||
#define ST_LPS22HB_FIFO_THS_MASK 0x1f
|
||||
#define ST_LPS22HB_FIFO_MODE_MASK 0xe0
|
||||
#define ST_LPS22HB_INT_FTH_MASK 0x10
|
||||
|
||||
#define ST_LPS22HB_FIFO_SRC_ADDR 0x26
|
||||
#define ST_LPS22HB_FIFO_SRC_DIFF_MASK 0x1f
|
||||
|
||||
#define ST_LPS22HB_PRESS_OUT_XL_ADDR 0x28
|
||||
|
||||
#define ST_LPS22HB_PRESS_SAMPLE_LEN 3
|
||||
#define ST_LPS22HB_TEMP_SAMPLE_LEN 2
|
||||
#define ST_LPS22HB_FIFO_SAMPLE_LEN (ST_LPS22HB_PRESS_SAMPLE_LEN + \
|
||||
ST_LPS22HB_TEMP_SAMPLE_LEN)
|
||||
|
||||
static inline s64 st_lps22hb_get_time_ns(struct iio_dev *iio_dev)
|
||||
{
|
||||
return iio_get_time_ns(iio_dev);
|
||||
}
|
||||
|
||||
#define ST_LPS22HB_EWMA_LEVEL 96
|
||||
#define ST_LPS22HB_EWMA_DIV 128
|
||||
static inline s64 st_lps22hb_ewma(s64 old, s64 new, int weight)
|
||||
{
|
||||
s64 diff, incr;
|
||||
|
||||
diff = new - old;
|
||||
incr = div_s64((ST_LPS22HB_EWMA_DIV - weight) * diff,
|
||||
ST_LPS22HB_EWMA_DIV);
|
||||
|
||||
return old + incr;
|
||||
}
|
||||
|
||||
static int st_lps22hb_set_fifo_mode(struct st_lps22hb_hw *hw,
|
||||
enum st_lps22hb_fifo_mode mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case ST_LPS22HB_BYPASS:
|
||||
case ST_LPS22HB_STREAM:
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return st_lps22hb_write_with_mask(hw, ST_LPS22HB_FIFO_CTRL_ADDR,
|
||||
ST_LPS22HB_FIFO_MODE_MASK, mode);
|
||||
}
|
||||
|
||||
static int st_lps22hb_update_fifo_watermark(struct st_lps22hb_hw *hw, u8 val)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = st_lps22hb_write_with_mask(hw, ST_LPS22HB_FIFO_CTRL_ADDR,
|
||||
ST_LPS22HB_FIFO_THS_MASK, val);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
hw->watermark = val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t st_lps22hb_sysfs_set_hwfifo_watermark(struct device * dev,
|
||||
struct device_attribute * attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct st_lps22hb_sensor *sensor = iio_priv(dev_get_drvdata(dev));
|
||||
int err, watermark;
|
||||
|
||||
err = kstrtoint(buf, 10, &watermark);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (watermark < 1 || watermark > ST_LPS22HB_MAX_FIFO_LENGTH)
|
||||
return -EINVAL;
|
||||
|
||||
err = st_lps22hb_update_fifo_watermark(sensor->hw, watermark);
|
||||
|
||||
return err < 0 ? err : count;
|
||||
}
|
||||
|
||||
static int st_lps22hb_read_fifo(struct st_lps22hb_hw *hw)
|
||||
{
|
||||
u8 iio_buff[ALIGN(sizeof(u32) + sizeof(s64), sizeof(s64))];
|
||||
u8 status, buff[ST_LPS22HB_RX_MAX_LENGTH];
|
||||
int err, i, read_len;
|
||||
|
||||
err = hw->tf->read(hw->dev, ST_LPS22HB_FIFO_SRC_ADDR,
|
||||
sizeof(status), &status);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
read_len = (status & ST_LPS22HB_FIFO_SRC_DIFF_MASK) *
|
||||
ST_LPS22HB_FIFO_SAMPLE_LEN;
|
||||
if (!read_len)
|
||||
return 0;
|
||||
|
||||
err = hw->tf->read(hw->dev, ST_LPS22HB_PRESS_OUT_XL_ADDR,
|
||||
read_len, buff);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
for (i = 0; i < read_len; i += ST_LPS22HB_FIFO_SAMPLE_LEN) {
|
||||
/* press sample */
|
||||
memcpy(iio_buff, buff + i, ST_LPS22HB_PRESS_SAMPLE_LEN);
|
||||
iio_push_to_buffers_with_timestamp(
|
||||
hw->iio_devs[ST_LPS22HB_PRESS],
|
||||
iio_buff, hw->ts);
|
||||
/* temp sample */
|
||||
memcpy(iio_buff, buff + i + ST_LPS22HB_PRESS_SAMPLE_LEN,
|
||||
ST_LPS22HB_TEMP_SAMPLE_LEN);
|
||||
iio_push_to_buffers_with_timestamp(
|
||||
hw->iio_devs[ST_LPS22HB_TEMP],
|
||||
iio_buff, hw->ts);
|
||||
hw->ts += hw->delta_ts;
|
||||
}
|
||||
|
||||
return read_len;
|
||||
}
|
||||
|
||||
ssize_t st_lps22hb_sysfs_flush_fifo(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
||||
struct st_lps22hb_sensor *sensor = iio_priv(indio_dev);
|
||||
struct st_lps22hb_hw *hw = sensor->hw;
|
||||
u64 type, event;
|
||||
int len;
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
if (!iio_buffer_enabled(indio_dev)) {
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&hw->fifo_lock);
|
||||
len = st_lps22hb_read_fifo(hw);
|
||||
mutex_unlock(&hw->fifo_lock);
|
||||
|
||||
type = len > 0 ? IIO_EV_DIR_FIFO_DATA : IIO_EV_DIR_FIFO_EMPTY;
|
||||
if (sensor->type == ST_LPS22HB_PRESS)
|
||||
event = IIO_UNMOD_EVENT_CODE(IIO_PRESSURE, -1,
|
||||
IIO_EV_TYPE_FIFO_FLUSH, type);
|
||||
else
|
||||
event = IIO_UNMOD_EVENT_CODE(IIO_TEMP, -1,
|
||||
IIO_EV_TYPE_FIFO_FLUSH, type);
|
||||
iio_push_event(indio_dev, event, st_lps22hb_get_time_ns(indio_dev));
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
static irqreturn_t st_lps22hb_irq_handler(int irq, void *private)
|
||||
{
|
||||
struct st_lps22hb_hw *hw = private;
|
||||
s64 delta_ts, ts;
|
||||
|
||||
ts = st_lps22hb_get_time_ns(hw->iio_devs[ST_LPS22HB_PRESS]);
|
||||
delta_ts = div_s64((ts - hw->ts_irq), hw->watermark);
|
||||
if (hw->odr >= 50)
|
||||
hw->delta_ts = st_lps22hb_ewma(hw->delta_ts, delta_ts,
|
||||
ST_LPS22HB_EWMA_LEVEL);
|
||||
else
|
||||
hw->delta_ts = delta_ts;
|
||||
hw->ts_irq = ts;
|
||||
|
||||
return IRQ_WAKE_THREAD;
|
||||
}
|
||||
|
||||
static irqreturn_t st_lps22hb_irq_thread(int irq, void *private)
|
||||
{
|
||||
struct st_lps22hb_hw *hw = private;
|
||||
|
||||
mutex_lock(&hw->fifo_lock);
|
||||
st_lps22hb_read_fifo(hw);
|
||||
mutex_unlock(&hw->fifo_lock);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int st_lps22hb_buffer_preenable(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct st_lps22hb_sensor *sensor = iio_priv(indio_dev);
|
||||
struct st_lps22hb_hw *hw = sensor->hw;
|
||||
int err;
|
||||
|
||||
err = st_lps22hb_set_fifo_mode(sensor->hw, ST_LPS22HB_STREAM);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = st_lps22hb_update_fifo_watermark(hw, hw->watermark);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = st_lps22hb_write_with_mask(sensor->hw, ST_LPS22HB_CTRL3_ADDR,
|
||||
ST_LPS22HB_INT_FTH_MASK, true);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = st_lps22hb_set_enable(sensor, true);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
hw->delta_ts = div_s64(1000000000UL, hw->odr);
|
||||
hw->ts = st_lps22hb_get_time_ns(indio_dev);
|
||||
hw->ts_irq = hw->ts;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int st_lps22hb_buffer_postdisable(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct st_lps22hb_sensor *sensor = iio_priv(indio_dev);
|
||||
int err;
|
||||
|
||||
err = st_lps22hb_set_fifo_mode(sensor->hw, ST_LPS22HB_BYPASS);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = st_lps22hb_write_with_mask(sensor->hw, ST_LPS22HB_CTRL3_ADDR,
|
||||
ST_LPS22HB_INT_FTH_MASK, false);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return st_lps22hb_set_enable(sensor, false);
|
||||
}
|
||||
|
||||
static const struct iio_buffer_setup_ops st_lps22hb_buffer_ops = {
|
||||
.preenable = st_lps22hb_buffer_preenable,
|
||||
.postdisable = st_lps22hb_buffer_postdisable,
|
||||
};
|
||||
|
||||
int st_lps22hb_allocate_buffers(struct st_lps22hb_hw *hw)
|
||||
{
|
||||
struct iio_buffer *buffer;
|
||||
int err, i;
|
||||
|
||||
err = devm_request_threaded_irq(hw->dev, hw->irq,
|
||||
st_lps22hb_irq_handler,
|
||||
st_lps22hb_irq_thread,
|
||||
IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
|
||||
"lps22hb", hw);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
for (i = 0; i < ST_LPS22HB_SENSORS_NUMB; i++) {
|
||||
buffer = devm_iio_kfifo_allocate(hw->dev);
|
||||
if (!buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
iio_device_attach_buffer(hw->iio_devs[i], buffer);
|
||||
hw->iio_devs[i]->modes |= INDIO_BUFFER_SOFTWARE;
|
||||
hw->iio_devs[i]->setup_ops = &st_lps22hb_buffer_ops;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
MODULE_DESCRIPTION("STMicroelectronics lps22hb buffer driver");
|
||||
MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
484
drivers/iio/stm/pressure/st_lps22hb_core.c
Normal file
484
drivers/iio/stm/pressure/st_lps22hb_core.c
Normal file
@ -0,0 +1,484 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* STMicroelectronics lps22hb driver
|
||||
*
|
||||
* Copyright 2017 STMicroelectronics Inc.
|
||||
*
|
||||
* Lorenzo Bianconi <lorenzo.bianconi@st.com>
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/iio/sysfs.h>
|
||||
#include <linux/iio/trigger.h>
|
||||
#include <linux/delay.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include "st_lps22hb.h"
|
||||
|
||||
#define ST_LPS22HB_WHO_AM_I_ADDR 0x0f
|
||||
#define ST_LPS22HB_WHO_AM_I_DEF 0xb1
|
||||
|
||||
#define ST_LPS22HB_CTRL1_ADDR 0x10
|
||||
#define ST_LPS22HB_BDU_MASK 0x02
|
||||
#define ST_LPS22HB_CTRL2_ADDR 0x11
|
||||
#define ST_LPS22HB_SOFT_RESET_MASK 0x04
|
||||
#define ST_LPS22HB_FIFO_ENABLE_MASK 0x40
|
||||
|
||||
#define ST_LPS22HB_LIR_ADDR 0x0b
|
||||
#define ST_LPS22HB_LIR_MASK 0x04
|
||||
|
||||
#define ST_LPS22HB_PRESS_FS_AVL_GAIN (1000000000UL / 4096UL)
|
||||
#define ST_LPS22HB_TEMP_FS_AVL_GAIN (1000000000UL / 100UL)
|
||||
|
||||
#define ST_LPS22HB_ODR_LIST_NUM 6
|
||||
struct st_lps22hb_odr_table_t {
|
||||
u8 addr;
|
||||
u8 mask;
|
||||
u8 odr_avl[ST_LPS22HB_ODR_LIST_NUM];
|
||||
};
|
||||
|
||||
const static struct st_lps22hb_odr_table_t st_lps22hb_odr_table = {
|
||||
.addr = 0x10,
|
||||
.mask = 0x70,
|
||||
.odr_avl = { 0, 1, 10, 25, 50, 75 },
|
||||
};
|
||||
|
||||
const struct iio_event_spec st_lps22hb_fifo_flush_event = {
|
||||
.type = IIO_EV_TYPE_FIFO_FLUSH,
|
||||
.dir = IIO_EV_DIR_EITHER,
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec st_lps22hb_press_channels[] = {
|
||||
{
|
||||
.type = IIO_PRESSURE,
|
||||
.address = 0x28,
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
|
||||
BIT(IIO_CHAN_INFO_SCALE),
|
||||
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
|
||||
.channel2 = IIO_NO_MOD,
|
||||
.scan_index = 0,
|
||||
.scan_type = {
|
||||
.sign = 'u',
|
||||
.realbits = 24,
|
||||
.storagebits = 32,
|
||||
.endianness = IIO_LE,
|
||||
},
|
||||
},
|
||||
{
|
||||
.type = IIO_PRESSURE,
|
||||
.scan_index = -1,
|
||||
.indexed = -1,
|
||||
.event_spec = &st_lps22hb_fifo_flush_event,
|
||||
.num_event_specs = 1,
|
||||
},
|
||||
IIO_CHAN_SOFT_TIMESTAMP(1)
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec st_lps22hb_temp_channels[] = {
|
||||
{
|
||||
.type = IIO_TEMP,
|
||||
.address = 0x2b,
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
|
||||
BIT(IIO_CHAN_INFO_SCALE),
|
||||
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
|
||||
.channel2 = IIO_NO_MOD,
|
||||
.scan_index = 0,
|
||||
.scan_type = {
|
||||
.sign = 's',
|
||||
.realbits = 16,
|
||||
.storagebits = 16,
|
||||
.endianness = IIO_LE,
|
||||
},
|
||||
},
|
||||
{
|
||||
.type = IIO_TEMP,
|
||||
.scan_index = -1,
|
||||
.indexed = -1,
|
||||
.event_spec = &st_lps22hb_fifo_flush_event,
|
||||
.num_event_specs = 1,
|
||||
},
|
||||
IIO_CHAN_SOFT_TIMESTAMP(1)
|
||||
};
|
||||
|
||||
int st_lps22hb_write_with_mask(struct st_lps22hb_hw *hw, u8 addr, u8 mask,
|
||||
u8 val)
|
||||
{
|
||||
int err;
|
||||
u8 data;
|
||||
|
||||
mutex_lock(&hw->lock);
|
||||
|
||||
err = hw->tf->read(hw->dev, addr, sizeof(data), &data);
|
||||
if (err < 0)
|
||||
goto unlock;
|
||||
|
||||
data = (data & ~mask) | ((val << __ffs(mask)) & mask);
|
||||
err = hw->tf->write(hw->dev, addr, sizeof(data), &data);
|
||||
unlock:
|
||||
mutex_unlock(&hw->lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int st_lps22hb_check_whoami(struct st_lps22hb_hw *hw)
|
||||
{
|
||||
int err;
|
||||
u8 data;
|
||||
|
||||
err = hw->tf->read(hw->dev, ST_LPS22HB_WHO_AM_I_ADDR, sizeof(data),
|
||||
&data);
|
||||
if (err < 0) {
|
||||
dev_err(hw->dev, "failed to read Who-Am-I register.\n");
|
||||
|
||||
return err;
|
||||
}
|
||||
if (data != ST_LPS22HB_WHO_AM_I_DEF) {
|
||||
dev_err(hw->dev, "Who-Am-I value not valid.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int st_lps22hb_get_odr(struct st_lps22hb_sensor *sensor, u8 odr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ST_LPS22HB_ODR_LIST_NUM; i++) {
|
||||
if (st_lps22hb_odr_table.odr_avl[i] == odr)
|
||||
break;
|
||||
}
|
||||
return i == ST_LPS22HB_ODR_LIST_NUM ? -EINVAL : i;
|
||||
}
|
||||
|
||||
int st_lps22hb_set_enable(struct st_lps22hb_sensor *sensor, bool enable)
|
||||
{
|
||||
struct st_lps22hb_hw *hw = sensor->hw;
|
||||
u32 max_odr = enable ? sensor->odr : 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ST_LPS22HB_SENSORS_NUMB; i++) {
|
||||
if (sensor->type == i)
|
||||
continue;
|
||||
|
||||
if (hw->enable_mask & BIT(i)) {
|
||||
struct st_lps22hb_sensor *temp;
|
||||
|
||||
temp = iio_priv(hw->iio_devs[i]);
|
||||
max_odr = max_t(u32, max_odr, temp->odr);
|
||||
}
|
||||
}
|
||||
|
||||
if (max_odr != hw->odr) {
|
||||
int err, ret;
|
||||
|
||||
ret = st_lps22hb_get_odr(sensor, max_odr);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
err = st_lps22hb_write_with_mask(hw, st_lps22hb_odr_table.addr,
|
||||
st_lps22hb_odr_table.mask, ret);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
hw->odr = max_odr;
|
||||
}
|
||||
|
||||
if (enable)
|
||||
hw->enable_mask |= BIT(sensor->type);
|
||||
else
|
||||
hw->enable_mask &= ~BIT(sensor->type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int st_lps22hb_init_sensors(struct st_lps22hb_hw *hw)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* soft reset the device on power on. */
|
||||
err = st_lps22hb_write_with_mask(hw, ST_LPS22HB_CTRL2_ADDR,
|
||||
ST_LPS22HB_SOFT_RESET_MASK, 1);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
msleep(200);
|
||||
|
||||
/* enable latched interrupt mode */
|
||||
err = st_lps22hb_write_with_mask(hw, ST_LPS22HB_LIR_ADDR,
|
||||
ST_LPS22HB_LIR_MASK, 1);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* enable FIFO */
|
||||
err = st_lps22hb_write_with_mask(hw, ST_LPS22HB_CTRL2_ADDR,
|
||||
ST_LPS22HB_FIFO_ENABLE_MASK, 1);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* enable BDU */
|
||||
return st_lps22hb_write_with_mask(hw, ST_LPS22HB_CTRL1_ADDR,
|
||||
ST_LPS22HB_BDU_MASK, 1);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
st_lps22hb_get_sampling_frequency_avail(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int i, len = 0;
|
||||
|
||||
for (i = 1; i < ST_LPS22HB_ODR_LIST_NUM; i++) {
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
|
||||
st_lps22hb_odr_table.odr_avl[i]);
|
||||
}
|
||||
buf[len - 1] = '\n';
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
st_lps22hb_sysfs_get_hwfifo_watermark(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct st_lps22hb_sensor *sensor = iio_priv(dev_get_drvdata(dev));
|
||||
|
||||
return sprintf(buf, "%d\n", sensor->hw->watermark);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
st_lps22hb_sysfs_get_hwfifo_watermark_min(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", 1);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
st_lps22hb_sysfs_get_hwfifo_watermark_max(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", ST_LPS22HB_MAX_FIFO_LENGTH);
|
||||
}
|
||||
|
||||
static int st_lps22hb_read_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *ch,
|
||||
int *val, int *val2, long mask)
|
||||
{
|
||||
struct st_lps22hb_sensor *sensor = iio_priv(indio_dev);
|
||||
struct st_lps22hb_hw *hw = sensor->hw;
|
||||
int ret;
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_RAW: {
|
||||
u8 len = ch->scan_type.realbits / 8;
|
||||
u8 data[4] = {};
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
if (iio_buffer_enabled(indio_dev)) {
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
ret = -EBUSY;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = st_lps22hb_set_enable(sensor, true);
|
||||
if (ret < 0) {
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
ret = -EBUSY;
|
||||
break;
|
||||
}
|
||||
|
||||
msleep(40);
|
||||
ret = hw->tf->read(hw->dev, ch->address, len, data);
|
||||
if (ret < 0) {
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (sensor->type == ST_LPS22HB_PRESS)
|
||||
*val = (s32)get_unaligned_le32(data);
|
||||
else if (sensor->type == ST_LPS22HB_TEMP)
|
||||
*val = (s16)get_unaligned_le16(data);
|
||||
|
||||
ret = st_lps22hb_set_enable(sensor, false);
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = IIO_VAL_INT;
|
||||
break;
|
||||
}
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
*val = 0;
|
||||
*val2 = sensor->gain;
|
||||
ret = IIO_VAL_INT_PLUS_NANO;
|
||||
break;
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
*val = sensor->odr;
|
||||
ret = IIO_VAL_INT;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int st_lps22hb_write_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *ch,
|
||||
int val, int val2, long mask)
|
||||
{
|
||||
struct st_lps22hb_sensor *sensor = iio_priv(indio_dev);
|
||||
int ret;
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
ret = st_lps22hb_get_odr(sensor, val);
|
||||
if (ret > 0)
|
||||
sensor->odr = val;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lps22hb_get_sampling_frequency_avail);
|
||||
static IIO_DEVICE_ATTR(hwfifo_watermark, S_IWUSR | S_IRUGO,
|
||||
st_lps22hb_sysfs_get_hwfifo_watermark,
|
||||
st_lps22hb_sysfs_set_hwfifo_watermark, 0);
|
||||
static IIO_DEVICE_ATTR(hwfifo_watermark_min, S_IRUGO,
|
||||
st_lps22hb_sysfs_get_hwfifo_watermark_min, NULL, 0);
|
||||
static IIO_DEVICE_ATTR(hwfifo_watermark_max, S_IRUGO,
|
||||
st_lps22hb_sysfs_get_hwfifo_watermark_max, NULL, 0);
|
||||
static IIO_DEVICE_ATTR(hwfifo_flush, S_IWUSR, NULL,
|
||||
st_lps22hb_sysfs_flush_fifo, 0);
|
||||
|
||||
static struct attribute *st_lps22hb_press_attributes[] = {
|
||||
&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
|
||||
&iio_dev_attr_hwfifo_watermark.dev_attr.attr,
|
||||
&iio_dev_attr_hwfifo_watermark_min.dev_attr.attr,
|
||||
&iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
|
||||
&iio_dev_attr_hwfifo_flush.dev_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute *st_lps22hb_temp_attributes[] = {
|
||||
&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
|
||||
&iio_dev_attr_hwfifo_watermark.dev_attr.attr,
|
||||
&iio_dev_attr_hwfifo_watermark_min.dev_attr.attr,
|
||||
&iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
|
||||
&iio_dev_attr_hwfifo_flush.dev_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct attribute_group st_lps22hb_press_attribute_group = {
|
||||
.attrs = st_lps22hb_press_attributes,
|
||||
};
|
||||
static const struct attribute_group st_lps22hb_temp_attribute_group = {
|
||||
.attrs = st_lps22hb_temp_attributes,
|
||||
};
|
||||
|
||||
static const struct iio_info st_lps22hb_press_info = {
|
||||
.attrs = &st_lps22hb_press_attribute_group,
|
||||
.read_raw = st_lps22hb_read_raw,
|
||||
.write_raw = st_lps22hb_write_raw,
|
||||
};
|
||||
|
||||
static const struct iio_info st_lps22hb_temp_info = {
|
||||
.attrs = &st_lps22hb_temp_attribute_group,
|
||||
.read_raw = st_lps22hb_read_raw,
|
||||
.write_raw = st_lps22hb_write_raw,
|
||||
};
|
||||
|
||||
int st_lps22hb_common_probe(struct device *dev, int irq, const char *name,
|
||||
const struct st_lps22hb_transfer_function *tf_ops)
|
||||
{
|
||||
struct st_lps22hb_sensor *sensor;
|
||||
struct st_lps22hb_hw *hw;
|
||||
struct iio_dev *iio_dev;
|
||||
int err, i;
|
||||
|
||||
hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
|
||||
if (!hw)
|
||||
return -ENOMEM;
|
||||
|
||||
dev_set_drvdata(dev, (void *)hw);
|
||||
hw->dev = dev;
|
||||
hw->tf = tf_ops;
|
||||
hw->irq = irq;
|
||||
/* set initial watermark */
|
||||
hw->watermark = 1;
|
||||
|
||||
mutex_init(&hw->lock);
|
||||
mutex_init(&hw->fifo_lock);
|
||||
|
||||
err = st_lps22hb_check_whoami(hw);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
for (i = 0; i < ST_LPS22HB_SENSORS_NUMB; i++) {
|
||||
iio_dev = devm_iio_device_alloc(dev, sizeof(*sensor));
|
||||
if (!iio_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
hw->iio_devs[i] = iio_dev;
|
||||
sensor = iio_priv(iio_dev);
|
||||
sensor->hw = hw;
|
||||
sensor->type = i;
|
||||
sensor->odr = 1;
|
||||
|
||||
switch (i) {
|
||||
case ST_LPS22HB_PRESS:
|
||||
sensor->gain = ST_LPS22HB_PRESS_FS_AVL_GAIN;
|
||||
scnprintf(sensor->name, sizeof(sensor->name),
|
||||
"%s_press", name);
|
||||
iio_dev->channels = st_lps22hb_press_channels;
|
||||
iio_dev->num_channels =
|
||||
ARRAY_SIZE(st_lps22hb_press_channels);
|
||||
iio_dev->info = &st_lps22hb_press_info;
|
||||
break;
|
||||
case ST_LPS22HB_TEMP:
|
||||
sensor->gain = ST_LPS22HB_TEMP_FS_AVL_GAIN;
|
||||
scnprintf(sensor->name, sizeof(sensor->name),
|
||||
"%s_temp", name);
|
||||
iio_dev->channels = st_lps22hb_temp_channels;
|
||||
iio_dev->num_channels =
|
||||
ARRAY_SIZE(st_lps22hb_temp_channels);
|
||||
iio_dev->info = &st_lps22hb_temp_info;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
};
|
||||
iio_dev->name = sensor->name;
|
||||
iio_dev->modes = INDIO_DIRECT_MODE;
|
||||
}
|
||||
|
||||
err = st_lps22hb_init_sensors(hw);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (irq > 0) {
|
||||
err = st_lps22hb_allocate_buffers(hw);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
for (i = 0; i < ST_LPS22HB_SENSORS_NUMB; i++) {
|
||||
err = devm_iio_device_register(dev, hw->iio_devs[i]);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(st_lps22hb_common_probe);
|
||||
|
||||
MODULE_DESCRIPTION("STMicroelectronics lps22hb driver");
|
||||
MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
87
drivers/iio/stm/pressure/st_lps22hb_i2c.c
Normal file
87
drivers/iio/stm/pressure/st_lps22hb_i2c.c
Normal file
@ -0,0 +1,87 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* STMicroelectronics lps22hb i2c driver
|
||||
*
|
||||
* Copyright 2017 STMicroelectronics Inc.
|
||||
*
|
||||
* Lorenzo Bianconi <lorenzo.bianconi@st.com>
|
||||
*/
|
||||
|
||||
#include <linux/i2c.h>
|
||||
|
||||
#include "st_lps22hb.h"
|
||||
|
||||
static int st_lps22hb_i2c_read(struct device *dev, u8 addr, int len, u8 *data)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct i2c_msg msg[2];
|
||||
|
||||
msg[0].addr = client->addr;
|
||||
msg[0].flags = client->flags;
|
||||
msg[0].len = 1;
|
||||
msg[0].buf = &addr;
|
||||
|
||||
msg[1].addr = client->addr;
|
||||
msg[1].flags = client->flags | I2C_M_RD;
|
||||
msg[1].len = len;
|
||||
msg[1].buf = data;
|
||||
|
||||
return i2c_transfer(client->adapter, msg, 2);
|
||||
}
|
||||
|
||||
static int st_lps22hb_i2c_write(struct device *dev, u8 addr, int len, u8 *data)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct i2c_msg msg;
|
||||
u8 send[len + 1];
|
||||
|
||||
send[0] = addr;
|
||||
memcpy(&send[1], data, len * sizeof(u8));
|
||||
len++;
|
||||
|
||||
msg.addr = client->addr;
|
||||
msg.flags = client->flags;
|
||||
msg.len = len;
|
||||
msg.buf = send;
|
||||
|
||||
return i2c_transfer(client->adapter, &msg, 1);
|
||||
}
|
||||
|
||||
static const struct st_lps22hb_transfer_function st_lps22hb_tf_i2c = {
|
||||
.write = st_lps22hb_i2c_write,
|
||||
.read = st_lps22hb_i2c_read,
|
||||
};
|
||||
|
||||
static int st_lps22hb_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
return st_lps22hb_common_probe(&client->dev, client->irq, client->name,
|
||||
&st_lps22hb_tf_i2c);
|
||||
}
|
||||
|
||||
static const struct i2c_device_id st_lps22hb_ids[] = {
|
||||
{ "lps22hb" },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, st_lps22hb_ids);
|
||||
|
||||
static const struct of_device_id st_lps22hb_id_table[] = {
|
||||
{ .compatible = "st,lps22hb" },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, st_lps22hb_id_table);
|
||||
|
||||
static struct i2c_driver st_lps22hb_i2c_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "st_lps22hb_i2c",
|
||||
.of_match_table = of_match_ptr(st_lps22hb_id_table),
|
||||
},
|
||||
.probe = st_lps22hb_i2c_probe,
|
||||
.id_table = st_lps22hb_ids,
|
||||
};
|
||||
module_i2c_driver(st_lps22hb_i2c_driver);
|
||||
|
||||
MODULE_DESCRIPTION("STMicroelectronics lps22hb i2c driver");
|
||||
MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
97
drivers/iio/stm/pressure/st_lps22hb_spi.c
Normal file
97
drivers/iio/stm/pressure/st_lps22hb_spi.c
Normal file
@ -0,0 +1,97 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* STMicroelectronics lps22hb spi driver
|
||||
*
|
||||
* Copyright 2017 STMicroelectronics Inc.
|
||||
*
|
||||
* Lorenzo Bianconi <lorenzo.bianconi@st.com>
|
||||
*/
|
||||
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
#include "st_lps22hb.h"
|
||||
|
||||
#define ST_SENSORS_SPI_READ 0x80
|
||||
|
||||
static int st_lps22hb_spi_read(struct device *dev, u8 addr, int len, u8 *data)
|
||||
{
|
||||
struct spi_device *spi = to_spi_device(dev);
|
||||
struct st_lps22hb_hw *hw = spi_get_drvdata(spi);
|
||||
struct spi_transfer xfers[] = {
|
||||
{
|
||||
.tx_buf = hw->tb.tx_buf,
|
||||
.bits_per_word = 8,
|
||||
.len = 1,
|
||||
},
|
||||
{
|
||||
.rx_buf = hw->tb.rx_buf,
|
||||
.bits_per_word = 8,
|
||||
.len = len,
|
||||
}
|
||||
};
|
||||
int err;
|
||||
|
||||
hw->tb.tx_buf[0] = addr | ST_SENSORS_SPI_READ;
|
||||
err = spi_sync_transfer(spi, xfers, ARRAY_SIZE(xfers));
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
memcpy(data, hw->tb.rx_buf, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int st_lps22hb_spi_write(struct device *dev, u8 addr, int len, u8 *data)
|
||||
{
|
||||
struct st_lps22hb_hw *hw;
|
||||
struct spi_device *spi;
|
||||
|
||||
if (len >= ST_LPS22HB_TX_MAX_LENGTH)
|
||||
return -ENOMEM;
|
||||
|
||||
spi = to_spi_device(dev);
|
||||
hw = spi_get_drvdata(spi);
|
||||
|
||||
hw->tb.tx_buf[0] = addr;
|
||||
memcpy(&hw->tb.tx_buf[1], data, len);
|
||||
|
||||
return spi_write(spi, hw->tb.tx_buf, len + 1);
|
||||
}
|
||||
|
||||
static const struct st_lps22hb_transfer_function st_lps22hb_tf_spi = {
|
||||
.write = st_lps22hb_spi_write,
|
||||
.read = st_lps22hb_spi_read,
|
||||
};
|
||||
|
||||
static int st_lps22hb_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
return st_lps22hb_common_probe(&spi->dev, spi->irq, spi->modalias,
|
||||
&st_lps22hb_tf_spi);
|
||||
}
|
||||
|
||||
static const struct spi_device_id st_lps22hb_ids[] = {
|
||||
{ "lps22hb" },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, st_lps22hb_ids);
|
||||
|
||||
static const struct of_device_id st_lps22hb_id_table[] = {
|
||||
{ .compatible = "st,lps22hb" },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, st_lps22hb_id_table);
|
||||
|
||||
static struct spi_driver st_lps22hb_spi_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "st_lps22hb_spi",
|
||||
.of_match_table = of_match_ptr(st_lps22hb_id_table),
|
||||
},
|
||||
.probe = st_lps22hb_spi_probe,
|
||||
.id_table = st_lps22hb_ids,
|
||||
};
|
||||
module_spi_driver(st_lps22hb_spi_driver);
|
||||
|
||||
MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
|
||||
MODULE_DESCRIPTION("STMicroelectronics lps22hb spi driver");
|
||||
MODULE_LICENSE("GPL v2");
|
3
stm_iio_configs/lps22hb_defconfig
Normal file
3
stm_iio_configs/lps22hb_defconfig
Normal file
@ -0,0 +1,3 @@
|
||||
CONFIG_ST_LPS22HB_IIO=m
|
||||
CONFIG_ST_LPS22HB_I2C_IIO=m
|
||||
CONFIG_ST_LPS22HB_SPI_IIO=m
|
Loading…
Reference in New Issue
Block a user