xref: /linux/drivers/iio/pressure/st_pressure_core.c (revision 2c1ed907520c50326b8f604907a8478b27881a2e)
1fda8d26eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2217494e5SDenis CIOCCA /*
3217494e5SDenis CIOCCA  * STMicroelectronics pressures driver
4217494e5SDenis CIOCCA  *
5217494e5SDenis CIOCCA  * Copyright 2013 STMicroelectronics Inc.
6217494e5SDenis CIOCCA  *
7217494e5SDenis CIOCCA  * Denis Ciocca <denis.ciocca@st.com>
8217494e5SDenis CIOCCA  */
9217494e5SDenis CIOCCA 
10217494e5SDenis CIOCCA #include <linux/kernel.h>
11217494e5SDenis CIOCCA #include <linux/module.h>
129c6cd755SJonathan Cameron #include <linux/mutex.h>
139c6cd755SJonathan Cameron #include <linux/sysfs.h>
14217494e5SDenis CIOCCA #include <linux/iio/iio.h>
15217494e5SDenis CIOCCA #include <linux/iio/sysfs.h>
16217494e5SDenis CIOCCA #include <linux/iio/trigger.h>
175f60d5f6SAl Viro #include <linux/unaligned.h>
18217494e5SDenis CIOCCA 
19217494e5SDenis CIOCCA #include <linux/iio/common/st_sensors.h>
20217494e5SDenis CIOCCA #include "st_pressure.h"
21217494e5SDenis CIOCCA 
2219b7b8a8SGregor Boirie /*
2319b7b8a8SGregor Boirie  * About determining pressure scaling factors
2419b7b8a8SGregor Boirie  * ------------------------------------------
2519b7b8a8SGregor Boirie  *
2619b7b8a8SGregor Boirie  * Datasheets specify typical pressure sensitivity so that pressure is computed
2719b7b8a8SGregor Boirie  * according to the following equation :
2819b7b8a8SGregor Boirie  *     pressure[mBar] = raw / sensitivity
2919b7b8a8SGregor Boirie  * where :
3019b7b8a8SGregor Boirie  *     raw          the 24 bits long raw sampled pressure
3119b7b8a8SGregor Boirie  *     sensitivity  a scaling factor specified by the datasheet in LSB/mBar
3219b7b8a8SGregor Boirie  *
3319b7b8a8SGregor Boirie  * IIO ABI expects pressure to be expressed as kPascal, hence pressure should be
3419b7b8a8SGregor Boirie  * computed according to :
3519b7b8a8SGregor Boirie  *     pressure[kPascal] = pressure[mBar] / 10
3619b7b8a8SGregor Boirie  *                       = raw / (sensitivity * 10)                          (1)
3719b7b8a8SGregor Boirie  *
3819b7b8a8SGregor Boirie  * Finally, st_press_read_raw() returns pressure scaling factor as an
3919b7b8a8SGregor Boirie  * IIO_VAL_INT_PLUS_NANO with a zero integral part and "gain" as decimal part.
4019b7b8a8SGregor Boirie  * Therefore, from (1), "gain" becomes :
4119b7b8a8SGregor Boirie  *     gain = 10^9 / (sensitivity * 10)
4219b7b8a8SGregor Boirie  *          = 10^8 / sensitivity
4319b7b8a8SGregor Boirie  *
4419b7b8a8SGregor Boirie  * About determining temperature scaling factors and offsets
4519b7b8a8SGregor Boirie  * ---------------------------------------------------------
4619b7b8a8SGregor Boirie  *
4719b7b8a8SGregor Boirie  * Datasheets specify typical temperature sensitivity and offset so that
4819b7b8a8SGregor Boirie  * temperature is computed according to the following equation :
4919b7b8a8SGregor Boirie  *     temp[Celsius] = offset[Celsius] + (raw / sensitivity)
5019b7b8a8SGregor Boirie  * where :
5119b7b8a8SGregor Boirie  *     raw          the 16 bits long raw sampled temperature
5219b7b8a8SGregor Boirie  *     offset       a constant specified by the datasheet in degree Celsius
5319b7b8a8SGregor Boirie  *                  (sometimes zero)
5419b7b8a8SGregor Boirie  *     sensitivity  a scaling factor specified by the datasheet in LSB/Celsius
5519b7b8a8SGregor Boirie  *
5619b7b8a8SGregor Boirie  * IIO ABI expects temperature to be expressed as milli degree Celsius such as
5719b7b8a8SGregor Boirie  * user space should compute temperature according to :
5819b7b8a8SGregor Boirie  *     temp[mCelsius] = temp[Celsius] * 10^3
5919b7b8a8SGregor Boirie  *                    = (offset[Celsius] + (raw / sensitivity)) * 10^3
6019b7b8a8SGregor Boirie  *                    = ((offset[Celsius] * sensitivity) + raw) *
6119b7b8a8SGregor Boirie  *                      (10^3 / sensitivity)                                 (2)
6219b7b8a8SGregor Boirie  *
6319b7b8a8SGregor Boirie  * IIO ABI expects user space to apply offset and scaling factors to raw samples
6419b7b8a8SGregor Boirie  * according to :
6519b7b8a8SGregor Boirie  *     temp[mCelsius] = (OFFSET + raw) * SCALE
6619b7b8a8SGregor Boirie  * where :
6719b7b8a8SGregor Boirie  *     OFFSET an arbitrary constant exposed by device
6819b7b8a8SGregor Boirie  *     SCALE  an arbitrary scaling factor exposed by device
6919b7b8a8SGregor Boirie  *
7019b7b8a8SGregor Boirie  * Matching OFFSET and SCALE with members of (2) gives :
7119b7b8a8SGregor Boirie  *     OFFSET = offset[Celsius] * sensitivity                                (3)
7219b7b8a8SGregor Boirie  *     SCALE  = 10^3 / sensitivity                                           (4)
7319b7b8a8SGregor Boirie  *
7419b7b8a8SGregor Boirie  * st_press_read_raw() returns temperature scaling factor as an
7519b7b8a8SGregor Boirie  * IIO_VAL_FRACTIONAL with a 10^3 numerator and "gain2" as denominator.
7619b7b8a8SGregor Boirie  * Therefore, from (3), "gain2" becomes :
7719b7b8a8SGregor Boirie  *     gain2 = sensitivity
7819b7b8a8SGregor Boirie  *
7919b7b8a8SGregor Boirie  * When declared within channel, i.e. for a non zero specified offset,
8019b7b8a8SGregor Boirie  * st_press_read_raw() will return the latter as an IIO_VAL_FRACTIONAL such as :
8119b7b8a8SGregor Boirie  *     numerator = OFFSET * 10^3
8219b7b8a8SGregor Boirie  *     denominator = 10^3
8319b7b8a8SGregor Boirie  * giving from (4):
8419b7b8a8SGregor Boirie  *     numerator = offset[Celsius] * 10^3 * sensitivity
8519b7b8a8SGregor Boirie  *               = offset[mCelsius] * gain2
8619b7b8a8SGregor Boirie  */
8719b7b8a8SGregor Boirie 
88d43a4115SGregor Boirie #define MCELSIUS_PER_CELSIUS			1000
89d43a4115SGregor Boirie 
90d43a4115SGregor Boirie /* Default pressure sensitivity */
9167dbf54aSJacek Anaszewski #define ST_PRESS_LSB_PER_MBAR			4096UL
9267dbf54aSJacek Anaszewski #define ST_PRESS_KPASCAL_NANO_SCALE		(100000000UL / \
9367dbf54aSJacek Anaszewski 						 ST_PRESS_LSB_PER_MBAR)
94d43a4115SGregor Boirie 
95d43a4115SGregor Boirie /* Default temperature sensitivity */
961003eb67SJacek Anaszewski #define ST_PRESS_LSB_PER_CELSIUS		480UL
97d43a4115SGregor Boirie #define ST_PRESS_MILLI_CELSIUS_OFFSET		42500UL
98d43a4115SGregor Boirie 
99217494e5SDenis CIOCCA /* FULLSCALE */
100d43a4115SGregor Boirie #define ST_PRESS_FS_AVL_1100MB			1100
101217494e5SDenis CIOCCA #define ST_PRESS_FS_AVL_1260MB			1260
102217494e5SDenis CIOCCA 
10393187840SDenis CIOCCA #define ST_PRESS_1_OUT_XL_ADDR			0x28
10493187840SDenis CIOCCA #define ST_TEMP_1_OUT_L_ADDR			0x2b
10593187840SDenis CIOCCA 
106d43a4115SGregor Boirie /* LPS001WP pressure resolution */
107d43a4115SGregor Boirie #define ST_PRESS_LPS001WP_LSB_PER_MBAR		16UL
108d43a4115SGregor Boirie /* LPS001WP temperature resolution */
109d43a4115SGregor Boirie #define ST_PRESS_LPS001WP_LSB_PER_CELSIUS	64UL
11091a86a3bSLinus Walleij /* LPS001WP pressure gain */
111d43a4115SGregor Boirie #define ST_PRESS_LPS001WP_FS_AVL_PRESS_GAIN \
112d43a4115SGregor Boirie 	(100000000UL / ST_PRESS_LPS001WP_LSB_PER_MBAR)
11391a86a3bSLinus Walleij /* LPS001WP pressure and temp L addresses */
1147885a8ceSLee Jones #define ST_PRESS_LPS001WP_OUT_L_ADDR		0x28
1157885a8ceSLee Jones #define ST_TEMP_LPS001WP_OUT_L_ADDR		0x2a
1167885a8ceSLee Jones 
11791a86a3bSLinus Walleij /* LPS25H pressure and temp L addresses */
11893187840SDenis CIOCCA #define ST_PRESS_LPS25H_OUT_XL_ADDR		0x28
11993187840SDenis CIOCCA #define ST_TEMP_LPS25H_OUT_L_ADDR		0x2b
12093187840SDenis CIOCCA 
12185d79136SGregor Boirie /* LPS22HB temperature sensitivity */
12285d79136SGregor Boirie #define ST_PRESS_LPS22HB_LSB_PER_CELSIUS	100UL
12385d79136SGregor Boirie 
12493187840SDenis CIOCCA static const struct iio_chan_spec st_press_1_channels[] = {
1252f5effcbSLee Jones 	{
1262f5effcbSLee Jones 		.type = IIO_PRESSURE,
12793187840SDenis CIOCCA 		.address = ST_PRESS_1_OUT_XL_ADDR,
128b4701fd6SGregor Boirie 		.scan_index = 0,
1292f5effcbSLee Jones 		.scan_type = {
1301b211d48SMarcin Niestroj 			.sign = 's',
1312f5effcbSLee Jones 			.realbits = 24,
132c9d5e5b9SGregor Boirie 			.storagebits = 32,
1332f5effcbSLee Jones 			.endianness = IIO_LE,
1342f5effcbSLee Jones 		},
1352f5effcbSLee Jones 		.info_mask_separate =
136217494e5SDenis CIOCCA 			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
1377f0d8740SMarcin Niestroj 		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
1382f5effcbSLee Jones 	},
1392f5effcbSLee Jones 	{
1402f5effcbSLee Jones 		.type = IIO_TEMP,
14193187840SDenis CIOCCA 		.address = ST_TEMP_1_OUT_L_ADDR,
142b4701fd6SGregor Boirie 		.scan_index = 1,
1432f5effcbSLee Jones 		.scan_type = {
1441b211d48SMarcin Niestroj 			.sign = 's',
1452f5effcbSLee Jones 			.realbits = 16,
1462f5effcbSLee Jones 			.storagebits = 16,
1472f5effcbSLee Jones 			.endianness = IIO_LE,
1482f5effcbSLee Jones 		},
1492f5effcbSLee Jones 		.info_mask_separate =
1502f5effcbSLee Jones 			BIT(IIO_CHAN_INFO_RAW) |
1512f5effcbSLee Jones 			BIT(IIO_CHAN_INFO_SCALE) |
152217494e5SDenis CIOCCA 			BIT(IIO_CHAN_INFO_OFFSET),
1537f0d8740SMarcin Niestroj 		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
1542f5effcbSLee Jones 	},
155b4701fd6SGregor Boirie 	IIO_CHAN_SOFT_TIMESTAMP(2)
156217494e5SDenis CIOCCA };
157217494e5SDenis CIOCCA 
1587885a8ceSLee Jones static const struct iio_chan_spec st_press_lps001wp_channels[] = {
1597885a8ceSLee Jones 	{
1607885a8ceSLee Jones 		.type = IIO_PRESSURE,
1617885a8ceSLee Jones 		.address = ST_PRESS_LPS001WP_OUT_L_ADDR,
162b4701fd6SGregor Boirie 		.scan_index = 0,
1637885a8ceSLee Jones 		.scan_type = {
1641b211d48SMarcin Niestroj 			.sign = 's',
1657885a8ceSLee Jones 			.realbits = 16,
1667885a8ceSLee Jones 			.storagebits = 16,
1677885a8ceSLee Jones 			.endianness = IIO_LE,
1687885a8ceSLee Jones 		},
169d43a4115SGregor Boirie 		.info_mask_separate =
170d43a4115SGregor Boirie 			BIT(IIO_CHAN_INFO_RAW) |
171d43a4115SGregor Boirie 			BIT(IIO_CHAN_INFO_SCALE),
1727885a8ceSLee Jones 	},
1737885a8ceSLee Jones 	{
1747885a8ceSLee Jones 		.type = IIO_TEMP,
1757885a8ceSLee Jones 		.address = ST_TEMP_LPS001WP_OUT_L_ADDR,
176b4701fd6SGregor Boirie 		.scan_index = 1,
1777885a8ceSLee Jones 		.scan_type = {
1781b211d48SMarcin Niestroj 			.sign = 's',
1797885a8ceSLee Jones 			.realbits = 16,
1807885a8ceSLee Jones 			.storagebits = 16,
1817885a8ceSLee Jones 			.endianness = IIO_LE,
1827885a8ceSLee Jones 		},
1837885a8ceSLee Jones 		.info_mask_separate =
1847885a8ceSLee Jones 			BIT(IIO_CHAN_INFO_RAW) |
185d43a4115SGregor Boirie 			BIT(IIO_CHAN_INFO_SCALE),
1867885a8ceSLee Jones 	},
187b4701fd6SGregor Boirie 	IIO_CHAN_SOFT_TIMESTAMP(2)
1887885a8ceSLee Jones };
1897885a8ceSLee Jones 
190e039e2f5SGregor Boirie static const struct iio_chan_spec st_press_lps22hb_channels[] = {
191e039e2f5SGregor Boirie 	{
192e039e2f5SGregor Boirie 		.type = IIO_PRESSURE,
193e039e2f5SGregor Boirie 		.address = ST_PRESS_1_OUT_XL_ADDR,
194e039e2f5SGregor Boirie 		.scan_index = 0,
195e039e2f5SGregor Boirie 		.scan_type = {
1961b211d48SMarcin Niestroj 			.sign = 's',
197e039e2f5SGregor Boirie 			.realbits = 24,
198c9d5e5b9SGregor Boirie 			.storagebits = 32,
199e039e2f5SGregor Boirie 			.endianness = IIO_LE,
200e039e2f5SGregor Boirie 		},
201e039e2f5SGregor Boirie 		.info_mask_separate =
202e039e2f5SGregor Boirie 			BIT(IIO_CHAN_INFO_RAW) |
203e039e2f5SGregor Boirie 			BIT(IIO_CHAN_INFO_SCALE),
204e039e2f5SGregor Boirie 		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
205e039e2f5SGregor Boirie 	},
20685d79136SGregor Boirie 	{
20785d79136SGregor Boirie 		.type = IIO_TEMP,
20885d79136SGregor Boirie 		.address = ST_TEMP_1_OUT_L_ADDR,
20985d79136SGregor Boirie 		.scan_index = 1,
21085d79136SGregor Boirie 		.scan_type = {
21185d79136SGregor Boirie 			.sign = 's',
21285d79136SGregor Boirie 			.realbits = 16,
21385d79136SGregor Boirie 			.storagebits = 16,
21485d79136SGregor Boirie 			.endianness = IIO_LE,
21585d79136SGregor Boirie 		},
21685d79136SGregor Boirie 		.info_mask_separate =
21785d79136SGregor Boirie 			BIT(IIO_CHAN_INFO_RAW) |
21885d79136SGregor Boirie 			BIT(IIO_CHAN_INFO_SCALE),
21985d79136SGregor Boirie 		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
22085d79136SGregor Boirie 	},
22185d79136SGregor Boirie 	IIO_CHAN_SOFT_TIMESTAMP(2)
222e039e2f5SGregor Boirie };
223e039e2f5SGregor Boirie 
224a7ee8839SDenis CIOCCA static const struct st_sensor_settings st_press_sensors_settings[] = {
225217494e5SDenis CIOCCA 	{
22691a86a3bSLinus Walleij 		/*
22791a86a3bSLinus Walleij 		 * CUSTOM VALUES FOR LPS331AP SENSOR
22891a86a3bSLinus Walleij 		 * See LPS331AP datasheet:
22991a86a3bSLinus Walleij 		 * http://www2.st.com/resource/en/datasheet/lps331ap.pdf
23091a86a3bSLinus Walleij 		 */
23191a86a3bSLinus Walleij 		.wai = 0xbb,
232bc27381eSGiuseppe Barba 		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
233217494e5SDenis CIOCCA 		.sensors_supported = {
234217494e5SDenis CIOCCA 			[0] = LPS331AP_PRESS_DEV_NAME,
235217494e5SDenis CIOCCA 		},
23693187840SDenis CIOCCA 		.ch = (struct iio_chan_spec *)st_press_1_channels,
23793187840SDenis CIOCCA 		.num_ch = ARRAY_SIZE(st_press_1_channels),
238217494e5SDenis CIOCCA 		.odr = {
23991a86a3bSLinus Walleij 			.addr = 0x20,
24091a86a3bSLinus Walleij 			.mask = 0x70,
241217494e5SDenis CIOCCA 			.odr_avl = {
24291a86a3bSLinus Walleij 				{ .hz = 1, .value = 0x01 },
24391a86a3bSLinus Walleij 				{ .hz = 7, .value = 0x05 },
24491a86a3bSLinus Walleij 				{ .hz = 13, .value = 0x06 },
24591a86a3bSLinus Walleij 				{ .hz = 25, .value = 0x07 },
246217494e5SDenis CIOCCA 			},
247217494e5SDenis CIOCCA 		},
248217494e5SDenis CIOCCA 		.pw = {
24991a86a3bSLinus Walleij 			.addr = 0x20,
25091a86a3bSLinus Walleij 			.mask = 0x80,
251217494e5SDenis CIOCCA 			.value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
252217494e5SDenis CIOCCA 			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
253217494e5SDenis CIOCCA 		},
254217494e5SDenis CIOCCA 		.fs = {
25591a86a3bSLinus Walleij 			.addr = 0x23,
25691a86a3bSLinus Walleij 			.mask = 0x30,
257217494e5SDenis CIOCCA 			.fs_avl = {
258d43a4115SGregor Boirie 				/*
259d43a4115SGregor Boirie 				 * Pressure and temperature sensitivity values
260d43a4115SGregor Boirie 				 * as defined in table 3 of LPS331AP datasheet.
261d43a4115SGregor Boirie 				 */
262217494e5SDenis CIOCCA 				[0] = {
263217494e5SDenis CIOCCA 					.num = ST_PRESS_FS_AVL_1260MB,
264d43a4115SGregor Boirie 					.gain = ST_PRESS_KPASCAL_NANO_SCALE,
265d43a4115SGregor Boirie 					.gain2 = ST_PRESS_LSB_PER_CELSIUS,
266217494e5SDenis CIOCCA 				},
267217494e5SDenis CIOCCA 			},
268217494e5SDenis CIOCCA 		},
269217494e5SDenis CIOCCA 		.bdu = {
27091a86a3bSLinus Walleij 			.addr = 0x20,
27191a86a3bSLinus Walleij 			.mask = 0x04,
272217494e5SDenis CIOCCA 		},
273217494e5SDenis CIOCCA 		.drdy_irq = {
27475d4c6d2SLorenzo Bianconi 			.int1 = {
27591a86a3bSLinus Walleij 				.addr = 0x22,
27675d4c6d2SLorenzo Bianconi 				.mask = 0x04,
277a542f9a0SLorenzo Bianconi 				.addr_od = 0x22,
278a542f9a0SLorenzo Bianconi 				.mask_od = 0x40,
27975d4c6d2SLorenzo Bianconi 			},
28075d4c6d2SLorenzo Bianconi 			.int2 = {
28175d4c6d2SLorenzo Bianconi 				.addr = 0x22,
28275d4c6d2SLorenzo Bianconi 				.mask = 0x20,
283a542f9a0SLorenzo Bianconi 				.addr_od = 0x22,
284a542f9a0SLorenzo Bianconi 				.mask_od = 0x40,
28575d4c6d2SLorenzo Bianconi 			},
28691a86a3bSLinus Walleij 			.addr_ihl = 0x22,
28791a86a3bSLinus Walleij 			.mask_ihl = 0x80,
288e72a0601SLorenzo Bianconi 			.stat_drdy = {
289e72a0601SLorenzo Bianconi 				.addr = ST_SENSORS_DEFAULT_STAT_ADDR,
290e72a0601SLorenzo Bianconi 				.mask = 0x03,
291e72a0601SLorenzo Bianconi 			},
292217494e5SDenis CIOCCA 		},
2936f667004SLorenzo Bianconi 		.sim = {
2946f667004SLorenzo Bianconi 			.addr = 0x20,
2956f667004SLorenzo Bianconi 			.value = BIT(0),
2966f667004SLorenzo Bianconi 		},
29791a86a3bSLinus Walleij 		.multi_read_bit = true,
298217494e5SDenis CIOCCA 		.bootime = 2,
299217494e5SDenis CIOCCA 	},
3007885a8ceSLee Jones 	{
30191a86a3bSLinus Walleij 		/*
30291a86a3bSLinus Walleij 		 * CUSTOM VALUES FOR LPS001WP SENSOR
30391a86a3bSLinus Walleij 		 */
30491a86a3bSLinus Walleij 		.wai = 0xba,
305bc27381eSGiuseppe Barba 		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
3067885a8ceSLee Jones 		.sensors_supported = {
3077885a8ceSLee Jones 			[0] = LPS001WP_PRESS_DEV_NAME,
3087885a8ceSLee Jones 		},
3097885a8ceSLee Jones 		.ch = (struct iio_chan_spec *)st_press_lps001wp_channels,
3107885a8ceSLee Jones 		.num_ch = ARRAY_SIZE(st_press_lps001wp_channels),
3117885a8ceSLee Jones 		.odr = {
31291a86a3bSLinus Walleij 			.addr = 0x20,
31391a86a3bSLinus Walleij 			.mask = 0x30,
3147885a8ceSLee Jones 			.odr_avl = {
31591a86a3bSLinus Walleij 				{ .hz = 1, .value = 0x01 },
31691a86a3bSLinus Walleij 				{ .hz = 7, .value = 0x02 },
31791a86a3bSLinus Walleij 				{ .hz = 13, .value = 0x03 },
3187885a8ceSLee Jones 			},
3197885a8ceSLee Jones 		},
3207885a8ceSLee Jones 		.pw = {
32191a86a3bSLinus Walleij 			.addr = 0x20,
32291a86a3bSLinus Walleij 			.mask = 0x40,
3237885a8ceSLee Jones 			.value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
3247885a8ceSLee Jones 			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
3257885a8ceSLee Jones 		},
3267885a8ceSLee Jones 		.fs = {
327d43a4115SGregor Boirie 			.fs_avl = {
328d43a4115SGregor Boirie 				/*
329d43a4115SGregor Boirie 				 * Pressure and temperature resolution values
330d43a4115SGregor Boirie 				 * as defined in table 3 of LPS001WP datasheet.
331d43a4115SGregor Boirie 				 */
332d43a4115SGregor Boirie 				[0] = {
333d43a4115SGregor Boirie 					.num = ST_PRESS_FS_AVL_1100MB,
334d43a4115SGregor Boirie 					.gain = ST_PRESS_LPS001WP_FS_AVL_PRESS_GAIN,
335d43a4115SGregor Boirie 					.gain2 = ST_PRESS_LPS001WP_LSB_PER_CELSIUS,
336d43a4115SGregor Boirie 				},
337d43a4115SGregor Boirie 			},
3387885a8ceSLee Jones 		},
3397885a8ceSLee Jones 		.bdu = {
34091a86a3bSLinus Walleij 			.addr = 0x20,
34191a86a3bSLinus Walleij 			.mask = 0x04,
3427885a8ceSLee Jones 		},
3436f667004SLorenzo Bianconi 		.sim = {
3446f667004SLorenzo Bianconi 			.addr = 0x20,
3456f667004SLorenzo Bianconi 			.value = BIT(0),
3466f667004SLorenzo Bianconi 		},
34791a86a3bSLinus Walleij 		.multi_read_bit = true,
3487885a8ceSLee Jones 		.bootime = 2,
3497885a8ceSLee Jones 	},
35093187840SDenis CIOCCA 	{
35191a86a3bSLinus Walleij 		/*
35291a86a3bSLinus Walleij 		 * CUSTOM VALUES FOR LPS25H SENSOR
35391a86a3bSLinus Walleij 		 * See LPS25H datasheet:
35491a86a3bSLinus Walleij 		 * http://www2.st.com/resource/en/datasheet/lps25h.pdf
35591a86a3bSLinus Walleij 		 */
35691a86a3bSLinus Walleij 		.wai = 0xbd,
357bc27381eSGiuseppe Barba 		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
35893187840SDenis CIOCCA 		.sensors_supported = {
35993187840SDenis CIOCCA 			[0] = LPS25H_PRESS_DEV_NAME,
36093187840SDenis CIOCCA 		},
36193187840SDenis CIOCCA 		.ch = (struct iio_chan_spec *)st_press_1_channels,
36293187840SDenis CIOCCA 		.num_ch = ARRAY_SIZE(st_press_1_channels),
36393187840SDenis CIOCCA 		.odr = {
36491a86a3bSLinus Walleij 			.addr = 0x20,
36591a86a3bSLinus Walleij 			.mask = 0x70,
36693187840SDenis CIOCCA 			.odr_avl = {
36791a86a3bSLinus Walleij 				{ .hz = 1, .value = 0x01 },
36891a86a3bSLinus Walleij 				{ .hz = 7, .value = 0x02 },
36991a86a3bSLinus Walleij 				{ .hz = 13, .value = 0x03 },
37091a86a3bSLinus Walleij 				{ .hz = 25, .value = 0x04 },
37193187840SDenis CIOCCA 			},
37293187840SDenis CIOCCA 		},
37393187840SDenis CIOCCA 		.pw = {
37491a86a3bSLinus Walleij 			.addr = 0x20,
37591a86a3bSLinus Walleij 			.mask = 0x80,
37693187840SDenis CIOCCA 			.value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
37793187840SDenis CIOCCA 			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
37893187840SDenis CIOCCA 		},
37993187840SDenis CIOCCA 		.fs = {
38093187840SDenis CIOCCA 			.fs_avl = {
381d43a4115SGregor Boirie 				/*
382d43a4115SGregor Boirie 				 * Pressure and temperature sensitivity values
383d43a4115SGregor Boirie 				 * as defined in table 3 of LPS25H datasheet.
384d43a4115SGregor Boirie 				 */
38593187840SDenis CIOCCA 				[0] = {
38693187840SDenis CIOCCA 					.num = ST_PRESS_FS_AVL_1260MB,
387d43a4115SGregor Boirie 					.gain = ST_PRESS_KPASCAL_NANO_SCALE,
388d43a4115SGregor Boirie 					.gain2 = ST_PRESS_LSB_PER_CELSIUS,
38993187840SDenis CIOCCA 				},
39093187840SDenis CIOCCA 			},
39193187840SDenis CIOCCA 		},
39293187840SDenis CIOCCA 		.bdu = {
39391a86a3bSLinus Walleij 			.addr = 0x20,
39491a86a3bSLinus Walleij 			.mask = 0x04,
39593187840SDenis CIOCCA 		},
39693187840SDenis CIOCCA 		.drdy_irq = {
39775d4c6d2SLorenzo Bianconi 			.int1 = {
39891a86a3bSLinus Walleij 				.addr = 0x23,
39975d4c6d2SLorenzo Bianconi 				.mask = 0x01,
400a542f9a0SLorenzo Bianconi 				.addr_od = 0x22,
401a542f9a0SLorenzo Bianconi 				.mask_od = 0x40,
40275d4c6d2SLorenzo Bianconi 			},
40391a86a3bSLinus Walleij 			.addr_ihl = 0x22,
40491a86a3bSLinus Walleij 			.mask_ihl = 0x80,
405e72a0601SLorenzo Bianconi 			.stat_drdy = {
406e72a0601SLorenzo Bianconi 				.addr = ST_SENSORS_DEFAULT_STAT_ADDR,
407e72a0601SLorenzo Bianconi 				.mask = 0x03,
408e72a0601SLorenzo Bianconi 			},
40993187840SDenis CIOCCA 		},
4106f667004SLorenzo Bianconi 		.sim = {
4116f667004SLorenzo Bianconi 			.addr = 0x20,
4126f667004SLorenzo Bianconi 			.value = BIT(0),
4136f667004SLorenzo Bianconi 		},
41491a86a3bSLinus Walleij 		.multi_read_bit = true,
41593187840SDenis CIOCCA 		.bootime = 2,
41693187840SDenis CIOCCA 	},
417e039e2f5SGregor Boirie 	{
41891a86a3bSLinus Walleij 		/*
41991a86a3bSLinus Walleij 		 * CUSTOM VALUES FOR LPS22HB SENSOR
42091a86a3bSLinus Walleij 		 * See LPS22HB datasheet:
42191a86a3bSLinus Walleij 		 * http://www2.st.com/resource/en/datasheet/lps22hb.pdf
42291a86a3bSLinus Walleij 		 */
42391a86a3bSLinus Walleij 		.wai = 0xb1,
424e039e2f5SGregor Boirie 		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
425e039e2f5SGregor Boirie 		.sensors_supported = {
426e039e2f5SGregor Boirie 			[0] = LPS22HB_PRESS_DEV_NAME,
427b954d77aSLorenzo Bianconi 			[1] = LPS33HW_PRESS_DEV_NAME,
428b954d77aSLorenzo Bianconi 			[2] = LPS35HW_PRESS_DEV_NAME,
429e039e2f5SGregor Boirie 		},
430e039e2f5SGregor Boirie 		.ch = (struct iio_chan_spec *)st_press_lps22hb_channels,
431e039e2f5SGregor Boirie 		.num_ch = ARRAY_SIZE(st_press_lps22hb_channels),
432e039e2f5SGregor Boirie 		.odr = {
43391a86a3bSLinus Walleij 			.addr = 0x10,
43491a86a3bSLinus Walleij 			.mask = 0x70,
435e039e2f5SGregor Boirie 			.odr_avl = {
43691a86a3bSLinus Walleij 				{ .hz = 1, .value = 0x01 },
43791a86a3bSLinus Walleij 				{ .hz = 10, .value = 0x02 },
43891a86a3bSLinus Walleij 				{ .hz = 25, .value = 0x03 },
43991a86a3bSLinus Walleij 				{ .hz = 50, .value = 0x04 },
44091a86a3bSLinus Walleij 				{ .hz = 75, .value = 0x05 },
441e039e2f5SGregor Boirie 			},
442e039e2f5SGregor Boirie 		},
443e039e2f5SGregor Boirie 		.pw = {
44491a86a3bSLinus Walleij 			.addr = 0x10,
44591a86a3bSLinus Walleij 			.mask = 0x70,
446e039e2f5SGregor Boirie 			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
447e039e2f5SGregor Boirie 		},
448e039e2f5SGregor Boirie 		.fs = {
449e039e2f5SGregor Boirie 			.fs_avl = {
45019b7b8a8SGregor Boirie 				/*
45185d79136SGregor Boirie 				 * Pressure and temperature sensitivity values
45285d79136SGregor Boirie 				 * as defined in table 3 of LPS22HB datasheet.
45319b7b8a8SGregor Boirie 				 */
454e039e2f5SGregor Boirie 				[0] = {
455e039e2f5SGregor Boirie 					.num = ST_PRESS_FS_AVL_1260MB,
456e039e2f5SGregor Boirie 					.gain = ST_PRESS_KPASCAL_NANO_SCALE,
45785d79136SGregor Boirie 					.gain2 = ST_PRESS_LPS22HB_LSB_PER_CELSIUS,
458e039e2f5SGregor Boirie 				},
459e039e2f5SGregor Boirie 			},
460e039e2f5SGregor Boirie 		},
461e039e2f5SGregor Boirie 		.bdu = {
46291a86a3bSLinus Walleij 			.addr = 0x10,
46391a86a3bSLinus Walleij 			.mask = 0x02,
464e039e2f5SGregor Boirie 		},
465e039e2f5SGregor Boirie 		.drdy_irq = {
46675d4c6d2SLorenzo Bianconi 			.int1 = {
46791a86a3bSLinus Walleij 				.addr = 0x12,
46875d4c6d2SLorenzo Bianconi 				.mask = 0x04,
469a542f9a0SLorenzo Bianconi 				.addr_od = 0x12,
470a542f9a0SLorenzo Bianconi 				.mask_od = 0x40,
47175d4c6d2SLorenzo Bianconi 			},
47291a86a3bSLinus Walleij 			.addr_ihl = 0x12,
47391a86a3bSLinus Walleij 			.mask_ihl = 0x80,
474e72a0601SLorenzo Bianconi 			.stat_drdy = {
475e72a0601SLorenzo Bianconi 				.addr = ST_SENSORS_DEFAULT_STAT_ADDR,
476e72a0601SLorenzo Bianconi 				.mask = 0x03,
477e72a0601SLorenzo Bianconi 			},
478e039e2f5SGregor Boirie 		},
4796f667004SLorenzo Bianconi 		.sim = {
4806f667004SLorenzo Bianconi 			.addr = 0x10,
4816f667004SLorenzo Bianconi 			.value = BIT(0),
4826f667004SLorenzo Bianconi 		},
483add6e6abSLorenzo Bianconi 		.multi_read_bit = false,
48451f528a1SShrirang Bagul 		.bootime = 2,
485e039e2f5SGregor Boirie 	},
486e5aab7b0Smario tesi 	{
487e5aab7b0Smario tesi 		/*
488e5aab7b0Smario tesi 		 * CUSTOM VALUES FOR LPS22HH SENSOR
489e5aab7b0Smario tesi 		 * See LPS22HH datasheet:
490e5aab7b0Smario tesi 		 * http://www2.st.com/resource/en/datasheet/lps22hh.pdf
491e5aab7b0Smario tesi 		 */
492e5aab7b0Smario tesi 		.wai = 0xb3,
493e5aab7b0Smario tesi 		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
494e5aab7b0Smario tesi 		.sensors_supported = {
495e5aab7b0Smario tesi 			[0] = LPS22HH_PRESS_DEV_NAME,
496e5aab7b0Smario tesi 		},
497e5aab7b0Smario tesi 		.ch = (struct iio_chan_spec *)st_press_lps22hb_channels,
498e5aab7b0Smario tesi 		.num_ch = ARRAY_SIZE(st_press_lps22hb_channels),
499e5aab7b0Smario tesi 		.odr = {
500e5aab7b0Smario tesi 			.addr = 0x10,
501e5aab7b0Smario tesi 			.mask = 0x70,
502e5aab7b0Smario tesi 			.odr_avl = {
503e5aab7b0Smario tesi 				{ .hz = 1, .value = 0x01 },
504e5aab7b0Smario tesi 				{ .hz = 10, .value = 0x02 },
505e5aab7b0Smario tesi 				{ .hz = 25, .value = 0x03 },
506e5aab7b0Smario tesi 				{ .hz = 50, .value = 0x04 },
507e5aab7b0Smario tesi 				{ .hz = 75, .value = 0x05 },
508e5aab7b0Smario tesi 				{ .hz = 100, .value = 0x06 },
509e5aab7b0Smario tesi 				{ .hz = 200, .value = 0x07 },
510e5aab7b0Smario tesi 			},
511e5aab7b0Smario tesi 		},
512e5aab7b0Smario tesi 		.pw = {
513e5aab7b0Smario tesi 			.addr = 0x10,
514e5aab7b0Smario tesi 			.mask = 0x70,
515e5aab7b0Smario tesi 			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
516e5aab7b0Smario tesi 		},
517e5aab7b0Smario tesi 		.fs = {
518e5aab7b0Smario tesi 			.fs_avl = {
519e5aab7b0Smario tesi 				/*
520e5aab7b0Smario tesi 				 * Pressure and temperature sensitivity values
521e5aab7b0Smario tesi 				 * as defined in table 3 of LPS22HH datasheet.
522e5aab7b0Smario tesi 				 */
523e5aab7b0Smario tesi 				[0] = {
524e5aab7b0Smario tesi 					.num = ST_PRESS_FS_AVL_1260MB,
525e5aab7b0Smario tesi 					.gain = ST_PRESS_KPASCAL_NANO_SCALE,
526e5aab7b0Smario tesi 					.gain2 = ST_PRESS_LPS22HB_LSB_PER_CELSIUS,
527e5aab7b0Smario tesi 				},
528e5aab7b0Smario tesi 			},
529e5aab7b0Smario tesi 		},
530e5aab7b0Smario tesi 		.bdu = {
531e5aab7b0Smario tesi 			.addr = 0x10,
532e5aab7b0Smario tesi 			.mask = BIT(1),
533e5aab7b0Smario tesi 		},
534e5aab7b0Smario tesi 		.drdy_irq = {
535e5aab7b0Smario tesi 			.int1 = {
536e5aab7b0Smario tesi 				.addr = 0x12,
537e5aab7b0Smario tesi 				.mask = BIT(2),
538e5aab7b0Smario tesi 				.addr_od = 0x11,
539e5aab7b0Smario tesi 				.mask_od = BIT(5),
540e5aab7b0Smario tesi 			},
541e5aab7b0Smario tesi 			.addr_ihl = 0x11,
542e5aab7b0Smario tesi 			.mask_ihl = BIT(6),
543e5aab7b0Smario tesi 			.stat_drdy = {
544e5aab7b0Smario tesi 				.addr = ST_SENSORS_DEFAULT_STAT_ADDR,
545e5aab7b0Smario tesi 				.mask = 0x03,
546e5aab7b0Smario tesi 			},
547e5aab7b0Smario tesi 		},
548e5aab7b0Smario tesi 		.sim = {
549e5aab7b0Smario tesi 			.addr = 0x10,
550e5aab7b0Smario tesi 			.value = BIT(0),
551e5aab7b0Smario tesi 		},
552e5aab7b0Smario tesi 		.multi_read_bit = false,
553e5aab7b0Smario tesi 		.bootime = 2,
554e5aab7b0Smario tesi 	},
55592ba0ab9SMartyn Welch 	{
55692ba0ab9SMartyn Welch 		/*
55792ba0ab9SMartyn Welch 		 * CUSTOM VALUES FOR LPS22DF SENSOR
55892ba0ab9SMartyn Welch 		 * See LPS22DF datasheet:
55992ba0ab9SMartyn Welch 		 * http://www.st.com/resource/en/datasheet/lps22df.pdf
56092ba0ab9SMartyn Welch 		 */
56192ba0ab9SMartyn Welch 		.wai = 0xb4,
56292ba0ab9SMartyn Welch 		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
56392ba0ab9SMartyn Welch 		.sensors_supported = {
56492ba0ab9SMartyn Welch 			[0] = LPS22DF_PRESS_DEV_NAME,
56592ba0ab9SMartyn Welch 		},
56692ba0ab9SMartyn Welch 		.ch = (struct iio_chan_spec *)st_press_lps22hb_channels,
56792ba0ab9SMartyn Welch 		.num_ch = ARRAY_SIZE(st_press_lps22hb_channels),
56892ba0ab9SMartyn Welch 		.odr = {
56992ba0ab9SMartyn Welch 			.addr = 0x10,
57092ba0ab9SMartyn Welch 			.mask = 0x78,
57192ba0ab9SMartyn Welch 			.odr_avl = {
57292ba0ab9SMartyn Welch 				{ .hz = 1, .value = 0x01 },
57392ba0ab9SMartyn Welch 				{ .hz = 4, .value = 0x02 },
57492ba0ab9SMartyn Welch 				{ .hz = 10, .value = 0x03 },
57592ba0ab9SMartyn Welch 				{ .hz = 25, .value = 0x04 },
57692ba0ab9SMartyn Welch 				{ .hz = 50, .value = 0x05 },
57792ba0ab9SMartyn Welch 				{ .hz = 75, .value = 0x06 },
57892ba0ab9SMartyn Welch 				{ .hz = 100, .value = 0x07 },
57992ba0ab9SMartyn Welch 				{ .hz = 200, .value = 0x08 },
58092ba0ab9SMartyn Welch 			},
58192ba0ab9SMartyn Welch 		},
58292ba0ab9SMartyn Welch 		.pw = {
58392ba0ab9SMartyn Welch 			.addr = 0x10,
58492ba0ab9SMartyn Welch 			.mask = 0x78,
58592ba0ab9SMartyn Welch 			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
58692ba0ab9SMartyn Welch 		},
58792ba0ab9SMartyn Welch 		.fs = {
58892ba0ab9SMartyn Welch 			.fs_avl = {
58992ba0ab9SMartyn Welch 				/*
59092ba0ab9SMartyn Welch 				 * Pressure and temperature sensitivity values
59192ba0ab9SMartyn Welch 				 * as defined in table 2 of LPS22DF datasheet.
59292ba0ab9SMartyn Welch 				 */
59392ba0ab9SMartyn Welch 				[0] = {
59492ba0ab9SMartyn Welch 					.num = ST_PRESS_FS_AVL_1260MB,
59592ba0ab9SMartyn Welch 					.gain = ST_PRESS_KPASCAL_NANO_SCALE,
59692ba0ab9SMartyn Welch 					.gain2 = ST_PRESS_LPS22HB_LSB_PER_CELSIUS,
59792ba0ab9SMartyn Welch 				},
59892ba0ab9SMartyn Welch 			},
59992ba0ab9SMartyn Welch 		},
60092ba0ab9SMartyn Welch 		.bdu = {
60192ba0ab9SMartyn Welch 			.addr = 0x11,
60292ba0ab9SMartyn Welch 			.mask = BIT(3),
60392ba0ab9SMartyn Welch 		},
60492ba0ab9SMartyn Welch 		.drdy_irq = {
60592ba0ab9SMartyn Welch 			.int1 = {
60692ba0ab9SMartyn Welch 				.addr = 0x13,
60792ba0ab9SMartyn Welch 				.mask = BIT(5),
60892ba0ab9SMartyn Welch 				.addr_od = 0x12,
60992ba0ab9SMartyn Welch 				.mask_od = BIT(1),
61092ba0ab9SMartyn Welch 			},
61192ba0ab9SMartyn Welch 			.addr_ihl = 0x12,
61292ba0ab9SMartyn Welch 			.mask_ihl = BIT(3),
61392ba0ab9SMartyn Welch 			.stat_drdy = {
61492ba0ab9SMartyn Welch 				.addr = ST_SENSORS_DEFAULT_STAT_ADDR,
61592ba0ab9SMartyn Welch 				.mask = 0x03,
61692ba0ab9SMartyn Welch 			},
61792ba0ab9SMartyn Welch 		},
61892ba0ab9SMartyn Welch 		.sim = {
61992ba0ab9SMartyn Welch 			.addr = 0x0E,
62092ba0ab9SMartyn Welch 			.value = BIT(5),
62192ba0ab9SMartyn Welch 		},
62292ba0ab9SMartyn Welch 		.multi_read_bit = false,
62392ba0ab9SMartyn Welch 		.bootime = 2,
62492ba0ab9SMartyn Welch 	},
625217494e5SDenis CIOCCA };
626217494e5SDenis CIOCCA 
st_press_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * ch,int val,int val2,long mask)6272d239c9eSJonathan Cameron static int st_press_write_raw(struct iio_dev *indio_dev,
6282d239c9eSJonathan Cameron 			      struct iio_chan_spec const *ch,
6292d239c9eSJonathan Cameron 			      int val,
6302d239c9eSJonathan Cameron 			      int val2,
6312d239c9eSJonathan Cameron 			      long mask)
6322d239c9eSJonathan Cameron {
6332d239c9eSJonathan Cameron 	switch (mask) {
6342d239c9eSJonathan Cameron 	case IIO_CHAN_INFO_SAMP_FREQ:
6352d239c9eSJonathan Cameron 		if (val2)
6362d239c9eSJonathan Cameron 			return -EINVAL;
63712345968SMiquel Raynal 
63812345968SMiquel Raynal 		return st_sensors_set_odr(indio_dev, val);
6392d239c9eSJonathan Cameron 	default:
6402d239c9eSJonathan Cameron 		return -EINVAL;
6412d239c9eSJonathan Cameron 	}
6422d239c9eSJonathan Cameron }
6432d239c9eSJonathan Cameron 
st_press_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * ch,int * val,int * val2,long mask)644217494e5SDenis CIOCCA static int st_press_read_raw(struct iio_dev *indio_dev,
645217494e5SDenis CIOCCA 			struct iio_chan_spec const *ch, int *val,
646217494e5SDenis CIOCCA 							int *val2, long mask)
647217494e5SDenis CIOCCA {
648217494e5SDenis CIOCCA 	int err;
649a1dcf429SDenis CIOCCA 	struct st_sensor_data *press_data = iio_priv(indio_dev);
650217494e5SDenis CIOCCA 
651217494e5SDenis CIOCCA 	switch (mask) {
652217494e5SDenis CIOCCA 	case IIO_CHAN_INFO_RAW:
653217494e5SDenis CIOCCA 		err = st_sensors_read_info_raw(indio_dev, ch, val);
654217494e5SDenis CIOCCA 		if (err < 0)
655217494e5SDenis CIOCCA 			goto read_error;
656217494e5SDenis CIOCCA 
657217494e5SDenis CIOCCA 		return IIO_VAL_INT;
658217494e5SDenis CIOCCA 	case IIO_CHAN_INFO_SCALE:
659217494e5SDenis CIOCCA 		switch (ch->type) {
660217494e5SDenis CIOCCA 		case IIO_PRESSURE:
661d43a4115SGregor Boirie 			*val = 0;
662a1dcf429SDenis CIOCCA 			*val2 = press_data->current_fullscale->gain;
663d43a4115SGregor Boirie 			return IIO_VAL_INT_PLUS_NANO;
664217494e5SDenis CIOCCA 		case IIO_TEMP:
665d43a4115SGregor Boirie 			*val = MCELSIUS_PER_CELSIUS;
666a1dcf429SDenis CIOCCA 			*val2 = press_data->current_fullscale->gain2;
667d43a4115SGregor Boirie 			return IIO_VAL_FRACTIONAL;
668217494e5SDenis CIOCCA 		default:
669217494e5SDenis CIOCCA 			err = -EINVAL;
670217494e5SDenis CIOCCA 			goto read_error;
671217494e5SDenis CIOCCA 		}
672217494e5SDenis CIOCCA 
673217494e5SDenis CIOCCA 	case IIO_CHAN_INFO_OFFSET:
674217494e5SDenis CIOCCA 		switch (ch->type) {
675217494e5SDenis CIOCCA 		case IIO_TEMP:
676d43a4115SGregor Boirie 			*val = ST_PRESS_MILLI_CELSIUS_OFFSET *
677d43a4115SGregor Boirie 			       press_data->current_fullscale->gain2;
678d43a4115SGregor Boirie 			*val2 = MCELSIUS_PER_CELSIUS;
679217494e5SDenis CIOCCA 			break;
680217494e5SDenis CIOCCA 		default:
681217494e5SDenis CIOCCA 			err = -EINVAL;
682217494e5SDenis CIOCCA 			goto read_error;
683217494e5SDenis CIOCCA 		}
684217494e5SDenis CIOCCA 
685217494e5SDenis CIOCCA 		return IIO_VAL_FRACTIONAL;
6862d239c9eSJonathan Cameron 	case IIO_CHAN_INFO_SAMP_FREQ:
687a1dcf429SDenis CIOCCA 		*val = press_data->odr;
6882d239c9eSJonathan Cameron 		return IIO_VAL_INT;
689217494e5SDenis CIOCCA 	default:
690217494e5SDenis CIOCCA 		return -EINVAL;
691217494e5SDenis CIOCCA 	}
692217494e5SDenis CIOCCA 
693217494e5SDenis CIOCCA read_error:
694217494e5SDenis CIOCCA 	return err;
695217494e5SDenis CIOCCA }
696217494e5SDenis CIOCCA 
697217494e5SDenis CIOCCA static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
698217494e5SDenis CIOCCA 
699217494e5SDenis CIOCCA static struct attribute *st_press_attributes[] = {
700217494e5SDenis CIOCCA 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
701217494e5SDenis CIOCCA 	NULL,
702217494e5SDenis CIOCCA };
703217494e5SDenis CIOCCA 
704217494e5SDenis CIOCCA static const struct attribute_group st_press_attribute_group = {
705217494e5SDenis CIOCCA 	.attrs = st_press_attributes,
706217494e5SDenis CIOCCA };
707217494e5SDenis CIOCCA 
708217494e5SDenis CIOCCA static const struct iio_info press_info = {
709217494e5SDenis CIOCCA 	.attrs = &st_press_attribute_group,
710217494e5SDenis CIOCCA 	.read_raw = &st_press_read_raw,
7112d239c9eSJonathan Cameron 	.write_raw = &st_press_write_raw,
712a0175b9cSLinus Walleij 	.debugfs_reg_access = &st_sensors_debugfs_reg_access,
713217494e5SDenis CIOCCA };
714217494e5SDenis CIOCCA 
715217494e5SDenis CIOCCA #ifdef CONFIG_IIO_TRIGGER
716217494e5SDenis CIOCCA static const struct iio_trigger_ops st_press_trigger_ops = {
717217494e5SDenis CIOCCA 	.set_trigger_state = ST_PRESS_TRIGGER_SET_STATE,
71865925b65SLinus Walleij 	.validate_device = st_sensors_validate_device,
719217494e5SDenis CIOCCA };
720217494e5SDenis CIOCCA #define ST_PRESS_TRIGGER_OPS (&st_press_trigger_ops)
721217494e5SDenis CIOCCA #else
722217494e5SDenis CIOCCA #define ST_PRESS_TRIGGER_OPS NULL
723217494e5SDenis CIOCCA #endif
724217494e5SDenis CIOCCA 
725539b25faSDenis Ciocca /*
726539b25faSDenis Ciocca  * st_press_get_settings() - get sensor settings from device name
727539b25faSDenis Ciocca  * @name: device name buffer reference.
728539b25faSDenis Ciocca  *
729539b25faSDenis Ciocca  * Return: valid reference on success, NULL otherwise.
730539b25faSDenis Ciocca  */
st_press_get_settings(const char * name)731539b25faSDenis Ciocca const struct st_sensor_settings *st_press_get_settings(const char *name)
732539b25faSDenis Ciocca {
733539b25faSDenis Ciocca 	int index = st_sensors_get_settings_index(name,
734539b25faSDenis Ciocca 					st_press_sensors_settings,
735539b25faSDenis Ciocca 					ARRAY_SIZE(st_press_sensors_settings));
736539b25faSDenis Ciocca 	if (index < 0)
737539b25faSDenis Ciocca 		return NULL;
738539b25faSDenis Ciocca 
739539b25faSDenis Ciocca 	return &st_press_sensors_settings[index];
740539b25faSDenis Ciocca }
741*cdd30ebbSPeter Zijlstra EXPORT_SYMBOL_NS(st_press_get_settings, "IIO_ST_SENSORS");
742539b25faSDenis Ciocca 
st_press_common_probe(struct iio_dev * indio_dev)7430baa3fc1SDenis CIOCCA int st_press_common_probe(struct iio_dev *indio_dev)
744217494e5SDenis CIOCCA {
745a1dcf429SDenis CIOCCA 	struct st_sensor_data *press_data = iio_priv(indio_dev);
7466b658c31SAlexandru Ardelean 	struct device *parent = indio_dev->dev.parent;
747e4269651SAlexandru Ardelean 	struct st_sensors_platform_data *pdata = dev_get_platdata(parent);
748a6cc5b25SLee Jones 	int err;
749217494e5SDenis CIOCCA 
750217494e5SDenis CIOCCA 	indio_dev->modes = INDIO_DIRECT_MODE;
751217494e5SDenis CIOCCA 	indio_dev->info = &press_info;
752217494e5SDenis CIOCCA 
7531ecd245eSDenis Ciocca 	err = st_sensors_verify_id(indio_dev);
754217494e5SDenis CIOCCA 	if (err < 0)
7557db4f2caSAndy Shevchenko 		return err;
756217494e5SDenis CIOCCA 
757b4701fd6SGregor Boirie 	/*
758b4701fd6SGregor Boirie 	 * Skip timestamping channel while declaring available channels to
759b4701fd6SGregor Boirie 	 * common st_sensor layer. Look at st_sensors_get_buffer_element() to
760b4701fd6SGregor Boirie 	 * see how timestamps are explicitly pushed as last samples block
761b4701fd6SGregor Boirie 	 * element.
762b4701fd6SGregor Boirie 	 */
763b4701fd6SGregor Boirie 	press_data->num_data_channels = press_data->sensor_settings->num_ch - 1;
764a1dcf429SDenis CIOCCA 	indio_dev->channels = press_data->sensor_settings->ch;
765a1dcf429SDenis CIOCCA 	indio_dev->num_channels = press_data->sensor_settings->num_ch;
766217494e5SDenis CIOCCA 
7671f38527dSAndy Shevchenko 	press_data->current_fullscale = &press_data->sensor_settings->fs.fs_avl[0];
768362f2f86SLee Jones 
769a1dcf429SDenis CIOCCA 	press_data->odr = press_data->sensor_settings->odr.odr_avl[0].hz;
770217494e5SDenis CIOCCA 
77138d1c6a9SLee Jones 	/* Some devices don't support a data ready pin. */
77275d4c6d2SLorenzo Bianconi 	if (!pdata && (press_data->sensor_settings->drdy_irq.int1.addr ||
77375d4c6d2SLorenzo Bianconi 		       press_data->sensor_settings->drdy_irq.int2.addr))
7747383d44bSShrirang Bagul 		pdata =	(struct st_sensors_platform_data *)&default_press_pdata;
77523cde4d6SDenis CIOCCA 
7768b438686SMichael Nosthoff 	err = st_sensors_init_sensor(indio_dev, pdata);
777217494e5SDenis CIOCCA 	if (err < 0)
7787db4f2caSAndy Shevchenko 		return err;
779217494e5SDenis CIOCCA 
780217494e5SDenis CIOCCA 	err = st_press_allocate_ring(indio_dev);
781217494e5SDenis CIOCCA 	if (err < 0)
7827db4f2caSAndy Shevchenko 		return err;
783217494e5SDenis CIOCCA 
7849cd15d52SDenis Ciocca 	if (press_data->irq > 0) {
785217494e5SDenis CIOCCA 		err = st_sensors_allocate_trigger(indio_dev,
786217494e5SDenis CIOCCA 						  ST_PRESS_TRIGGER_OPS);
787217494e5SDenis CIOCCA 		if (err < 0)
788674db1e9SAlexandru Ardelean 			return err;
789217494e5SDenis CIOCCA 	}
790217494e5SDenis CIOCCA 
7916b658c31SAlexandru Ardelean 	return devm_iio_device_register(parent, indio_dev);
792217494e5SDenis CIOCCA }
793*cdd30ebbSPeter Zijlstra EXPORT_SYMBOL_NS(st_press_common_probe, "IIO_ST_SENSORS");
794217494e5SDenis CIOCCA 
795217494e5SDenis CIOCCA MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
796217494e5SDenis CIOCCA MODULE_DESCRIPTION("STMicroelectronics pressures driver");
797217494e5SDenis CIOCCA MODULE_LICENSE("GPL v2");
798*cdd30ebbSPeter Zijlstra MODULE_IMPORT_NS("IIO_ST_SENSORS");
799