0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/module.h>
0014 #include <linux/iio/iio.h>
0015 #include <linux/delay.h>
0016 #include <linux/regulator/consumer.h>
0017
0018 #include <linux/iio/sysfs.h>
0019 #include <linux/iio/buffer.h>
0020 #include <linux/iio/triggered_buffer.h>
0021 #include <linux/iio/trigger_consumer.h>
0022 #include "ms5611.h"
0023
0024 #define MS5611_INIT_OSR(_cmd, _conv_usec, _rate) \
0025 { .cmd = _cmd, .conv_usec = _conv_usec, .rate = _rate }
0026
0027 static const struct ms5611_osr ms5611_avail_pressure_osr[] = {
0028 MS5611_INIT_OSR(0x40, 600, 256),
0029 MS5611_INIT_OSR(0x42, 1170, 512),
0030 MS5611_INIT_OSR(0x44, 2280, 1024),
0031 MS5611_INIT_OSR(0x46, 4540, 2048),
0032 MS5611_INIT_OSR(0x48, 9040, 4096)
0033 };
0034
0035 static const struct ms5611_osr ms5611_avail_temp_osr[] = {
0036 MS5611_INIT_OSR(0x50, 600, 256),
0037 MS5611_INIT_OSR(0x52, 1170, 512),
0038 MS5611_INIT_OSR(0x54, 2280, 1024),
0039 MS5611_INIT_OSR(0x56, 4540, 2048),
0040 MS5611_INIT_OSR(0x58, 9040, 4096)
0041 };
0042
0043 static const char ms5611_show_osr[] = "256 512 1024 2048 4096";
0044
0045 static IIO_CONST_ATTR(oversampling_ratio_available, ms5611_show_osr);
0046
0047 static struct attribute *ms5611_attributes[] = {
0048 &iio_const_attr_oversampling_ratio_available.dev_attr.attr,
0049 NULL,
0050 };
0051
0052 static const struct attribute_group ms5611_attribute_group = {
0053 .attrs = ms5611_attributes,
0054 };
0055
0056 static bool ms5611_prom_is_valid(u16 *prom, size_t len)
0057 {
0058 int i, j;
0059 uint16_t crc = 0, crc_orig = prom[7] & 0x000F;
0060
0061 prom[7] &= 0xFF00;
0062
0063 for (i = 0; i < len * 2; i++) {
0064 if (i % 2 == 1)
0065 crc ^= prom[i >> 1] & 0x00FF;
0066 else
0067 crc ^= prom[i >> 1] >> 8;
0068
0069 for (j = 0; j < 8; j++) {
0070 if (crc & 0x8000)
0071 crc = (crc << 1) ^ 0x3000;
0072 else
0073 crc <<= 1;
0074 }
0075 }
0076
0077 crc = (crc >> 12) & 0x000F;
0078
0079 return crc_orig != 0x0000 && crc == crc_orig;
0080 }
0081
0082 static int ms5611_read_prom(struct iio_dev *indio_dev)
0083 {
0084 int ret, i;
0085 struct ms5611_state *st = iio_priv(indio_dev);
0086
0087 for (i = 0; i < MS5611_PROM_WORDS_NB; i++) {
0088 ret = st->read_prom_word(st, i, &st->chip_info->prom[i]);
0089 if (ret < 0) {
0090 dev_err(&indio_dev->dev,
0091 "failed to read prom at %d\n", i);
0092 return ret;
0093 }
0094 }
0095
0096 if (!ms5611_prom_is_valid(st->chip_info->prom, MS5611_PROM_WORDS_NB)) {
0097 dev_err(&indio_dev->dev, "PROM integrity check failed\n");
0098 return -ENODEV;
0099 }
0100
0101 return 0;
0102 }
0103
0104 static int ms5611_read_temp_and_pressure(struct iio_dev *indio_dev,
0105 s32 *temp, s32 *pressure)
0106 {
0107 int ret;
0108 struct ms5611_state *st = iio_priv(indio_dev);
0109
0110 ret = st->read_adc_temp_and_pressure(st, temp, pressure);
0111 if (ret < 0) {
0112 dev_err(&indio_dev->dev,
0113 "failed to read temperature and pressure\n");
0114 return ret;
0115 }
0116
0117 return st->chip_info->temp_and_pressure_compensate(st->chip_info,
0118 temp, pressure);
0119 }
0120
0121 static int ms5611_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info,
0122 s32 *temp, s32 *pressure)
0123 {
0124 s32 t = *temp, p = *pressure;
0125 s64 off, sens, dt;
0126
0127 dt = t - (chip_info->prom[5] << 8);
0128 off = ((s64)chip_info->prom[2] << 16) + ((chip_info->prom[4] * dt) >> 7);
0129 sens = ((s64)chip_info->prom[1] << 15) + ((chip_info->prom[3] * dt) >> 8);
0130
0131 t = 2000 + ((chip_info->prom[6] * dt) >> 23);
0132 if (t < 2000) {
0133 s64 off2, sens2, t2;
0134
0135 t2 = (dt * dt) >> 31;
0136 off2 = (5 * (t - 2000) * (t - 2000)) >> 1;
0137 sens2 = off2 >> 1;
0138
0139 if (t < -1500) {
0140 s64 tmp = (t + 1500) * (t + 1500);
0141
0142 off2 += 7 * tmp;
0143 sens2 += (11 * tmp) >> 1;
0144 }
0145
0146 t -= t2;
0147 off -= off2;
0148 sens -= sens2;
0149 }
0150
0151 *temp = t;
0152 *pressure = (((p * sens) >> 21) - off) >> 15;
0153
0154 return 0;
0155 }
0156
0157 static int ms5607_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info,
0158 s32 *temp, s32 *pressure)
0159 {
0160 s32 t = *temp, p = *pressure;
0161 s64 off, sens, dt;
0162
0163 dt = t - (chip_info->prom[5] << 8);
0164 off = ((s64)chip_info->prom[2] << 17) + ((chip_info->prom[4] * dt) >> 6);
0165 sens = ((s64)chip_info->prom[1] << 16) + ((chip_info->prom[3] * dt) >> 7);
0166
0167 t = 2000 + ((chip_info->prom[6] * dt) >> 23);
0168 if (t < 2000) {
0169 s64 off2, sens2, t2, tmp;
0170
0171 t2 = (dt * dt) >> 31;
0172 tmp = (t - 2000) * (t - 2000);
0173 off2 = (61 * tmp) >> 4;
0174 sens2 = tmp << 1;
0175
0176 if (t < -1500) {
0177 tmp = (t + 1500) * (t + 1500);
0178 off2 += 15 * tmp;
0179 sens2 += 8 * tmp;
0180 }
0181
0182 t -= t2;
0183 off -= off2;
0184 sens -= sens2;
0185 }
0186
0187 *temp = t;
0188 *pressure = (((p * sens) >> 21) - off) >> 15;
0189
0190 return 0;
0191 }
0192
0193 static int ms5611_reset(struct iio_dev *indio_dev)
0194 {
0195 int ret;
0196 struct ms5611_state *st = iio_priv(indio_dev);
0197
0198 ret = st->reset(st);
0199 if (ret < 0) {
0200 dev_err(&indio_dev->dev, "failed to reset device\n");
0201 return ret;
0202 }
0203
0204 usleep_range(3000, 4000);
0205
0206 return 0;
0207 }
0208
0209 static irqreturn_t ms5611_trigger_handler(int irq, void *p)
0210 {
0211 struct iio_poll_func *pf = p;
0212 struct iio_dev *indio_dev = pf->indio_dev;
0213 struct ms5611_state *st = iio_priv(indio_dev);
0214
0215 struct {
0216 s32 channels[2];
0217 s64 ts __aligned(8);
0218 } scan;
0219 int ret;
0220
0221 mutex_lock(&st->lock);
0222 ret = ms5611_read_temp_and_pressure(indio_dev, &scan.channels[1],
0223 &scan.channels[0]);
0224 mutex_unlock(&st->lock);
0225 if (ret < 0)
0226 goto err;
0227
0228 iio_push_to_buffers_with_timestamp(indio_dev, &scan,
0229 iio_get_time_ns(indio_dev));
0230
0231 err:
0232 iio_trigger_notify_done(indio_dev->trig);
0233
0234 return IRQ_HANDLED;
0235 }
0236
0237 static int ms5611_read_raw(struct iio_dev *indio_dev,
0238 struct iio_chan_spec const *chan,
0239 int *val, int *val2, long mask)
0240 {
0241 int ret;
0242 s32 temp, pressure;
0243 struct ms5611_state *st = iio_priv(indio_dev);
0244
0245 switch (mask) {
0246 case IIO_CHAN_INFO_PROCESSED:
0247 mutex_lock(&st->lock);
0248 ret = ms5611_read_temp_and_pressure(indio_dev,
0249 &temp, &pressure);
0250 mutex_unlock(&st->lock);
0251 if (ret < 0)
0252 return ret;
0253
0254 switch (chan->type) {
0255 case IIO_TEMP:
0256 *val = temp * 10;
0257 return IIO_VAL_INT;
0258 case IIO_PRESSURE:
0259 *val = pressure / 1000;
0260 *val2 = (pressure % 1000) * 1000;
0261 return IIO_VAL_INT_PLUS_MICRO;
0262 default:
0263 return -EINVAL;
0264 }
0265 case IIO_CHAN_INFO_SCALE:
0266 switch (chan->type) {
0267 case IIO_TEMP:
0268 *val = 10;
0269 return IIO_VAL_INT;
0270 case IIO_PRESSURE:
0271 *val = 0;
0272 *val2 = 1000;
0273 return IIO_VAL_INT_PLUS_MICRO;
0274 default:
0275 return -EINVAL;
0276 }
0277 case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
0278 if (chan->type != IIO_TEMP && chan->type != IIO_PRESSURE)
0279 break;
0280 mutex_lock(&st->lock);
0281 if (chan->type == IIO_TEMP)
0282 *val = (int)st->temp_osr->rate;
0283 else
0284 *val = (int)st->pressure_osr->rate;
0285 mutex_unlock(&st->lock);
0286 return IIO_VAL_INT;
0287 }
0288
0289 return -EINVAL;
0290 }
0291
0292 static const struct ms5611_osr *ms5611_find_osr(int rate,
0293 const struct ms5611_osr *osr,
0294 size_t count)
0295 {
0296 unsigned int r;
0297
0298 for (r = 0; r < count; r++)
0299 if ((unsigned short)rate == osr[r].rate)
0300 break;
0301 if (r >= count)
0302 return NULL;
0303 return &osr[r];
0304 }
0305
0306 static int ms5611_write_raw(struct iio_dev *indio_dev,
0307 struct iio_chan_spec const *chan,
0308 int val, int val2, long mask)
0309 {
0310 struct ms5611_state *st = iio_priv(indio_dev);
0311 const struct ms5611_osr *osr = NULL;
0312 int ret;
0313
0314 if (mask != IIO_CHAN_INFO_OVERSAMPLING_RATIO)
0315 return -EINVAL;
0316
0317 if (chan->type == IIO_TEMP)
0318 osr = ms5611_find_osr(val, ms5611_avail_temp_osr,
0319 ARRAY_SIZE(ms5611_avail_temp_osr));
0320 else if (chan->type == IIO_PRESSURE)
0321 osr = ms5611_find_osr(val, ms5611_avail_pressure_osr,
0322 ARRAY_SIZE(ms5611_avail_pressure_osr));
0323 if (!osr)
0324 return -EINVAL;
0325
0326 ret = iio_device_claim_direct_mode(indio_dev);
0327 if (ret)
0328 return ret;
0329
0330 mutex_lock(&st->lock);
0331
0332 if (chan->type == IIO_TEMP)
0333 st->temp_osr = osr;
0334 else
0335 st->pressure_osr = osr;
0336
0337 mutex_unlock(&st->lock);
0338 iio_device_release_direct_mode(indio_dev);
0339
0340 return 0;
0341 }
0342
0343 static const unsigned long ms5611_scan_masks[] = {0x3, 0};
0344
0345 static struct ms5611_chip_info chip_info_tbl[] = {
0346 [MS5611] = {
0347 .temp_and_pressure_compensate = ms5611_temp_and_pressure_compensate,
0348 },
0349 [MS5607] = {
0350 .temp_and_pressure_compensate = ms5607_temp_and_pressure_compensate,
0351 }
0352 };
0353
0354 static const struct iio_chan_spec ms5611_channels[] = {
0355 {
0356 .type = IIO_PRESSURE,
0357 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
0358 BIT(IIO_CHAN_INFO_SCALE) |
0359 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
0360 .scan_index = 0,
0361 .scan_type = {
0362 .sign = 's',
0363 .realbits = 32,
0364 .storagebits = 32,
0365 .endianness = IIO_CPU,
0366 },
0367 },
0368 {
0369 .type = IIO_TEMP,
0370 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
0371 BIT(IIO_CHAN_INFO_SCALE) |
0372 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
0373 .scan_index = 1,
0374 .scan_type = {
0375 .sign = 's',
0376 .realbits = 32,
0377 .storagebits = 32,
0378 .endianness = IIO_CPU,
0379 },
0380 },
0381 IIO_CHAN_SOFT_TIMESTAMP(2),
0382 };
0383
0384 static const struct iio_info ms5611_info = {
0385 .read_raw = &ms5611_read_raw,
0386 .write_raw = &ms5611_write_raw,
0387 .attrs = &ms5611_attribute_group,
0388 };
0389
0390 static int ms5611_init(struct iio_dev *indio_dev)
0391 {
0392 int ret;
0393 struct ms5611_state *st = iio_priv(indio_dev);
0394
0395
0396 st->vdd = devm_regulator_get(indio_dev->dev.parent, "vdd");
0397 if (IS_ERR(st->vdd))
0398 return PTR_ERR(st->vdd);
0399
0400 ret = regulator_enable(st->vdd);
0401 if (ret) {
0402 dev_err(indio_dev->dev.parent,
0403 "failed to enable Vdd supply: %d\n", ret);
0404 return ret;
0405 }
0406
0407 ret = ms5611_reset(indio_dev);
0408 if (ret < 0)
0409 goto err_regulator_disable;
0410
0411 ret = ms5611_read_prom(indio_dev);
0412 if (ret < 0)
0413 goto err_regulator_disable;
0414
0415 return 0;
0416
0417 err_regulator_disable:
0418 regulator_disable(st->vdd);
0419 return ret;
0420 }
0421
0422 static void ms5611_fini(const struct iio_dev *indio_dev)
0423 {
0424 const struct ms5611_state *st = iio_priv(indio_dev);
0425
0426 regulator_disable(st->vdd);
0427 }
0428
0429 int ms5611_probe(struct iio_dev *indio_dev, struct device *dev,
0430 const char *name, int type)
0431 {
0432 int ret;
0433 struct ms5611_state *st = iio_priv(indio_dev);
0434
0435 mutex_init(&st->lock);
0436 st->chip_info = &chip_info_tbl[type];
0437 st->temp_osr =
0438 &ms5611_avail_temp_osr[ARRAY_SIZE(ms5611_avail_temp_osr) - 1];
0439 st->pressure_osr =
0440 &ms5611_avail_pressure_osr[ARRAY_SIZE(ms5611_avail_pressure_osr)
0441 - 1];
0442 indio_dev->name = name;
0443 indio_dev->info = &ms5611_info;
0444 indio_dev->channels = ms5611_channels;
0445 indio_dev->num_channels = ARRAY_SIZE(ms5611_channels);
0446 indio_dev->modes = INDIO_DIRECT_MODE;
0447 indio_dev->available_scan_masks = ms5611_scan_masks;
0448
0449 ret = ms5611_init(indio_dev);
0450 if (ret < 0)
0451 return ret;
0452
0453 ret = iio_triggered_buffer_setup(indio_dev, NULL,
0454 ms5611_trigger_handler, NULL);
0455 if (ret < 0) {
0456 dev_err(dev, "iio triggered buffer setup failed\n");
0457 goto err_fini;
0458 }
0459
0460 ret = iio_device_register(indio_dev);
0461 if (ret < 0) {
0462 dev_err(dev, "unable to register iio device\n");
0463 goto err_buffer_cleanup;
0464 }
0465
0466 return 0;
0467
0468 err_buffer_cleanup:
0469 iio_triggered_buffer_cleanup(indio_dev);
0470 err_fini:
0471 ms5611_fini(indio_dev);
0472 return ret;
0473 }
0474 EXPORT_SYMBOL_NS(ms5611_probe, IIO_MS5611);
0475
0476 void ms5611_remove(struct iio_dev *indio_dev)
0477 {
0478 iio_device_unregister(indio_dev);
0479 iio_triggered_buffer_cleanup(indio_dev);
0480 ms5611_fini(indio_dev);
0481 }
0482 EXPORT_SYMBOL_NS(ms5611_remove, IIO_MS5611);
0483
0484 MODULE_AUTHOR("Tomasz Duszynski <tduszyns@gmail.com>");
0485 MODULE_DESCRIPTION("MS5611 core driver");
0486 MODULE_LICENSE("GPL v2");