| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * MS5611 pressure and temperature sensor driver |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com> |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 7 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 8 | | - * published by the Free Software Foundation. |
|---|
| 9 | 6 | * |
|---|
| 10 | 7 | * Data sheet: |
|---|
| 11 | 8 | * http://www.meas-spec.com/downloads/MS5611-01BA03.pdf |
|---|
| .. | .. |
|---|
| 88 | 85 | struct ms5611_state *st = iio_priv(indio_dev); |
|---|
| 89 | 86 | |
|---|
| 90 | 87 | for (i = 0; i < MS5611_PROM_WORDS_NB; i++) { |
|---|
| 91 | | - ret = st->read_prom_word(&indio_dev->dev, |
|---|
| 92 | | - i, &st->chip_info->prom[i]); |
|---|
| 88 | + ret = st->read_prom_word(st, i, &st->prom[i]); |
|---|
| 93 | 89 | if (ret < 0) { |
|---|
| 94 | 90 | dev_err(&indio_dev->dev, |
|---|
| 95 | 91 | "failed to read prom at %d\n", i); |
|---|
| .. | .. |
|---|
| 97 | 93 | } |
|---|
| 98 | 94 | } |
|---|
| 99 | 95 | |
|---|
| 100 | | - if (!ms5611_prom_is_valid(st->chip_info->prom, MS5611_PROM_WORDS_NB)) { |
|---|
| 96 | + if (!ms5611_prom_is_valid(st->prom, MS5611_PROM_WORDS_NB)) { |
|---|
| 101 | 97 | dev_err(&indio_dev->dev, "PROM integrity check failed\n"); |
|---|
| 102 | 98 | return -ENODEV; |
|---|
| 103 | 99 | } |
|---|
| .. | .. |
|---|
| 111 | 107 | int ret; |
|---|
| 112 | 108 | struct ms5611_state *st = iio_priv(indio_dev); |
|---|
| 113 | 109 | |
|---|
| 114 | | - ret = st->read_adc_temp_and_pressure(&indio_dev->dev, temp, pressure); |
|---|
| 110 | + ret = st->read_adc_temp_and_pressure(st, temp, pressure); |
|---|
| 115 | 111 | if (ret < 0) { |
|---|
| 116 | 112 | dev_err(&indio_dev->dev, |
|---|
| 117 | 113 | "failed to read temperature and pressure\n"); |
|---|
| 118 | 114 | return ret; |
|---|
| 119 | 115 | } |
|---|
| 120 | 116 | |
|---|
| 121 | | - return st->chip_info->temp_and_pressure_compensate(st->chip_info, |
|---|
| 122 | | - temp, pressure); |
|---|
| 117 | + return st->compensate_temp_and_pressure(st, temp, pressure); |
|---|
| 123 | 118 | } |
|---|
| 124 | 119 | |
|---|
| 125 | | -static int ms5611_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info, |
|---|
| 120 | +static int ms5611_temp_and_pressure_compensate(struct ms5611_state *st, |
|---|
| 126 | 121 | s32 *temp, s32 *pressure) |
|---|
| 127 | 122 | { |
|---|
| 128 | 123 | s32 t = *temp, p = *pressure; |
|---|
| 129 | 124 | s64 off, sens, dt; |
|---|
| 130 | 125 | |
|---|
| 131 | | - dt = t - (chip_info->prom[5] << 8); |
|---|
| 132 | | - off = ((s64)chip_info->prom[2] << 16) + ((chip_info->prom[4] * dt) >> 7); |
|---|
| 133 | | - sens = ((s64)chip_info->prom[1] << 15) + ((chip_info->prom[3] * dt) >> 8); |
|---|
| 126 | + dt = t - (st->prom[5] << 8); |
|---|
| 127 | + off = ((s64)st->prom[2] << 16) + ((st->prom[4] * dt) >> 7); |
|---|
| 128 | + sens = ((s64)st->prom[1] << 15) + ((st->prom[3] * dt) >> 8); |
|---|
| 134 | 129 | |
|---|
| 135 | | - t = 2000 + ((chip_info->prom[6] * dt) >> 23); |
|---|
| 130 | + t = 2000 + ((st->prom[6] * dt) >> 23); |
|---|
| 136 | 131 | if (t < 2000) { |
|---|
| 137 | 132 | s64 off2, sens2, t2; |
|---|
| 138 | 133 | |
|---|
| .. | .. |
|---|
| 158 | 153 | return 0; |
|---|
| 159 | 154 | } |
|---|
| 160 | 155 | |
|---|
| 161 | | -static int ms5607_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info, |
|---|
| 156 | +static int ms5607_temp_and_pressure_compensate(struct ms5611_state *st, |
|---|
| 162 | 157 | s32 *temp, s32 *pressure) |
|---|
| 163 | 158 | { |
|---|
| 164 | 159 | s32 t = *temp, p = *pressure; |
|---|
| 165 | 160 | s64 off, sens, dt; |
|---|
| 166 | 161 | |
|---|
| 167 | | - dt = t - (chip_info->prom[5] << 8); |
|---|
| 168 | | - off = ((s64)chip_info->prom[2] << 17) + ((chip_info->prom[4] * dt) >> 6); |
|---|
| 169 | | - sens = ((s64)chip_info->prom[1] << 16) + ((chip_info->prom[3] * dt) >> 7); |
|---|
| 162 | + dt = t - (st->prom[5] << 8); |
|---|
| 163 | + off = ((s64)st->prom[2] << 17) + ((st->prom[4] * dt) >> 6); |
|---|
| 164 | + sens = ((s64)st->prom[1] << 16) + ((st->prom[3] * dt) >> 7); |
|---|
| 170 | 165 | |
|---|
| 171 | | - t = 2000 + ((chip_info->prom[6] * dt) >> 23); |
|---|
| 166 | + t = 2000 + ((st->prom[6] * dt) >> 23); |
|---|
| 172 | 167 | if (t < 2000) { |
|---|
| 173 | 168 | s64 off2, sens2, t2, tmp; |
|---|
| 174 | 169 | |
|---|
| .. | .. |
|---|
| 199 | 194 | int ret; |
|---|
| 200 | 195 | struct ms5611_state *st = iio_priv(indio_dev); |
|---|
| 201 | 196 | |
|---|
| 202 | | - ret = st->reset(&indio_dev->dev); |
|---|
| 197 | + ret = st->reset(st); |
|---|
| 203 | 198 | if (ret < 0) { |
|---|
| 204 | 199 | dev_err(&indio_dev->dev, "failed to reset device\n"); |
|---|
| 205 | 200 | return ret; |
|---|
| .. | .. |
|---|
| 346 | 341 | |
|---|
| 347 | 342 | static const unsigned long ms5611_scan_masks[] = {0x3, 0}; |
|---|
| 348 | 343 | |
|---|
| 349 | | -static struct ms5611_chip_info chip_info_tbl[] = { |
|---|
| 350 | | - [MS5611] = { |
|---|
| 351 | | - .temp_and_pressure_compensate = ms5611_temp_and_pressure_compensate, |
|---|
| 352 | | - }, |
|---|
| 353 | | - [MS5607] = { |
|---|
| 354 | | - .temp_and_pressure_compensate = ms5607_temp_and_pressure_compensate, |
|---|
| 355 | | - } |
|---|
| 356 | | -}; |
|---|
| 357 | | - |
|---|
| 358 | 344 | static const struct iio_chan_spec ms5611_channels[] = { |
|---|
| 359 | 345 | { |
|---|
| 360 | 346 | .type = IIO_PRESSURE, |
|---|
| .. | .. |
|---|
| 437 | 423 | struct ms5611_state *st = iio_priv(indio_dev); |
|---|
| 438 | 424 | |
|---|
| 439 | 425 | mutex_init(&st->lock); |
|---|
| 440 | | - st->chip_info = &chip_info_tbl[type]; |
|---|
| 426 | + |
|---|
| 427 | + switch (type) { |
|---|
| 428 | + case MS5611: |
|---|
| 429 | + st->compensate_temp_and_pressure = |
|---|
| 430 | + ms5611_temp_and_pressure_compensate; |
|---|
| 431 | + break; |
|---|
| 432 | + case MS5607: |
|---|
| 433 | + st->compensate_temp_and_pressure = |
|---|
| 434 | + ms5607_temp_and_pressure_compensate; |
|---|
| 435 | + break; |
|---|
| 436 | + default: |
|---|
| 437 | + return -EINVAL; |
|---|
| 438 | + } |
|---|
| 439 | + |
|---|
| 441 | 440 | st->temp_osr = |
|---|
| 442 | 441 | &ms5611_avail_temp_osr[ARRAY_SIZE(ms5611_avail_temp_osr) - 1]; |
|---|
| 443 | 442 | st->pressure_osr = |
|---|
| 444 | 443 | &ms5611_avail_pressure_osr[ARRAY_SIZE(ms5611_avail_pressure_osr) |
|---|
| 445 | 444 | - 1]; |
|---|
| 446 | | - indio_dev->dev.parent = dev; |
|---|
| 447 | 445 | indio_dev->name = name; |
|---|
| 448 | 446 | indio_dev->info = &ms5611_info; |
|---|
| 449 | 447 | indio_dev->channels = ms5611_channels; |
|---|