xref: /linux/drivers/iio/pressure/abp2030pa.c (revision c17ee635fd3a482b2ad2bf5e269755c2eae5f25e)
147d323ceSPetre Rodan // SPDX-License-Identifier: GPL-2.0-or-later
247d323ceSPetre Rodan /*
347d323ceSPetre Rodan  * Honeywell ABP2 series pressure sensor driver
447d323ceSPetre Rodan  *
547d323ceSPetre Rodan  * Copyright (c) 2025 Petre Rodan <petre.rodan@subdimension.ro>
647d323ceSPetre Rodan  *
747d323ceSPetre Rodan  * Datasheet: https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-us/products/sensors/pressure-sensors/board-mount-pressure-sensors/basic-abp2-series/documents/sps-siot-abp2-series-datasheet-32350268-en.pdf
847d323ceSPetre Rodan  */
947d323ceSPetre Rodan 
1047d323ceSPetre Rodan #include <linux/array_size.h>
1147d323ceSPetre Rodan #include <linux/bits.h>
1247d323ceSPetre Rodan #include <linux/completion.h>
1347d323ceSPetre Rodan #include <linux/delay.h>
1447d323ceSPetre Rodan #include <linux/dev_printk.h>
1547d323ceSPetre Rodan #include <linux/device.h>
1647d323ceSPetre Rodan #include <linux/errno.h>
1747d323ceSPetre Rodan #include <linux/export.h>
1847d323ceSPetre Rodan #include <linux/gpio/consumer.h>
1947d323ceSPetre Rodan #include <linux/interrupt.h>
2047d323ceSPetre Rodan #include <linux/jiffies.h>
2147d323ceSPetre Rodan #include <linux/math64.h>
2247d323ceSPetre Rodan #include <linux/module.h>
2347d323ceSPetre Rodan #include <linux/property.h>
2447d323ceSPetre Rodan #include <linux/regulator/consumer.h>
2547d323ceSPetre Rodan #include <linux/string.h>
2647d323ceSPetre Rodan #include <linux/time.h>
2747d323ceSPetre Rodan #include <linux/types.h>
2847d323ceSPetre Rodan #include <linux/unaligned.h>
2947d323ceSPetre Rodan #include <linux/units.h>
3047d323ceSPetre Rodan 
3147d323ceSPetre Rodan #include <linux/iio/buffer.h>
3247d323ceSPetre Rodan #include <linux/iio/iio.h>
3347d323ceSPetre Rodan #include <linux/iio/trigger_consumer.h>
3447d323ceSPetre Rodan #include <linux/iio/triggered_buffer.h>
3547d323ceSPetre Rodan 
3647d323ceSPetre Rodan #include "abp2030pa.h"
3747d323ceSPetre Rodan 
3847d323ceSPetre Rodan /* Status byte flags */
3947d323ceSPetre Rodan #define ABP2_ST_POWER     BIT(6) /* 1 if device is powered */
4047d323ceSPetre Rodan #define ABP2_ST_BUSY      BIT(5) /* 1 if device is busy */
4147d323ceSPetre Rodan 
4247d323ceSPetre Rodan #define ABP2_CMD_NOP      0xf0
4347d323ceSPetre Rodan #define ABP2_CMD_SYNC     0xaa
4447d323ceSPetre Rodan #define ABP2_PKT_SYNC_LEN 3
4547d323ceSPetre Rodan #define ABP2_PKT_NOP_LEN  ABP2_MEASUREMENT_RD_SIZE
4647d323ceSPetre Rodan 
4747d323ceSPetre Rodan struct abp2_func_spec {
4847d323ceSPetre Rodan 	u32 output_min;
4947d323ceSPetre Rodan 	u32 output_max;
5047d323ceSPetre Rodan };
5147d323ceSPetre Rodan 
5247d323ceSPetre Rodan /* transfer function A: 10%   to 90%   of 2^24 */
5347d323ceSPetre Rodan static const struct abp2_func_spec abp2_func_spec[] = {
5447d323ceSPetre Rodan 	[ABP2_FUNCTION_A] = { .output_min = 1677722, .output_max = 15099494 },
5547d323ceSPetre Rodan };
5647d323ceSPetre Rodan 
5747d323ceSPetre Rodan enum abp2_variants {
5847d323ceSPetre Rodan 	ABP2001BA, ABP21_6BA, ABP22_5BA, ABP2004BA, ABP2006BA, ABP2008BA,
5947d323ceSPetre Rodan 	ABP2010BA, ABP2012BA, ABP2001BD, ABP21_6BD, ABP22_5BD, ABP2004BD,
6047d323ceSPetre Rodan 	ABP2001BG, ABP21_6BG, ABP22_5BG, ABP2004BG, ABP2006BG, ABP2008BG,
6147d323ceSPetre Rodan 	ABP2010BG, ABP2012BG, ABP2001GG, ABP21_2GG, ABP2100KA, ABP2160KA,
6247d323ceSPetre Rodan 	ABP2250KA, ABP2001KD, ABP21_6KD, ABP22_5KD, ABP2004KD, ABP2006KD,
6347d323ceSPetre Rodan 	ABP2010KD, ABP2016KD, ABP2025KD, ABP2040KD, ABP2060KD, ABP2100KD,
6447d323ceSPetre Rodan 	ABP2160KD, ABP2250KD, ABP2400KD, ABP2001KG, ABP21_6KG, ABP22_5KG,
6547d323ceSPetre Rodan 	ABP2004KG, ABP2006KG, ABP2010KG, ABP2016KG, ABP2025KG, ABP2040KG,
6647d323ceSPetre Rodan 	ABP2060KG, ABP2100KG, ABP2160KG, ABP2250KG, ABP2400KG, ABP2600KG,
6747d323ceSPetre Rodan 	ABP2800KG, ABP2250LD, ABP2600LD, ABP2600LG, ABP22_5MD, ABP2006MD,
6847d323ceSPetre Rodan 	ABP2010MD, ABP2016MD, ABP2025MD, ABP2040MD, ABP2060MD, ABP2100MD,
6947d323ceSPetre Rodan 	ABP2160MD, ABP2250MD, ABP2400MD, ABP2600MD, ABP2006MG, ABP2010MG,
7047d323ceSPetre Rodan 	ABP2016MG, ABP2025MG, ABP2040MG, ABP2060MG, ABP2100MG, ABP2160MG,
7147d323ceSPetre Rodan 	ABP2250MG, ABP2400MG, ABP2600MG, ABP2001ND, ABP2002ND, ABP2004ND,
7247d323ceSPetre Rodan 	ABP2005ND, ABP2010ND, ABP2020ND, ABP2030ND, ABP2002NG, ABP2004NG,
7347d323ceSPetre Rodan 	ABP2005NG, ABP2010NG, ABP2020NG, ABP2030NG, ABP2015PA, ABP2030PA,
7447d323ceSPetre Rodan 	ABP2060PA, ABP2100PA, ABP2150PA, ABP2175PA, ABP2001PD, ABP2005PD,
7547d323ceSPetre Rodan 	ABP2015PD, ABP2030PD, ABP2060PD, ABP2001PG, ABP2005PG, ABP2015PG,
7647d323ceSPetre Rodan 	ABP2030PG, ABP2060PG, ABP2100PG, ABP2150PG, ABP2175PG,
7747d323ceSPetre Rodan };
7847d323ceSPetre Rodan 
7947d323ceSPetre Rodan static const char * const abp2_triplet_variants[] = {
8047d323ceSPetre Rodan 	[ABP2001BA] = "001BA", [ABP21_6BA] = "1.6BA", [ABP22_5BA] = "2.5BA",
8147d323ceSPetre Rodan 	[ABP2004BA] = "004BA", [ABP2006BA] = "006BA", [ABP2008BA] = "008BA",
8247d323ceSPetre Rodan 	[ABP2010BA] = "010BA", [ABP2012BA] = "012BA", [ABP2001BD] = "001BD",
8347d323ceSPetre Rodan 	[ABP21_6BD] = "1.6BD", [ABP22_5BD] = "2.5BD", [ABP2004BD] = "004BD",
8447d323ceSPetre Rodan 	[ABP2001BG] = "001BG", [ABP21_6BG] = "1.6BG", [ABP22_5BG] = "2.5BG",
8547d323ceSPetre Rodan 	[ABP2004BG] = "004BG", [ABP2006BG] = "006BG", [ABP2008BG] = "008BG",
8647d323ceSPetre Rodan 	[ABP2010BG] = "010BG", [ABP2012BG] = "012BG", [ABP2001GG] = "001GG",
8747d323ceSPetre Rodan 	[ABP21_2GG] = "1.2GG", [ABP2100KA] = "100KA", [ABP2160KA] = "160KA",
8847d323ceSPetre Rodan 	[ABP2250KA] = "250KA", [ABP2001KD] = "001KD", [ABP21_6KD] = "1.6KD",
8947d323ceSPetre Rodan 	[ABP22_5KD] = "2.5KD", [ABP2004KD] = "004KD", [ABP2006KD] = "006KD",
9047d323ceSPetre Rodan 	[ABP2010KD] = "010KD", [ABP2016KD] = "016KD", [ABP2025KD] = "025KD",
9147d323ceSPetre Rodan 	[ABP2040KD] = "040KD", [ABP2060KD] = "060KD", [ABP2100KD] = "100KD",
9247d323ceSPetre Rodan 	[ABP2160KD] = "160KD", [ABP2250KD] = "250KD", [ABP2400KD] = "400KD",
9347d323ceSPetre Rodan 	[ABP2001KG] = "001KG", [ABP21_6KG] = "1.6KG", [ABP22_5KG] = "2.5KG",
9447d323ceSPetre Rodan 	[ABP2004KG] = "004KG", [ABP2006KG] = "006KG", [ABP2010KG] = "010KG",
9547d323ceSPetre Rodan 	[ABP2016KG] = "016KG", [ABP2025KG] = "025KG", [ABP2040KG] = "040KG",
9647d323ceSPetre Rodan 	[ABP2060KG] = "060KG", [ABP2100KG] = "100KG", [ABP2160KG] = "160KG",
9747d323ceSPetre Rodan 	[ABP2250KG] = "250KG", [ABP2400KG] = "400KG", [ABP2600KG] = "600KG",
9847d323ceSPetre Rodan 	[ABP2800KG] = "800KG", [ABP2250LD] = "250LD", [ABP2600LD] = "600LD",
9947d323ceSPetre Rodan 	[ABP2600LG] = "600LG", [ABP22_5MD] = "2.5MD", [ABP2006MD] = "006MD",
10047d323ceSPetre Rodan 	[ABP2010MD] = "010MD", [ABP2016MD] = "016MD", [ABP2025MD] = "025MD",
10147d323ceSPetre Rodan 	[ABP2040MD] = "040MD", [ABP2060MD] = "060MD", [ABP2100MD] = "100MD",
10247d323ceSPetre Rodan 	[ABP2160MD] = "160MD", [ABP2250MD] = "250MD", [ABP2400MD] = "400MD",
10347d323ceSPetre Rodan 	[ABP2600MD] = "600MD", [ABP2006MG] = "006MG", [ABP2010MG] = "010MG",
10447d323ceSPetre Rodan 	[ABP2016MG] = "016MG", [ABP2025MG] = "025MG", [ABP2040MG] = "040MG",
10547d323ceSPetre Rodan 	[ABP2060MG] = "060MG", [ABP2100MG] = "100MG", [ABP2160MG] = "160MG",
10647d323ceSPetre Rodan 	[ABP2250MG] = "250MG", [ABP2400MG] = "400MG", [ABP2600MG] = "600MG",
10747d323ceSPetre Rodan 	[ABP2001ND] = "001ND", [ABP2002ND] = "002ND", [ABP2004ND] = "004ND",
10847d323ceSPetre Rodan 	[ABP2005ND] = "005ND", [ABP2010ND] = "010ND", [ABP2020ND] = "020ND",
10947d323ceSPetre Rodan 	[ABP2030ND] = "030ND", [ABP2002NG] = "002NG", [ABP2004NG] = "004NG",
11047d323ceSPetre Rodan 	[ABP2005NG] = "005NG", [ABP2010NG] = "010NG", [ABP2020NG] = "020NG",
11147d323ceSPetre Rodan 	[ABP2030NG] = "030NG", [ABP2015PA] = "015PA", [ABP2030PA] = "030PA",
11247d323ceSPetre Rodan 	[ABP2060PA] = "060PA", [ABP2100PA] = "100PA", [ABP2150PA] = "150PA",
11347d323ceSPetre Rodan 	[ABP2175PA] = "175PA", [ABP2001PD] = "001PD", [ABP2005PD] = "005PD",
11447d323ceSPetre Rodan 	[ABP2015PD] = "015PD", [ABP2030PD] = "030PD", [ABP2060PD] = "060PD",
11547d323ceSPetre Rodan 	[ABP2001PG] = "001PG", [ABP2005PG] = "005PG", [ABP2015PG] = "015PG",
11647d323ceSPetre Rodan 	[ABP2030PG] = "030PG", [ABP2060PG] = "060PG", [ABP2100PG] = "100PG",
11747d323ceSPetre Rodan 	[ABP2150PG] = "150PG", [ABP2175PG] = "175PG",
11847d323ceSPetre Rodan };
11947d323ceSPetre Rodan 
12047d323ceSPetre Rodan /**
12147d323ceSPetre Rodan  * struct abp2_range_config - list of pressure ranges based on nomenclature
12247d323ceSPetre Rodan  * @pmin: lowest pressure that can be measured
12347d323ceSPetre Rodan  * @pmax: highest pressure that can be measured
12447d323ceSPetre Rodan  */
12547d323ceSPetre Rodan struct abp2_range_config {
12647d323ceSPetre Rodan 	s32 pmin;
12747d323ceSPetre Rodan 	s32 pmax;
12847d323ceSPetre Rodan };
12947d323ceSPetre Rodan 
13047d323ceSPetre Rodan /* All min max limits have been converted to pascals */
13147d323ceSPetre Rodan static const struct abp2_range_config abp2_range_config[] = {
13247d323ceSPetre Rodan 	[ABP2001BA] = { .pmin =       0, .pmax =  100000 },
13347d323ceSPetre Rodan 	[ABP21_6BA] = { .pmin =       0, .pmax =  160000 },
13447d323ceSPetre Rodan 	[ABP22_5BA] = { .pmin =       0, .pmax =  250000 },
13547d323ceSPetre Rodan 	[ABP2004BA] = { .pmin =       0, .pmax =  400000 },
13647d323ceSPetre Rodan 	[ABP2006BA] = { .pmin =       0, .pmax =  600000 },
13747d323ceSPetre Rodan 	[ABP2008BA] = { .pmin =       0, .pmax =  800000 },
13847d323ceSPetre Rodan 	[ABP2010BA] = { .pmin =       0, .pmax = 1000000 },
13947d323ceSPetre Rodan 	[ABP2012BA] = { .pmin =       0, .pmax = 1200000 },
14047d323ceSPetre Rodan 	[ABP2001BD] = { .pmin = -100000, .pmax =  100000 },
14147d323ceSPetre Rodan 	[ABP21_6BD] = { .pmin = -160000, .pmax =  160000 },
14247d323ceSPetre Rodan 	[ABP22_5BD] = { .pmin = -250000, .pmax =  250000 },
14347d323ceSPetre Rodan 	[ABP2004BD] = { .pmin = -400000, .pmax =  400000 },
14447d323ceSPetre Rodan 	[ABP2001BG] = { .pmin =       0, .pmax =  100000 },
14547d323ceSPetre Rodan 	[ABP21_6BG] = { .pmin =       0, .pmax =  160000 },
14647d323ceSPetre Rodan 	[ABP22_5BG] = { .pmin =       0, .pmax =  250000 },
14747d323ceSPetre Rodan 	[ABP2004BG] = { .pmin =       0, .pmax =  400000 },
14847d323ceSPetre Rodan 	[ABP2006BG] = { .pmin =       0, .pmax =  600000 },
14947d323ceSPetre Rodan 	[ABP2008BG] = { .pmin =       0, .pmax =  800000 },
15047d323ceSPetre Rodan 	[ABP2010BG] = { .pmin =       0, .pmax = 1000000 },
15147d323ceSPetre Rodan 	[ABP2012BG] = { .pmin =       0, .pmax = 1200000 },
15247d323ceSPetre Rodan 	[ABP2001GG] = { .pmin =       0, .pmax = 1000000 },
15347d323ceSPetre Rodan 	[ABP21_2GG] = { .pmin =       0, .pmax = 1200000 },
15447d323ceSPetre Rodan 	[ABP2100KA] = { .pmin =       0, .pmax =  100000 },
15547d323ceSPetre Rodan 	[ABP2160KA] = { .pmin =       0, .pmax =  160000 },
15647d323ceSPetre Rodan 	[ABP2250KA] = { .pmin =       0, .pmax =  250000 },
15747d323ceSPetre Rodan 	[ABP2001KD] = { .pmin =   -1000, .pmax =    1000 },
15847d323ceSPetre Rodan 	[ABP21_6KD] = { .pmin =   -1600, .pmax =    1600 },
15947d323ceSPetre Rodan 	[ABP22_5KD] = { .pmin =   -2500, .pmax =    2500 },
16047d323ceSPetre Rodan 	[ABP2004KD] = { .pmin =   -4000, .pmax =    4000 },
16147d323ceSPetre Rodan 	[ABP2006KD] = { .pmin =   -6000, .pmax =    6000 },
16247d323ceSPetre Rodan 	[ABP2010KD] = { .pmin =  -10000, .pmax =   10000 },
16347d323ceSPetre Rodan 	[ABP2016KD] = { .pmin =  -16000, .pmax =   16000 },
16447d323ceSPetre Rodan 	[ABP2025KD] = { .pmin =  -25000, .pmax =   25000 },
16547d323ceSPetre Rodan 	[ABP2040KD] = { .pmin =  -40000, .pmax =   40000 },
16647d323ceSPetre Rodan 	[ABP2060KD] = { .pmin =  -60000, .pmax =   60000 },
16747d323ceSPetre Rodan 	[ABP2100KD] = { .pmin = -100000, .pmax =  100000 },
16847d323ceSPetre Rodan 	[ABP2160KD] = { .pmin = -160000, .pmax =  160000 },
16947d323ceSPetre Rodan 	[ABP2250KD] = { .pmin = -250000, .pmax =  250000 },
17047d323ceSPetre Rodan 	[ABP2400KD] = { .pmin = -400000, .pmax =  400000 },
17147d323ceSPetre Rodan 	[ABP2001KG] = { .pmin =       0, .pmax =    1000 },
17247d323ceSPetre Rodan 	[ABP21_6KG] = { .pmin =       0, .pmax =    1600 },
17347d323ceSPetre Rodan 	[ABP22_5KG] = { .pmin =       0, .pmax =    2500 },
17447d323ceSPetre Rodan 	[ABP2004KG] = { .pmin =       0, .pmax =    4000 },
17547d323ceSPetre Rodan 	[ABP2006KG] = { .pmin =       0, .pmax =    6000 },
17647d323ceSPetre Rodan 	[ABP2010KG] = { .pmin =       0, .pmax =   10000 },
17747d323ceSPetre Rodan 	[ABP2016KG] = { .pmin =       0, .pmax =   16000 },
17847d323ceSPetre Rodan 	[ABP2025KG] = { .pmin =       0, .pmax =   25000 },
17947d323ceSPetre Rodan 	[ABP2040KG] = { .pmin =       0, .pmax =   40000 },
18047d323ceSPetre Rodan 	[ABP2060KG] = { .pmin =       0, .pmax =   60000 },
18147d323ceSPetre Rodan 	[ABP2100KG] = { .pmin =       0, .pmax =  100000 },
18247d323ceSPetre Rodan 	[ABP2160KG] = { .pmin =       0, .pmax =  160000 },
18347d323ceSPetre Rodan 	[ABP2250KG] = { .pmin =       0, .pmax =  250000 },
18447d323ceSPetre Rodan 	[ABP2400KG] = { .pmin =       0, .pmax =  400000 },
18547d323ceSPetre Rodan 	[ABP2600KG] = { .pmin =       0, .pmax =  600000 },
18647d323ceSPetre Rodan 	[ABP2800KG] = { .pmin =       0, .pmax =  800000 },
18747d323ceSPetre Rodan 	[ABP2250LD] = { .pmin =    -250, .pmax =     250 },
18847d323ceSPetre Rodan 	[ABP2600LD] = { .pmin =    -600, .pmax =     600 },
18947d323ceSPetre Rodan 	[ABP2600LG] = { .pmin =       0, .pmax =     600 },
19047d323ceSPetre Rodan 	[ABP22_5MD] = { .pmin =    -250, .pmax =     250 },
19147d323ceSPetre Rodan 	[ABP2006MD] = { .pmin =    -600, .pmax =     600 },
19247d323ceSPetre Rodan 	[ABP2010MD] = { .pmin =   -1000, .pmax =    1000 },
19347d323ceSPetre Rodan 	[ABP2016MD] = { .pmin =   -1600, .pmax =    1600 },
19447d323ceSPetre Rodan 	[ABP2025MD] = { .pmin =   -2500, .pmax =    2500 },
19547d323ceSPetre Rodan 	[ABP2040MD] = { .pmin =   -4000, .pmax =    4000 },
19647d323ceSPetre Rodan 	[ABP2060MD] = { .pmin =   -6000, .pmax =    6000 },
19747d323ceSPetre Rodan 	[ABP2100MD] = { .pmin =  -10000, .pmax =   10000 },
19847d323ceSPetre Rodan 	[ABP2160MD] = { .pmin =  -16000, .pmax =   16000 },
19947d323ceSPetre Rodan 	[ABP2250MD] = { .pmin =  -25000, .pmax =   25000 },
20047d323ceSPetre Rodan 	[ABP2400MD] = { .pmin =  -40000, .pmax =   40000 },
20147d323ceSPetre Rodan 	[ABP2600MD] = { .pmin =  -60000, .pmax =   60000 },
20247d323ceSPetre Rodan 	[ABP2006MG] = { .pmin =       0, .pmax =     600 },
20347d323ceSPetre Rodan 	[ABP2010MG] = { .pmin =       0, .pmax =    1000 },
20447d323ceSPetre Rodan 	[ABP2016MG] = { .pmin =       0, .pmax =    1600 },
20547d323ceSPetre Rodan 	[ABP2025MG] = { .pmin =       0, .pmax =    2500 },
20647d323ceSPetre Rodan 	[ABP2040MG] = { .pmin =       0, .pmax =    4000 },
20747d323ceSPetre Rodan 	[ABP2060MG] = { .pmin =       0, .pmax =    6000 },
20847d323ceSPetre Rodan 	[ABP2100MG] = { .pmin =       0, .pmax =   10000 },
20947d323ceSPetre Rodan 	[ABP2160MG] = { .pmin =       0, .pmax =   16000 },
21047d323ceSPetre Rodan 	[ABP2250MG] = { .pmin =       0, .pmax =   25000 },
21147d323ceSPetre Rodan 	[ABP2400MG] = { .pmin =       0, .pmax =   40000 },
21247d323ceSPetre Rodan 	[ABP2600MG] = { .pmin =       0, .pmax =   60000 },
21347d323ceSPetre Rodan 	[ABP2001ND] = { .pmin =    -249, .pmax =     249 },
21447d323ceSPetre Rodan 	[ABP2002ND] = { .pmin =    -498, .pmax =     498 },
21547d323ceSPetre Rodan 	[ABP2004ND] = { .pmin =    -996, .pmax =     996 },
21647d323ceSPetre Rodan 	[ABP2005ND] = { .pmin =   -1245, .pmax =    1245 },
21747d323ceSPetre Rodan 	[ABP2010ND] = { .pmin =   -2491, .pmax =    2491 },
21847d323ceSPetre Rodan 	[ABP2020ND] = { .pmin =   -4982, .pmax =    4982 },
21947d323ceSPetre Rodan 	[ABP2030ND] = { .pmin =   -7473, .pmax =    7473 },
22047d323ceSPetre Rodan 	[ABP2002NG] = { .pmin =       0, .pmax =     498 },
22147d323ceSPetre Rodan 	[ABP2004NG] = { .pmin =       0, .pmax =     996 },
22247d323ceSPetre Rodan 	[ABP2005NG] = { .pmin =       0, .pmax =    1245 },
22347d323ceSPetre Rodan 	[ABP2010NG] = { .pmin =       0, .pmax =    2491 },
22447d323ceSPetre Rodan 	[ABP2020NG] = { .pmin =       0, .pmax =    4982 },
22547d323ceSPetre Rodan 	[ABP2030NG] = { .pmin =       0, .pmax =    7473 },
22647d323ceSPetre Rodan 	[ABP2015PA] = { .pmin =       0, .pmax =  103421 },
22747d323ceSPetre Rodan 	[ABP2030PA] = { .pmin =       0, .pmax =  206843 },
22847d323ceSPetre Rodan 	[ABP2060PA] = { .pmin =       0, .pmax =  413685 },
22947d323ceSPetre Rodan 	[ABP2100PA] = { .pmin =       0, .pmax =  689476 },
23047d323ceSPetre Rodan 	[ABP2150PA] = { .pmin =       0, .pmax = 1034214 },
23147d323ceSPetre Rodan 	[ABP2175PA] = { .pmin =       0, .pmax = 1206583 },
23247d323ceSPetre Rodan 	[ABP2001PD] = { .pmin =   -6895, .pmax =    6895 },
23347d323ceSPetre Rodan 	[ABP2005PD] = { .pmin =  -34474, .pmax =   34474 },
23447d323ceSPetre Rodan 	[ABP2015PD] = { .pmin = -103421, .pmax =  103421 },
23547d323ceSPetre Rodan 	[ABP2030PD] = { .pmin = -206843, .pmax =  206843 },
23647d323ceSPetre Rodan 	[ABP2060PD] = { .pmin = -413685, .pmax =  413685 },
23747d323ceSPetre Rodan 	[ABP2001PG] = { .pmin =       0, .pmax =    6895 },
23847d323ceSPetre Rodan 	[ABP2005PG] = { .pmin =       0, .pmax =   34474 },
23947d323ceSPetre Rodan 	[ABP2015PG] = { .pmin =       0, .pmax =  103421 },
24047d323ceSPetre Rodan 	[ABP2030PG] = { .pmin =       0, .pmax =  206843 },
24147d323ceSPetre Rodan 	[ABP2060PG] = { .pmin =       0, .pmax =  413685 },
24247d323ceSPetre Rodan 	[ABP2100PG] = { .pmin =       0, .pmax =  689476 },
24347d323ceSPetre Rodan 	[ABP2150PG] = { .pmin =       0, .pmax = 1034214 },
24447d323ceSPetre Rodan 	[ABP2175PG] = { .pmin =       0, .pmax = 1206583 },
24547d323ceSPetre Rodan };
24647d323ceSPetre Rodan 
24747d323ceSPetre Rodan static_assert(ARRAY_SIZE(abp2_triplet_variants) == ARRAY_SIZE(abp2_range_config));
24847d323ceSPetre Rodan 
24947d323ceSPetre Rodan static int abp2_get_measurement(struct abp2_data *data)
25047d323ceSPetre Rodan {
25147d323ceSPetre Rodan 	struct device *dev = data->dev;
25247d323ceSPetre Rodan 	int ret;
25347d323ceSPetre Rodan 
25447d323ceSPetre Rodan 	reinit_completion(&data->completion);
25547d323ceSPetre Rodan 
25647d323ceSPetre Rodan 	ret = data->ops->write(data, ABP2_CMD_SYNC, ABP2_PKT_SYNC_LEN);
25747d323ceSPetre Rodan 	if (ret < 0)
25847d323ceSPetre Rodan 		return ret;
25947d323ceSPetre Rodan 
26047d323ceSPetre Rodan 	if (data->irq > 0) {
26147d323ceSPetre Rodan 		ret = wait_for_completion_timeout(&data->completion, HZ);
26247d323ceSPetre Rodan 		if (!ret) {
26347d323ceSPetre Rodan 			dev_err(dev, "timeout waiting for EOC interrupt\n");
26447d323ceSPetre Rodan 			return -ETIMEDOUT;
26547d323ceSPetre Rodan 		}
26647d323ceSPetre Rodan 	} else {
26747d323ceSPetre Rodan 		fsleep(5 * USEC_PER_MSEC);
26847d323ceSPetre Rodan 	}
26947d323ceSPetre Rodan 
27047d323ceSPetre Rodan 	memset(data->rx_buf, 0, sizeof(data->rx_buf));
27147d323ceSPetre Rodan 	ret = data->ops->read(data, ABP2_CMD_NOP, ABP2_PKT_NOP_LEN);
27247d323ceSPetre Rodan 	if (ret < 0)
27347d323ceSPetre Rodan 		return ret;
27447d323ceSPetre Rodan 
27547d323ceSPetre Rodan 	/*
27647d323ceSPetre Rodan 	 * Status byte flags
27747d323ceSPetre Rodan 	 *  bit7 SANITY_CHK     - must always be 0
27847d323ceSPetre Rodan 	 *  bit6 ABP2_ST_POWER  - 1 if device is powered
27947d323ceSPetre Rodan 	 *  bit5 ABP2_ST_BUSY   - 1 if device has no new conversion ready
28047d323ceSPetre Rodan 	 *  bit4 SANITY_CHK     - must always be 0
28147d323ceSPetre Rodan 	 *  bit3 SANITY_CHK     - must always be 0
28247d323ceSPetre Rodan 	 *  bit2 MEMORY_ERR     - 1 if integrity test has failed
28347d323ceSPetre Rodan 	 *  bit1 SANITY_CHK     - must always be 0
28447d323ceSPetre Rodan 	 *  bit0 MATH_ERR       - 1 during internal math saturation error
28547d323ceSPetre Rodan 	 */
28647d323ceSPetre Rodan 
28747d323ceSPetre Rodan 	if (data->rx_buf[0] == (ABP2_ST_POWER | ABP2_ST_BUSY))
28847d323ceSPetre Rodan 		return -EBUSY;
28947d323ceSPetre Rodan 
29047d323ceSPetre Rodan 	/*
29147d323ceSPetre Rodan 	 * The ABP2 sensor series seem to have a noticeable latch-up sensitivity.
29247d323ceSPetre Rodan 	 * A partial latch-up condition manifests as either
29347d323ceSPetre Rodan 	 *   - output of invalid status bytes
29447d323ceSPetre Rodan 	 *   - zeroed out conversions (despite a normal status byte)
29547d323ceSPetre Rodan 	 *   - the MOSI line being pulled low randomly in sync with the SCLK
29647d323ceSPetre Rodan 	 * signal (visible during the ABP2_CMD_NOP command).
29747d323ceSPetre Rodan 	 * https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1588325/am3358-spi-tx-data-corruption
29847d323ceSPetre Rodan 	 */
29947d323ceSPetre Rodan 
30047d323ceSPetre Rodan 	if (data->rx_buf[0] != ABP2_ST_POWER) {
30147d323ceSPetre Rodan 		dev_err(data->dev,
30247d323ceSPetre Rodan 			"unexpected status byte 0x%02x\n", data->rx_buf[0]);
30347d323ceSPetre Rodan 		return -EIO;
30447d323ceSPetre Rodan 	}
30547d323ceSPetre Rodan 
30647d323ceSPetre Rodan 	return 0;
30747d323ceSPetre Rodan }
30847d323ceSPetre Rodan 
30947d323ceSPetre Rodan static irqreturn_t abp2_eoc_handler(int irq, void *private)
31047d323ceSPetre Rodan {
31147d323ceSPetre Rodan 	struct abp2_data *data = private;
31247d323ceSPetre Rodan 
31347d323ceSPetre Rodan 	complete(&data->completion);
31447d323ceSPetre Rodan 
31547d323ceSPetre Rodan 	return IRQ_HANDLED;
31647d323ceSPetre Rodan }
31747d323ceSPetre Rodan 
31847d323ceSPetre Rodan static irqreturn_t abp2_trigger_handler(int irq, void *private)
31947d323ceSPetre Rodan {
32047d323ceSPetre Rodan 	int ret;
32147d323ceSPetre Rodan 	struct iio_poll_func *pf = private;
32247d323ceSPetre Rodan 	struct iio_dev *indio_dev = pf->indio_dev;
32347d323ceSPetre Rodan 	struct abp2_data *data = iio_priv(indio_dev);
32447d323ceSPetre Rodan 
32547d323ceSPetre Rodan 	ret = abp2_get_measurement(data);
32647d323ceSPetre Rodan 	if (ret < 0)
32747d323ceSPetre Rodan 		goto out_notify_done;
32847d323ceSPetre Rodan 
32947d323ceSPetre Rodan 	data->scan.chan[0] = get_unaligned_be24(&data->rx_buf[1]);
33047d323ceSPetre Rodan 	data->scan.chan[1] = get_unaligned_be24(&data->rx_buf[4]);
33147d323ceSPetre Rodan 
33247d323ceSPetre Rodan 	iio_push_to_buffers_with_ts(indio_dev, &data->scan, sizeof(data->scan),
33347d323ceSPetre Rodan 				    iio_get_time_ns(indio_dev));
33447d323ceSPetre Rodan 
33547d323ceSPetre Rodan out_notify_done:
33647d323ceSPetre Rodan 	iio_trigger_notify_done(indio_dev->trig);
33747d323ceSPetre Rodan 
33847d323ceSPetre Rodan 	return IRQ_HANDLED;
33947d323ceSPetre Rodan }
34047d323ceSPetre Rodan 
34147d323ceSPetre Rodan /*
34247d323ceSPetre Rodan  * IIO ABI expects
34347d323ceSPetre Rodan  * value = (conv + offset) * scale
34447d323ceSPetre Rodan  *
34547d323ceSPetre Rodan  * temp[C] = conv * a + b
34647d323ceSPetre Rodan  *   where a = 200/16777215; b = -50
34747d323ceSPetre Rodan  *
34847d323ceSPetre Rodan  *  temp[C] = (conv + (b/a)) * a * (1000)
34947d323ceSPetre Rodan  *  =>
35047d323ceSPetre Rodan  *  scale = a * 1000 = .0000119209296 * 1000 = .01192092966562
35147d323ceSPetre Rodan  *  offset = b/a = -50 * 16777215 / 200 = -4194303.75
35247d323ceSPetre Rodan  *
35347d323ceSPetre Rodan  *  pressure = (conv - Omin) * Q + Pmin =
35447d323ceSPetre Rodan  *          ((conv - Omin) + Pmin/Q) * Q
35547d323ceSPetre Rodan  *  =>
35647d323ceSPetre Rodan  *  scale = Q = (Pmax - Pmin) / (Omax - Omin)
35747d323ceSPetre Rodan  *  offset = Pmin/Q - Omin = Pmin * (Omax - Omin) / (Pmax - Pmin) - Omin
35847d323ceSPetre Rodan  */
35947d323ceSPetre Rodan static int abp2_read_raw(struct iio_dev *indio_dev,
36047d323ceSPetre Rodan 			 struct iio_chan_spec const *channel, int *val,
36147d323ceSPetre Rodan 			 int *val2, long mask)
36247d323ceSPetre Rodan {
36347d323ceSPetre Rodan 	struct abp2_data *data = iio_priv(indio_dev);
36447d323ceSPetre Rodan 	int ret;
36547d323ceSPetre Rodan 
36647d323ceSPetre Rodan 	switch (mask) {
36747d323ceSPetre Rodan 	case IIO_CHAN_INFO_RAW:
36847d323ceSPetre Rodan 		ret = abp2_get_measurement(data);
36947d323ceSPetre Rodan 		if (ret < 0)
37047d323ceSPetre Rodan 			return ret;
37147d323ceSPetre Rodan 
37247d323ceSPetre Rodan 		switch (channel->type) {
37347d323ceSPetre Rodan 		case IIO_PRESSURE:
37447d323ceSPetre Rodan 			*val = get_unaligned_be24(&data->rx_buf[1]);
37547d323ceSPetre Rodan 			return IIO_VAL_INT;
37647d323ceSPetre Rodan 		case IIO_TEMP:
37747d323ceSPetre Rodan 			*val = get_unaligned_be24(&data->rx_buf[4]);
37847d323ceSPetre Rodan 			return IIO_VAL_INT;
37947d323ceSPetre Rodan 		default:
38047d323ceSPetre Rodan 			return -EINVAL;
38147d323ceSPetre Rodan 		}
38247d323ceSPetre Rodan 		return IIO_VAL_INT;
38347d323ceSPetre Rodan 
38447d323ceSPetre Rodan 	case IIO_CHAN_INFO_SCALE:
38547d323ceSPetre Rodan 		switch (channel->type) {
38647d323ceSPetre Rodan 		case IIO_TEMP:
38747d323ceSPetre Rodan 			*val = 0;
38847d323ceSPetre Rodan 			*val2 = 11920929;
38947d323ceSPetre Rodan 			return IIO_VAL_INT_PLUS_NANO;
39047d323ceSPetre Rodan 		case IIO_PRESSURE:
39147d323ceSPetre Rodan 			*val = data->p_scale;
39247d323ceSPetre Rodan 			*val2 = data->p_scale_dec;
39347d323ceSPetre Rodan 			return IIO_VAL_INT_PLUS_NANO;
39447d323ceSPetre Rodan 		default:
39547d323ceSPetre Rodan 			return -EINVAL;
39647d323ceSPetre Rodan 		}
39747d323ceSPetre Rodan 
39847d323ceSPetre Rodan 	case IIO_CHAN_INFO_OFFSET:
39947d323ceSPetre Rodan 		switch (channel->type) {
40047d323ceSPetre Rodan 		case IIO_TEMP:
40147d323ceSPetre Rodan 			*val = -4194304;
40247d323ceSPetre Rodan 			return IIO_VAL_INT;
40347d323ceSPetre Rodan 		case IIO_PRESSURE:
40447d323ceSPetre Rodan 			*val = data->p_offset;
40547d323ceSPetre Rodan 			return IIO_VAL_INT;
40647d323ceSPetre Rodan 		default:
40747d323ceSPetre Rodan 			return -EINVAL;
40847d323ceSPetre Rodan 		}
40947d323ceSPetre Rodan 
41047d323ceSPetre Rodan 	default:
41147d323ceSPetre Rodan 		return -EINVAL;
41247d323ceSPetre Rodan 	}
41347d323ceSPetre Rodan }
41447d323ceSPetre Rodan 
41547d323ceSPetre Rodan static const struct iio_info abp2_info = {
41647d323ceSPetre Rodan 	.read_raw = &abp2_read_raw,
41747d323ceSPetre Rodan };
41847d323ceSPetre Rodan 
41947d323ceSPetre Rodan static const unsigned long abp2_scan_masks[] = {0x3, 0};
42047d323ceSPetre Rodan 
42147d323ceSPetre Rodan static const struct iio_chan_spec abp2_channels[] = {
42247d323ceSPetre Rodan 	{
42347d323ceSPetre Rodan 		.type = IIO_PRESSURE,
42447d323ceSPetre Rodan 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
42547d323ceSPetre Rodan 					BIT(IIO_CHAN_INFO_SCALE) |
42647d323ceSPetre Rodan 					BIT(IIO_CHAN_INFO_OFFSET),
42747d323ceSPetre Rodan 		.scan_index = 0,
42847d323ceSPetre Rodan 		.scan_type = {
42947d323ceSPetre Rodan 			.sign = 'u',
43047d323ceSPetre Rodan 			.realbits = 24,
43147d323ceSPetre Rodan 			.storagebits = 32,
43247d323ceSPetre Rodan 			.endianness = IIO_CPU,
43347d323ceSPetre Rodan 		},
43447d323ceSPetre Rodan 	},
43547d323ceSPetre Rodan 	{
43647d323ceSPetre Rodan 		.type = IIO_TEMP,
43747d323ceSPetre Rodan 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
43847d323ceSPetre Rodan 				      BIT(IIO_CHAN_INFO_SCALE) |
43947d323ceSPetre Rodan 				      BIT(IIO_CHAN_INFO_OFFSET),
44047d323ceSPetre Rodan 		.scan_index = 1,
44147d323ceSPetre Rodan 		.scan_type = {
44247d323ceSPetre Rodan 			.sign = 'u',
44347d323ceSPetre Rodan 			.realbits = 24,
44447d323ceSPetre Rodan 			.storagebits = 32,
44547d323ceSPetre Rodan 			.endianness = IIO_CPU,
44647d323ceSPetre Rodan 		},
44747d323ceSPetre Rodan 	},
44847d323ceSPetre Rodan 	IIO_CHAN_SOFT_TIMESTAMP(2),
44947d323ceSPetre Rodan };
45047d323ceSPetre Rodan 
45147d323ceSPetre Rodan int abp2_common_probe(struct device *dev, const struct abp2_ops *ops, int irq)
45247d323ceSPetre Rodan {
45347d323ceSPetre Rodan 	int ret;
45447d323ceSPetre Rodan 	struct abp2_data *data;
45547d323ceSPetre Rodan 	struct iio_dev *indio_dev;
45647d323ceSPetre Rodan 	const char *triplet;
45747d323ceSPetre Rodan 	s32 tmp;
45847d323ceSPetre Rodan 	s64 odelta, pdelta;
45947d323ceSPetre Rodan 
46047d323ceSPetre Rodan 	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
46147d323ceSPetre Rodan 	if (!indio_dev)
46247d323ceSPetre Rodan 		return -ENOMEM;
46347d323ceSPetre Rodan 
46447d323ceSPetre Rodan 	data = iio_priv(indio_dev);
46547d323ceSPetre Rodan 	data->dev = dev;
46647d323ceSPetre Rodan 	data->ops = ops;
46747d323ceSPetre Rodan 	data->irq = irq;
46847d323ceSPetre Rodan 
46947d323ceSPetre Rodan 	init_completion(&data->completion);
47047d323ceSPetre Rodan 
47147d323ceSPetre Rodan 	indio_dev->name = "abp2030pa";
47247d323ceSPetre Rodan 	indio_dev->info = &abp2_info;
47347d323ceSPetre Rodan 	indio_dev->channels = abp2_channels;
47447d323ceSPetre Rodan 	indio_dev->num_channels = ARRAY_SIZE(abp2_channels);
47547d323ceSPetre Rodan 	indio_dev->modes = INDIO_DIRECT_MODE;
47647d323ceSPetre Rodan 	indio_dev->available_scan_masks = abp2_scan_masks;
47747d323ceSPetre Rodan 
47847d323ceSPetre Rodan 	ret = devm_regulator_get_enable(dev, "vdd");
47947d323ceSPetre Rodan 	if (ret)
48047d323ceSPetre Rodan 		return dev_err_probe(dev, ret, "can't get and enable vdd supply\n");
48147d323ceSPetre Rodan 
48247d323ceSPetre Rodan 	ret = device_property_read_string(dev, "honeywell,pressure-triplet",
48347d323ceSPetre Rodan 					  &triplet);
48447d323ceSPetre Rodan 	if (ret) {
48547d323ceSPetre Rodan 		ret = device_property_read_u32(dev, "honeywell,pmin-pascal",
48647d323ceSPetre Rodan 					       &data->pmin);
48747d323ceSPetre Rodan 		if (ret)
48847d323ceSPetre Rodan 			return dev_err_probe(dev, ret,
48947d323ceSPetre Rodan 					     "honeywell,pmin-pascal could not be read\n");
49047d323ceSPetre Rodan 
49147d323ceSPetre Rodan 		ret = device_property_read_u32(dev, "honeywell,pmax-pascal",
49247d323ceSPetre Rodan 					       &data->pmax);
49347d323ceSPetre Rodan 		if (ret)
49447d323ceSPetre Rodan 			return dev_err_probe(dev, ret,
49547d323ceSPetre Rodan 					     "honeywell,pmax-pascal could not be read\n");
49647d323ceSPetre Rodan 	} else {
49747d323ceSPetre Rodan 		ret = device_property_match_property_string(dev,
49847d323ceSPetre Rodan 							    "honeywell,pressure-triplet",
49947d323ceSPetre Rodan 							    abp2_triplet_variants,
50047d323ceSPetre Rodan 							    ARRAY_SIZE(abp2_triplet_variants));
50147d323ceSPetre Rodan 		if (ret < 0)
50247d323ceSPetre Rodan 			return dev_err_probe(dev, -EINVAL, "honeywell,pressure-triplet is invalid\n");
50347d323ceSPetre Rodan 
50447d323ceSPetre Rodan 		data->pmin = abp2_range_config[ret].pmin;
50547d323ceSPetre Rodan 		data->pmax = abp2_range_config[ret].pmax;
50647d323ceSPetre Rodan 	}
50747d323ceSPetre Rodan 
50847d323ceSPetre Rodan 	if (data->pmin >= data->pmax)
50947d323ceSPetre Rodan 		return dev_err_probe(dev, -EINVAL, "pressure limits are invalid\n");
51047d323ceSPetre Rodan 
51147d323ceSPetre Rodan 	data->outmin = abp2_func_spec[data->function].output_min;
51247d323ceSPetre Rodan 	data->outmax = abp2_func_spec[data->function].output_max;
51347d323ceSPetre Rodan 
51447d323ceSPetre Rodan 	odelta = data->outmax - data->outmin;
51547d323ceSPetre Rodan 	pdelta = data->pmax - data->pmin;
51647d323ceSPetre Rodan 
51747d323ceSPetre Rodan 	data->p_scale = div_s64_rem(div_s64(pdelta * NANO, odelta), NANO, &tmp);
51847d323ceSPetre Rodan 	data->p_scale_dec = tmp;
51947d323ceSPetre Rodan 
52047d323ceSPetre Rodan 	data->p_offset = div_s64(odelta * data->pmin, pdelta) - data->outmin;
52147d323ceSPetre Rodan 
52247d323ceSPetre Rodan 	if (data->irq > 0) {
52347d323ceSPetre Rodan 		ret = devm_request_irq(dev, irq, abp2_eoc_handler, IRQF_ONESHOT,
52447d323ceSPetre Rodan 				       dev_name(dev), data);
52547d323ceSPetre Rodan 		if (ret)
526*b82f3047SPetre Rodan 			return ret;
52747d323ceSPetre Rodan 	}
52847d323ceSPetre Rodan 
52947d323ceSPetre Rodan 	ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
53047d323ceSPetre Rodan 					      abp2_trigger_handler, NULL);
53147d323ceSPetre Rodan 	if (ret)
53247d323ceSPetre Rodan 		return dev_err_probe(dev, ret, "iio triggered buffer setup failed\n");
53347d323ceSPetre Rodan 
53447d323ceSPetre Rodan 	ret = devm_iio_device_register(dev, indio_dev);
53547d323ceSPetre Rodan 	if (ret)
53647d323ceSPetre Rodan 		return dev_err_probe(dev, ret, "unable to register iio device\n");
53747d323ceSPetre Rodan 
53847d323ceSPetre Rodan 	return 0;
53947d323ceSPetre Rodan }
54047d323ceSPetre Rodan EXPORT_SYMBOL_NS_GPL(abp2_common_probe, "IIO_HONEYWELL_ABP2030PA");
54147d323ceSPetre Rodan 
54247d323ceSPetre Rodan MODULE_AUTHOR("Petre Rodan <petre.rodan@subdimension.ro>");
54347d323ceSPetre Rodan MODULE_DESCRIPTION("Honeywell ABP2 pressure sensor core driver");
54447d323ceSPetre Rodan MODULE_LICENSE("GPL");
545