Commit 217494e5b780ad85485c1bb6382ce50b5fa2dc26

Authored by Denis CIOCCA
Committed by Jonathan Cameron
1 parent 607a568ab6

iio:pressure: Add STMicroelectronics pressures driver

This patch adds a generic pressure driver for STMicroelectronics
pressure sensors, currently it supports: LPS331AP.

Signed-off-by: Denis Ciocca <denis.ciocca@st.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>

Showing 9 changed files with 616 additions and 0 deletions Side-by-side Diff

... ... @@ -73,6 +73,7 @@
73 73 if IIO_TRIGGER
74 74 source "drivers/iio/trigger/Kconfig"
75 75 endif #IIO_TRIGGER
  76 +source "drivers/iio/pressure/Kconfig"
76 77  
77 78 endif # IIO
drivers/iio/Makefile
... ... @@ -22,4 +22,5 @@
22 22 obj-y += light/
23 23 obj-y += magnetometer/
24 24 obj-y += trigger/
  25 +obj-y += pressure/
drivers/iio/pressure/Kconfig
  1 +#
  2 +# Pressure drivers
  3 +#
  4 +menu "Pressure Sensors"
  5 +
  6 +config IIO_ST_PRESS
  7 + tristate "STMicroelectronics pressures Driver"
  8 + depends on (I2C || SPI_MASTER) && SYSFS
  9 + select IIO_ST_SENSORS_CORE
  10 + select IIO_ST_PRESS_I2C if (I2C)
  11 + select IIO_ST_PRESS_SPI if (SPI_MASTER)
  12 + select IIO_TRIGGERED_BUFFER if (IIO_BUFFER)
  13 + help
  14 + Say yes here to build support for STMicroelectronics pressures:
  15 + LPS331AP.
  16 +
  17 + This driver can also be built as a module. If so, will be created
  18 + these modules:
  19 + - st_pressure (core functions for the driver [it is mandatory]);
  20 + - st_pressure_i2c (necessary for the I2C devices [optional*]);
  21 + - st_pressure_spi (necessary for the SPI devices [optional*]);
  22 +
  23 + (*) one of these is necessary to do something.
  24 +
  25 +config IIO_ST_PRESS_I2C
  26 + tristate
  27 + depends on IIO_ST_PRESS
  28 + depends on IIO_ST_SENSORS_I2C
  29 +
  30 +config IIO_ST_PRESS_SPI
  31 + tristate
  32 + depends on IIO_ST_PRESS
  33 + depends on IIO_ST_SENSORS_SPI
  34 +
  35 +endmenu
drivers/iio/pressure/Makefile
  1 +#
  2 +# Makefile for industrial I/O pressure drivers
  3 +#
  4 +
  5 +obj-$(CONFIG_IIO_ST_PRESS) += st_pressure.o
  6 +st_pressure-y := st_pressure_core.o
  7 +st_pressure-$(CONFIG_IIO_BUFFER) += st_pressure_buffer.o
  8 +
  9 +obj-$(CONFIG_IIO_ST_PRESS_I2C) += st_pressure_i2c.o
  10 +obj-$(CONFIG_IIO_ST_PRESS_SPI) += st_pressure_spi.o
drivers/iio/pressure/st_pressure.h
  1 +/*
  2 + * STMicroelectronics pressures driver
  3 + *
  4 + * Copyright 2013 STMicroelectronics Inc.
  5 + *
  6 + * Denis Ciocca <denis.ciocca@st.com>
  7 + * v. 1.0.0
  8 + * Licensed under the GPL-2.
  9 + */
  10 +
  11 +#ifndef ST_PRESS_H
  12 +#define ST_PRESS_H
  13 +
  14 +#include <linux/types.h>
  15 +#include <linux/iio/common/st_sensors.h>
  16 +
  17 +#define LPS331AP_PRESS_DEV_NAME "lps331ap"
  18 +
  19 +int st_press_common_probe(struct iio_dev *indio_dev);
  20 +void st_press_common_remove(struct iio_dev *indio_dev);
  21 +
  22 +#ifdef CONFIG_IIO_BUFFER
  23 +int st_press_allocate_ring(struct iio_dev *indio_dev);
  24 +void st_press_deallocate_ring(struct iio_dev *indio_dev);
  25 +int st_press_trig_set_state(struct iio_trigger *trig, bool state);
  26 +#define ST_PRESS_TRIGGER_SET_STATE (&st_press_trig_set_state)
  27 +#else /* CONFIG_IIO_BUFFER */
  28 +static inline int st_press_allocate_ring(struct iio_dev *indio_dev)
  29 +{
  30 + return 0;
  31 +}
  32 +
  33 +static inline void st_press_deallocate_ring(struct iio_dev *indio_dev)
  34 +{
  35 +}
  36 +#define ST_PRESS_TRIGGER_SET_STATE NULL
  37 +#endif /* CONFIG_IIO_BUFFER */
  38 +
  39 +#endif /* ST_PRESS_H */
drivers/iio/pressure/st_pressure_buffer.c
  1 +/*
  2 + * STMicroelectronics pressures driver
  3 + *
  4 + * Copyright 2013 STMicroelectronics Inc.
  5 + *
  6 + * Denis Ciocca <denis.ciocca@st.com>
  7 + *
  8 + * Licensed under the GPL-2.
  9 + */
  10 +
  11 +#include <linux/module.h>
  12 +#include <linux/kernel.h>
  13 +#include <linux/slab.h>
  14 +#include <linux/stat.h>
  15 +#include <linux/interrupt.h>
  16 +#include <linux/i2c.h>
  17 +#include <linux/delay.h>
  18 +#include <linux/iio/iio.h>
  19 +#include <linux/iio/buffer.h>
  20 +#include <linux/iio/trigger_consumer.h>
  21 +#include <linux/iio/triggered_buffer.h>
  22 +
  23 +#include <linux/iio/common/st_sensors.h>
  24 +#include "st_pressure.h"
  25 +
  26 +int st_press_trig_set_state(struct iio_trigger *trig, bool state)
  27 +{
  28 + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
  29 +
  30 + return st_sensors_set_dataready_irq(indio_dev, state);
  31 +}
  32 +
  33 +static int st_press_buffer_preenable(struct iio_dev *indio_dev)
  34 +{
  35 + int err;
  36 +
  37 + err = st_sensors_set_enable(indio_dev, true);
  38 + if (err < 0)
  39 + goto st_press_set_enable_error;
  40 +
  41 + err = iio_sw_buffer_preenable(indio_dev);
  42 +
  43 +st_press_set_enable_error:
  44 + return err;
  45 +}
  46 +
  47 +static int st_press_buffer_postenable(struct iio_dev *indio_dev)
  48 +{
  49 + int err;
  50 + struct st_sensor_data *pdata = iio_priv(indio_dev);
  51 +
  52 + pdata->buffer_data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
  53 + if (pdata->buffer_data == NULL) {
  54 + err = -ENOMEM;
  55 + goto allocate_memory_error;
  56 + }
  57 +
  58 + err = iio_triggered_buffer_postenable(indio_dev);
  59 + if (err < 0)
  60 + goto st_press_buffer_postenable_error;
  61 +
  62 + return err;
  63 +
  64 +st_press_buffer_postenable_error:
  65 + kfree(pdata->buffer_data);
  66 +allocate_memory_error:
  67 + return err;
  68 +}
  69 +
  70 +static int st_press_buffer_predisable(struct iio_dev *indio_dev)
  71 +{
  72 + int err;
  73 + struct st_sensor_data *pdata = iio_priv(indio_dev);
  74 +
  75 + err = iio_triggered_buffer_predisable(indio_dev);
  76 + if (err < 0)
  77 + goto st_press_buffer_predisable_error;
  78 +
  79 + err = st_sensors_set_enable(indio_dev, false);
  80 +
  81 +st_press_buffer_predisable_error:
  82 + kfree(pdata->buffer_data);
  83 + return err;
  84 +}
  85 +
  86 +static const struct iio_buffer_setup_ops st_press_buffer_setup_ops = {
  87 + .preenable = &st_press_buffer_preenable,
  88 + .postenable = &st_press_buffer_postenable,
  89 + .predisable = &st_press_buffer_predisable,
  90 +};
  91 +
  92 +int st_press_allocate_ring(struct iio_dev *indio_dev)
  93 +{
  94 + return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
  95 + &st_sensors_trigger_handler, &st_press_buffer_setup_ops);
  96 +}
  97 +
  98 +void st_press_deallocate_ring(struct iio_dev *indio_dev)
  99 +{
  100 + iio_triggered_buffer_cleanup(indio_dev);
  101 +}
  102 +
  103 +MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
  104 +MODULE_DESCRIPTION("STMicroelectronics pressures buffer");
  105 +MODULE_LICENSE("GPL v2");
drivers/iio/pressure/st_pressure_core.c
  1 +/*
  2 + * STMicroelectronics pressures driver
  3 + *
  4 + * Copyright 2013 STMicroelectronics Inc.
  5 + *
  6 + * Denis Ciocca <denis.ciocca@st.com>
  7 + *
  8 + * Licensed under the GPL-2.
  9 + */
  10 +
  11 +#include <linux/kernel.h>
  12 +#include <linux/module.h>
  13 +#include <linux/slab.h>
  14 +#include <linux/errno.h>
  15 +#include <linux/types.h>
  16 +#include <linux/mutex.h>
  17 +#include <linux/interrupt.h>
  18 +#include <linux/i2c.h>
  19 +#include <linux/gpio.h>
  20 +#include <linux/irq.h>
  21 +#include <linux/delay.h>
  22 +#include <linux/iio/iio.h>
  23 +#include <linux/iio/sysfs.h>
  24 +#include <linux/iio/trigger.h>
  25 +#include <linux/iio/buffer.h>
  26 +#include <asm/unaligned.h>
  27 +
  28 +#include <linux/iio/common/st_sensors.h>
  29 +#include "st_pressure.h"
  30 +
  31 +#define ST_PRESS_MBAR_TO_KPASCAL(x) (x * 10)
  32 +#define ST_PRESS_NUMBER_DATA_CHANNELS 1
  33 +
  34 +/* DEFAULT VALUE FOR SENSORS */
  35 +#define ST_PRESS_DEFAULT_OUT_XL_ADDR 0x28
  36 +#define ST_TEMP_DEFAULT_OUT_L_ADDR 0x2b
  37 +
  38 +/* FULLSCALE */
  39 +#define ST_PRESS_FS_AVL_1260MB 1260
  40 +
  41 +/* CUSTOM VALUES FOR SENSOR 1 */
  42 +#define ST_PRESS_1_WAI_EXP 0xbb
  43 +#define ST_PRESS_1_ODR_ADDR 0x20
  44 +#define ST_PRESS_1_ODR_MASK 0x70
  45 +#define ST_PRESS_1_ODR_AVL_1HZ_VAL 0x01
  46 +#define ST_PRESS_1_ODR_AVL_7HZ_VAL 0x05
  47 +#define ST_PRESS_1_ODR_AVL_13HZ_VAL 0x06
  48 +#define ST_PRESS_1_ODR_AVL_25HZ_VAL 0x07
  49 +#define ST_PRESS_1_PW_ADDR 0x20
  50 +#define ST_PRESS_1_PW_MASK 0x80
  51 +#define ST_PRESS_1_FS_ADDR 0x23
  52 +#define ST_PRESS_1_FS_MASK 0x30
  53 +#define ST_PRESS_1_FS_AVL_1260_VAL 0x00
  54 +#define ST_PRESS_1_FS_AVL_1260_GAIN ST_PRESS_MBAR_TO_KPASCAL(244141)
  55 +#define ST_PRESS_1_FS_AVL_TEMP_GAIN 2083000
  56 +#define ST_PRESS_1_BDU_ADDR 0x20
  57 +#define ST_PRESS_1_BDU_MASK 0x04
  58 +#define ST_PRESS_1_DRDY_IRQ_ADDR 0x22
  59 +#define ST_PRESS_1_DRDY_IRQ_MASK 0x04
  60 +#define ST_PRESS_1_MULTIREAD_BIT true
  61 +#define ST_PRESS_1_TEMP_OFFSET 42500
  62 +
  63 +static const struct iio_chan_spec st_press_channels[] = {
  64 + ST_SENSORS_LSM_CHANNELS(IIO_PRESSURE,
  65 + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
  66 + ST_SENSORS_SCAN_X, 0, IIO_NO_MOD, 'u', IIO_LE, 24, 24,
  67 + ST_PRESS_DEFAULT_OUT_XL_ADDR),
  68 + ST_SENSORS_LSM_CHANNELS(IIO_TEMP,
  69 + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
  70 + BIT(IIO_CHAN_INFO_OFFSET),
  71 + -1, 0, IIO_NO_MOD, 's', IIO_LE, 16, 16,
  72 + ST_TEMP_DEFAULT_OUT_L_ADDR),
  73 + IIO_CHAN_SOFT_TIMESTAMP(1)
  74 +};
  75 +
  76 +static const struct st_sensors st_press_sensors[] = {
  77 + {
  78 + .wai = ST_PRESS_1_WAI_EXP,
  79 + .sensors_supported = {
  80 + [0] = LPS331AP_PRESS_DEV_NAME,
  81 + },
  82 + .ch = (struct iio_chan_spec *)st_press_channels,
  83 + .odr = {
  84 + .addr = ST_PRESS_1_ODR_ADDR,
  85 + .mask = ST_PRESS_1_ODR_MASK,
  86 + .odr_avl = {
  87 + { 1, ST_PRESS_1_ODR_AVL_1HZ_VAL, },
  88 + { 7, ST_PRESS_1_ODR_AVL_7HZ_VAL, },
  89 + { 13, ST_PRESS_1_ODR_AVL_13HZ_VAL, },
  90 + { 25, ST_PRESS_1_ODR_AVL_25HZ_VAL, },
  91 + },
  92 + },
  93 + .pw = {
  94 + .addr = ST_PRESS_1_PW_ADDR,
  95 + .mask = ST_PRESS_1_PW_MASK,
  96 + .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
  97 + .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
  98 + },
  99 + .fs = {
  100 + .addr = ST_PRESS_1_FS_ADDR,
  101 + .mask = ST_PRESS_1_FS_MASK,
  102 + .fs_avl = {
  103 + [0] = {
  104 + .num = ST_PRESS_FS_AVL_1260MB,
  105 + .value = ST_PRESS_1_FS_AVL_1260_VAL,
  106 + .gain = ST_PRESS_1_FS_AVL_1260_GAIN,
  107 + .gain2 = ST_PRESS_1_FS_AVL_TEMP_GAIN,
  108 + },
  109 + },
  110 + },
  111 + .bdu = {
  112 + .addr = ST_PRESS_1_BDU_ADDR,
  113 + .mask = ST_PRESS_1_BDU_MASK,
  114 + },
  115 + .drdy_irq = {
  116 + .addr = ST_PRESS_1_DRDY_IRQ_ADDR,
  117 + .mask = ST_PRESS_1_DRDY_IRQ_MASK,
  118 + },
  119 + .multi_read_bit = ST_PRESS_1_MULTIREAD_BIT,
  120 + .bootime = 2,
  121 + },
  122 +};
  123 +
  124 +static int st_press_read_raw(struct iio_dev *indio_dev,
  125 + struct iio_chan_spec const *ch, int *val,
  126 + int *val2, long mask)
  127 +{
  128 + int err;
  129 + struct st_sensor_data *pdata = iio_priv(indio_dev);
  130 +
  131 + switch (mask) {
  132 + case IIO_CHAN_INFO_RAW:
  133 + err = st_sensors_read_info_raw(indio_dev, ch, val);
  134 + if (err < 0)
  135 + goto read_error;
  136 +
  137 + return IIO_VAL_INT;
  138 + case IIO_CHAN_INFO_SCALE:
  139 + *val = 0;
  140 +
  141 + switch (ch->type) {
  142 + case IIO_PRESSURE:
  143 + *val2 = pdata->current_fullscale->gain;
  144 + break;
  145 + case IIO_TEMP:
  146 + *val2 = pdata->current_fullscale->gain2;
  147 + break;
  148 + default:
  149 + err = -EINVAL;
  150 + goto read_error;
  151 + }
  152 +
  153 + return IIO_VAL_INT_PLUS_NANO;
  154 + case IIO_CHAN_INFO_OFFSET:
  155 + switch (ch->type) {
  156 + case IIO_TEMP:
  157 + *val = 425;
  158 + *val2 = 10;
  159 + break;
  160 + default:
  161 + err = -EINVAL;
  162 + goto read_error;
  163 + }
  164 +
  165 + return IIO_VAL_FRACTIONAL;
  166 + default:
  167 + return -EINVAL;
  168 + }
  169 +
  170 +read_error:
  171 + return err;
  172 +}
  173 +
  174 +static ST_SENSOR_DEV_ATTR_SAMP_FREQ();
  175 +static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
  176 +
  177 +static struct attribute *st_press_attributes[] = {
  178 + &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
  179 + &iio_dev_attr_sampling_frequency.dev_attr.attr,
  180 + NULL,
  181 +};
  182 +
  183 +static const struct attribute_group st_press_attribute_group = {
  184 + .attrs = st_press_attributes,
  185 +};
  186 +
  187 +static const struct iio_info press_info = {
  188 + .driver_module = THIS_MODULE,
  189 + .attrs = &st_press_attribute_group,
  190 + .read_raw = &st_press_read_raw,
  191 +};
  192 +
  193 +#ifdef CONFIG_IIO_TRIGGER
  194 +static const struct iio_trigger_ops st_press_trigger_ops = {
  195 + .owner = THIS_MODULE,
  196 + .set_trigger_state = ST_PRESS_TRIGGER_SET_STATE,
  197 +};
  198 +#define ST_PRESS_TRIGGER_OPS (&st_press_trigger_ops)
  199 +#else
  200 +#define ST_PRESS_TRIGGER_OPS NULL
  201 +#endif
  202 +
  203 +int st_press_common_probe(struct iio_dev *indio_dev)
  204 +{
  205 + int err;
  206 + struct st_sensor_data *pdata = iio_priv(indio_dev);
  207 +
  208 + indio_dev->modes = INDIO_DIRECT_MODE;
  209 + indio_dev->info = &press_info;
  210 +
  211 + err = st_sensors_check_device_support(indio_dev,
  212 + ARRAY_SIZE(st_press_sensors), st_press_sensors);
  213 + if (err < 0)
  214 + goto st_press_common_probe_error;
  215 +
  216 + pdata->num_data_channels = ST_PRESS_NUMBER_DATA_CHANNELS;
  217 + pdata->multiread_bit = pdata->sensor->multi_read_bit;
  218 + indio_dev->channels = pdata->sensor->ch;
  219 + indio_dev->num_channels = ARRAY_SIZE(st_press_channels);
  220 +
  221 + pdata->current_fullscale = (struct st_sensor_fullscale_avl *)
  222 + &pdata->sensor->fs.fs_avl[0];
  223 + pdata->odr = pdata->sensor->odr.odr_avl[0].hz;
  224 +
  225 + err = st_sensors_init_sensor(indio_dev);
  226 + if (err < 0)
  227 + goto st_press_common_probe_error;
  228 +
  229 + if (pdata->get_irq_data_ready(indio_dev) > 0) {
  230 + err = st_press_allocate_ring(indio_dev);
  231 + if (err < 0)
  232 + goto st_press_common_probe_error;
  233 +
  234 + err = st_sensors_allocate_trigger(indio_dev,
  235 + ST_PRESS_TRIGGER_OPS);
  236 + if (err < 0)
  237 + goto st_press_probe_trigger_error;
  238 + }
  239 +
  240 + err = iio_device_register(indio_dev);
  241 + if (err)
  242 + goto st_press_device_register_error;
  243 +
  244 + return err;
  245 +
  246 +st_press_device_register_error:
  247 + if (pdata->get_irq_data_ready(indio_dev) > 0)
  248 + st_sensors_deallocate_trigger(indio_dev);
  249 +st_press_probe_trigger_error:
  250 + if (pdata->get_irq_data_ready(indio_dev) > 0)
  251 + st_press_deallocate_ring(indio_dev);
  252 +st_press_common_probe_error:
  253 + return err;
  254 +}
  255 +EXPORT_SYMBOL(st_press_common_probe);
  256 +
  257 +void st_press_common_remove(struct iio_dev *indio_dev)
  258 +{
  259 + struct st_sensor_data *pdata = iio_priv(indio_dev);
  260 +
  261 + iio_device_unregister(indio_dev);
  262 + if (pdata->get_irq_data_ready(indio_dev) > 0) {
  263 + st_sensors_deallocate_trigger(indio_dev);
  264 + st_press_deallocate_ring(indio_dev);
  265 + }
  266 + iio_device_free(indio_dev);
  267 +}
  268 +EXPORT_SYMBOL(st_press_common_remove);
  269 +
  270 +MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
  271 +MODULE_DESCRIPTION("STMicroelectronics pressures driver");
  272 +MODULE_LICENSE("GPL v2");
drivers/iio/pressure/st_pressure_i2c.c
  1 +/*
  2 + * STMicroelectronics pressures driver
  3 + *
  4 + * Copyright 2013 STMicroelectronics Inc.
  5 + *
  6 + * Denis Ciocca <denis.ciocca@st.com>
  7 + *
  8 + * Licensed under the GPL-2.
  9 + */
  10 +
  11 +#include <linux/kernel.h>
  12 +#include <linux/module.h>
  13 +#include <linux/slab.h>
  14 +#include <linux/i2c.h>
  15 +#include <linux/iio/iio.h>
  16 +
  17 +#include <linux/iio/common/st_sensors.h>
  18 +#include <linux/iio/common/st_sensors_i2c.h>
  19 +#include "st_pressure.h"
  20 +
  21 +static int st_press_i2c_probe(struct i2c_client *client,
  22 + const struct i2c_device_id *id)
  23 +{
  24 + struct iio_dev *indio_dev;
  25 + struct st_sensor_data *pdata;
  26 + int err;
  27 +
  28 + indio_dev = iio_device_alloc(sizeof(*pdata));
  29 + if (indio_dev == NULL) {
  30 + err = -ENOMEM;
  31 + goto iio_device_alloc_error;
  32 + }
  33 +
  34 + pdata = iio_priv(indio_dev);
  35 + pdata->dev = &client->dev;
  36 +
  37 + st_sensors_i2c_configure(indio_dev, client, pdata);
  38 +
  39 + err = st_press_common_probe(indio_dev);
  40 + if (err < 0)
  41 + goto st_press_common_probe_error;
  42 +
  43 + return 0;
  44 +
  45 +st_press_common_probe_error:
  46 + iio_device_free(indio_dev);
  47 +iio_device_alloc_error:
  48 + return err;
  49 +}
  50 +
  51 +static int st_press_i2c_remove(struct i2c_client *client)
  52 +{
  53 + st_press_common_remove(i2c_get_clientdata(client));
  54 +
  55 + return 0;
  56 +}
  57 +
  58 +static const struct i2c_device_id st_press_id_table[] = {
  59 + { LPS331AP_PRESS_DEV_NAME },
  60 + {},
  61 +};
  62 +MODULE_DEVICE_TABLE(i2c, st_press_id_table);
  63 +
  64 +static struct i2c_driver st_press_driver = {
  65 + .driver = {
  66 + .owner = THIS_MODULE,
  67 + .name = "st-press-i2c",
  68 + },
  69 + .probe = st_press_i2c_probe,
  70 + .remove = st_press_i2c_remove,
  71 + .id_table = st_press_id_table,
  72 +};
  73 +module_i2c_driver(st_press_driver);
  74 +
  75 +MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
  76 +MODULE_DESCRIPTION("STMicroelectronics pressures i2c driver");
  77 +MODULE_LICENSE("GPL v2");
drivers/iio/pressure/st_pressure_spi.c
  1 +/*
  2 + * STMicroelectronics pressures driver
  3 + *
  4 + * Copyright 2013 STMicroelectronics Inc.
  5 + *
  6 + * Denis Ciocca <denis.ciocca@st.com>
  7 + *
  8 + * Licensed under the GPL-2.
  9 + */
  10 +
  11 +#include <linux/kernel.h>
  12 +#include <linux/module.h>
  13 +#include <linux/slab.h>
  14 +#include <linux/spi/spi.h>
  15 +#include <linux/iio/iio.h>
  16 +
  17 +#include <linux/iio/common/st_sensors.h>
  18 +#include <linux/iio/common/st_sensors_spi.h>
  19 +#include "st_pressure.h"
  20 +
  21 +static int st_press_spi_probe(struct spi_device *spi)
  22 +{
  23 + struct iio_dev *indio_dev;
  24 + struct st_sensor_data *pdata;
  25 + int err;
  26 +
  27 + indio_dev = iio_device_alloc(sizeof(*pdata));
  28 + if (indio_dev == NULL) {
  29 + err = -ENOMEM;
  30 + goto iio_device_alloc_error;
  31 + }
  32 +
  33 + pdata = iio_priv(indio_dev);
  34 + pdata->dev = &spi->dev;
  35 +
  36 + st_sensors_spi_configure(indio_dev, spi, pdata);
  37 +
  38 + err = st_press_common_probe(indio_dev);
  39 + if (err < 0)
  40 + goto st_press_common_probe_error;
  41 +
  42 + return 0;
  43 +
  44 +st_press_common_probe_error:
  45 + iio_device_free(indio_dev);
  46 +iio_device_alloc_error:
  47 + return err;
  48 +}
  49 +
  50 +static int st_press_spi_remove(struct spi_device *spi)
  51 +{
  52 + st_press_common_remove(spi_get_drvdata(spi));
  53 +
  54 + return 0;
  55 +}
  56 +
  57 +static const struct spi_device_id st_press_id_table[] = {
  58 + { LPS331AP_PRESS_DEV_NAME },
  59 + {},
  60 +};
  61 +MODULE_DEVICE_TABLE(spi, st_press_id_table);
  62 +
  63 +static struct spi_driver st_press_driver = {
  64 + .driver = {
  65 + .owner = THIS_MODULE,
  66 + .name = "st-press-spi",
  67 + },
  68 + .probe = st_press_spi_probe,
  69 + .remove = st_press_spi_remove,
  70 + .id_table = st_press_id_table,
  71 +};
  72 +module_spi_driver(st_press_driver);
  73 +
  74 +MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
  75 +MODULE_DESCRIPTION("STMicroelectronics pressures spi driver");
  76 +MODULE_LICENSE("GPL v2");