0001
0002
0003
0004
0005 #include <linux/delay.h>
0006 #include <linux/device.h>
0007 #include <linux/err.h>
0008 #include <linux/i2c.h>
0009 #include <linux/io.h>
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/iio/iio.h>
0013
0014 #define ABP060MG_ERROR_MASK 0xC000
0015 #define ABP060MG_RESP_TIME_MS 40
0016 #define ABP060MG_MIN_COUNTS 1638
0017 #define ABP060MG_MAX_COUNTS 14745
0018 #define ABP060MG_NUM_COUNTS (ABP060MG_MAX_COUNTS - ABP060MG_MIN_COUNTS)
0019
0020 enum abp_variant {
0021
0022 ABP006KG, ABP010KG, ABP016KG, ABP025KG, ABP040KG, ABP060KG, ABP100KG,
0023 ABP160KG, ABP250KG, ABP400KG, ABP600KG, ABP001GG,
0024
0025 ABP006KD, ABP010KD, ABP016KD, ABP025KD, ABP040KD, ABP060KD, ABP100KD,
0026 ABP160KD, ABP250KD, ABP400KD,
0027
0028 ABP001PG, ABP005PG, ABP015PG, ABP030PG, ABP060PG, ABP100PG, ABP150PG,
0029
0030 ABP001PD, ABP005PD, ABP015PD, ABP030PD, ABP060PD,
0031 };
0032
0033 struct abp_config {
0034 int min;
0035 int max;
0036 };
0037
0038 static struct abp_config abp_config[] = {
0039
0040 [ABP006KG] = { .min = 0, .max = 6000 },
0041 [ABP010KG] = { .min = 0, .max = 10000 },
0042 [ABP016KG] = { .min = 0, .max = 16000 },
0043 [ABP025KG] = { .min = 0, .max = 25000 },
0044 [ABP040KG] = { .min = 0, .max = 40000 },
0045 [ABP060KG] = { .min = 0, .max = 60000 },
0046 [ABP100KG] = { .min = 0, .max = 100000 },
0047 [ABP160KG] = { .min = 0, .max = 160000 },
0048 [ABP250KG] = { .min = 0, .max = 250000 },
0049 [ABP400KG] = { .min = 0, .max = 400000 },
0050 [ABP600KG] = { .min = 0, .max = 600000 },
0051 [ABP001GG] = { .min = 0, .max = 1000000 },
0052 [ABP006KD] = { .min = -6000, .max = 6000 },
0053 [ABP010KD] = { .min = -10000, .max = 10000 },
0054 [ABP016KD] = { .min = -16000, .max = 16000 },
0055 [ABP025KD] = { .min = -25000, .max = 25000 },
0056 [ABP040KD] = { .min = -40000, .max = 40000 },
0057 [ABP060KD] = { .min = -60000, .max = 60000 },
0058 [ABP100KD] = { .min = -100000, .max = 100000 },
0059 [ABP160KD] = { .min = -160000, .max = 160000 },
0060 [ABP250KD] = { .min = -250000, .max = 250000 },
0061 [ABP400KD] = { .min = -400000, .max = 400000 },
0062
0063 [ABP001PG] = { .min = 0, .max = 6985 },
0064 [ABP005PG] = { .min = 0, .max = 34474 },
0065 [ABP015PG] = { .min = 0, .max = 103421 },
0066 [ABP030PG] = { .min = 0, .max = 206843 },
0067 [ABP060PG] = { .min = 0, .max = 413686 },
0068 [ABP100PG] = { .min = 0, .max = 689476 },
0069 [ABP150PG] = { .min = 0, .max = 1034214 },
0070 [ABP001PD] = { .min = -6895, .max = 6895 },
0071 [ABP005PD] = { .min = -34474, .max = 34474 },
0072 [ABP015PD] = { .min = -103421, .max = 103421 },
0073 [ABP030PD] = { .min = -206843, .max = 206843 },
0074 [ABP060PD] = { .min = -413686, .max = 413686 },
0075 };
0076
0077 struct abp_state {
0078 struct i2c_client *client;
0079 struct mutex lock;
0080
0081
0082
0083
0084
0085 int mreq_len;
0086
0087
0088 int scale;
0089 int offset;
0090 };
0091
0092 static const struct iio_chan_spec abp060mg_channels[] = {
0093 {
0094 .type = IIO_PRESSURE,
0095 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
0096 BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE),
0097 },
0098 };
0099
0100 static int abp060mg_get_measurement(struct abp_state *state, int *val)
0101 {
0102 struct i2c_client *client = state->client;
0103 __be16 buf[2];
0104 u16 pressure;
0105 int ret;
0106
0107 buf[0] = 0;
0108 ret = i2c_master_send(client, (u8 *)&buf, state->mreq_len);
0109 if (ret < 0)
0110 return ret;
0111
0112 msleep_interruptible(ABP060MG_RESP_TIME_MS);
0113
0114 ret = i2c_master_recv(client, (u8 *)&buf, sizeof(buf));
0115 if (ret < 0)
0116 return ret;
0117
0118 pressure = be16_to_cpu(buf[0]);
0119 if (pressure & ABP060MG_ERROR_MASK)
0120 return -EIO;
0121
0122 if (pressure < ABP060MG_MIN_COUNTS || pressure > ABP060MG_MAX_COUNTS)
0123 return -EIO;
0124
0125 *val = pressure;
0126
0127 return IIO_VAL_INT;
0128 }
0129
0130 static int abp060mg_read_raw(struct iio_dev *indio_dev,
0131 struct iio_chan_spec const *chan, int *val,
0132 int *val2, long mask)
0133 {
0134 struct abp_state *state = iio_priv(indio_dev);
0135 int ret;
0136
0137 mutex_lock(&state->lock);
0138
0139 switch (mask) {
0140 case IIO_CHAN_INFO_RAW:
0141 ret = abp060mg_get_measurement(state, val);
0142 break;
0143 case IIO_CHAN_INFO_OFFSET:
0144 *val = state->offset;
0145 ret = IIO_VAL_INT;
0146 break;
0147 case IIO_CHAN_INFO_SCALE:
0148 *val = state->scale;
0149 *val2 = ABP060MG_NUM_COUNTS * 1000;
0150 ret = IIO_VAL_FRACTIONAL;
0151 break;
0152 default:
0153 ret = -EINVAL;
0154 break;
0155 }
0156
0157 mutex_unlock(&state->lock);
0158 return ret;
0159 }
0160
0161 static const struct iio_info abp060mg_info = {
0162 .read_raw = abp060mg_read_raw,
0163 };
0164
0165 static void abp060mg_init_device(struct iio_dev *indio_dev, unsigned long id)
0166 {
0167 struct abp_state *state = iio_priv(indio_dev);
0168 struct abp_config *cfg = &abp_config[id];
0169
0170 state->scale = cfg->max - cfg->min;
0171 state->offset = -ABP060MG_MIN_COUNTS;
0172
0173 if (cfg->min < 0)
0174 state->offset -= ABP060MG_NUM_COUNTS >> 1;
0175 }
0176
0177 static int abp060mg_probe(struct i2c_client *client,
0178 const struct i2c_device_id *id)
0179 {
0180 struct iio_dev *indio_dev;
0181 struct abp_state *state;
0182 unsigned long cfg_id = id->driver_data;
0183
0184 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*state));
0185 if (!indio_dev)
0186 return -ENOMEM;
0187
0188 state = iio_priv(indio_dev);
0189 i2c_set_clientdata(client, state);
0190 state->client = client;
0191
0192 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_QUICK))
0193 state->mreq_len = 1;
0194
0195 abp060mg_init_device(indio_dev, cfg_id);
0196
0197 indio_dev->name = dev_name(&client->dev);
0198 indio_dev->modes = INDIO_DIRECT_MODE;
0199 indio_dev->info = &abp060mg_info;
0200
0201 indio_dev->channels = abp060mg_channels;
0202 indio_dev->num_channels = ARRAY_SIZE(abp060mg_channels);
0203
0204 mutex_init(&state->lock);
0205
0206 return devm_iio_device_register(&client->dev, indio_dev);
0207 }
0208
0209 static const struct i2c_device_id abp060mg_id_table[] = {
0210
0211
0212 { "abp060mg", ABP006KG }, { "abp006kg", ABP006KG },
0213 { "abp100mg", ABP010KG }, { "abp010kg", ABP010KG },
0214 { "abp160mg", ABP016KG }, { "abp016kg", ABP016KG },
0215 { "abp250mg", ABP025KG }, { "abp025kg", ABP025KG },
0216 { "abp400mg", ABP040KG }, { "abp040kg", ABP040KG },
0217 { "abp600mg", ABP060KG }, { "abp060kg", ABP060KG },
0218 { "abp001bg", ABP100KG }, { "abp100kg", ABP100KG },
0219 { "abp1_6bg", ABP160KG }, { "abp160kg", ABP160KG },
0220 { "abp2_5bg", ABP250KG }, { "abp250kg", ABP250KG },
0221 { "abp004bg", ABP400KG }, { "abp400kg", ABP400KG },
0222 { "abp006bg", ABP600KG }, { "abp600kg", ABP600KG },
0223 { "abp010bg", ABP001GG }, { "abp001gg", ABP001GG },
0224
0225 { "abp060md", ABP006KD }, { "abp006kd", ABP006KD },
0226 { "abp100md", ABP010KD }, { "abp010kd", ABP010KD },
0227 { "abp160md", ABP016KD }, { "abp016kd", ABP016KD },
0228 { "abp250md", ABP025KD }, { "abp025kd", ABP025KD },
0229 { "abp400md", ABP040KD }, { "abp040kd", ABP040KD },
0230 { "abp600md", ABP060KD }, { "abp060kd", ABP060KD },
0231 { "abp001bd", ABP100KD }, { "abp100kd", ABP100KD },
0232 { "abp1_6bd", ABP160KD }, { "abp160kd", ABP160KD },
0233 { "abp2_5bd", ABP250KD }, { "abp250kd", ABP250KD },
0234 { "abp004bd", ABP400KD }, { "abp400kd", ABP400KD },
0235
0236
0237 { "abp001pg", ABP001PG },
0238 { "abp005pg", ABP005PG },
0239 { "abp015pg", ABP015PG },
0240 { "abp030pg", ABP030PG },
0241 { "abp060pg", ABP060PG },
0242 { "abp100pg", ABP100PG },
0243 { "abp150pg", ABP150PG },
0244
0245 { "abp001pd", ABP001PD },
0246 { "abp005pd", ABP005PD },
0247 { "abp015pd", ABP015PD },
0248 { "abp030pd", ABP030PD },
0249 { "abp060pd", ABP060PD },
0250 { },
0251 };
0252 MODULE_DEVICE_TABLE(i2c, abp060mg_id_table);
0253
0254 static struct i2c_driver abp060mg_driver = {
0255 .driver = {
0256 .name = "abp060mg",
0257 },
0258 .probe = abp060mg_probe,
0259 .id_table = abp060mg_id_table,
0260 };
0261 module_i2c_driver(abp060mg_driver);
0262
0263 MODULE_AUTHOR("Marcin Malagowski <mrc@bourne.st>");
0264 MODULE_DESCRIPTION("Honeywell ABP pressure sensor driver");
0265 MODULE_LICENSE("GPL");