1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * MS5611 pressure and temperature sensor driver
4  *
5  * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com>
6  *
7  * Data sheet:
8  *  http://www.meas-spec.com/downloads/MS5611-01BA03.pdf
9  *  http://www.meas-spec.com/downloads/MS5607-02BA03.pdf
10  *
11  */
12 
13 #include <linux/module.h>
14 #include <linux/iio/iio.h>
15 #include <linux/delay.h>
16 #include <linux/regulator/consumer.h>
17 
18 #include <linux/iio/sysfs.h>
19 #include <linux/iio/buffer.h>
20 #include <linux/iio/triggered_buffer.h>
21 #include <linux/iio/trigger_consumer.h>
22 #include "ms5611.h"
23 
24 #define MS5611_INIT_OSR(_cmd, _conv_usec, _rate) \
25 	{ .cmd = _cmd, .conv_usec = _conv_usec, .rate = _rate }
26 
27 static const struct ms5611_osr ms5611_avail_pressure_osr[] = {
28 	MS5611_INIT_OSR(0x40, 600,  256),
29 	MS5611_INIT_OSR(0x42, 1170, 512),
30 	MS5611_INIT_OSR(0x44, 2280, 1024),
31 	MS5611_INIT_OSR(0x46, 4540, 2048),
32 	MS5611_INIT_OSR(0x48, 9040, 4096)
33 };
34 
35 static const struct ms5611_osr ms5611_avail_temp_osr[] = {
36 	MS5611_INIT_OSR(0x50, 600,  256),
37 	MS5611_INIT_OSR(0x52, 1170, 512),
38 	MS5611_INIT_OSR(0x54, 2280, 1024),
39 	MS5611_INIT_OSR(0x56, 4540, 2048),
40 	MS5611_INIT_OSR(0x58, 9040, 4096)
41 };
42 
43 static const char ms5611_show_osr[] = "256 512 1024 2048 4096";
44 
45 static IIO_CONST_ATTR(oversampling_ratio_available, ms5611_show_osr);
46 
47 static struct attribute *ms5611_attributes[] = {
48 	&iio_const_attr_oversampling_ratio_available.dev_attr.attr,
49 	NULL,
50 };
51 
52 static const struct attribute_group ms5611_attribute_group = {
53 	.attrs = ms5611_attributes,
54 };
55 
56 static bool ms5611_prom_is_valid(u16 *prom, size_t len)
57 {
58 	int i, j;
59 	uint16_t crc = 0, crc_orig = prom[7] & 0x000F;
60 
61 	prom[7] &= 0xFF00;
62 
63 	for (i = 0; i < len * 2; i++) {
64 		if (i % 2 == 1)
65 			crc ^= prom[i >> 1] & 0x00FF;
66 		else
67 			crc ^= prom[i >> 1] >> 8;
68 
69 		for (j = 0; j < 8; j++) {
70 			if (crc & 0x8000)
71 				crc = (crc << 1) ^ 0x3000;
72 			else
73 				crc <<= 1;
74 		}
75 	}
76 
77 	crc = (crc >> 12) & 0x000F;
78 
79 	return crc_orig != 0x0000 && crc == crc_orig;
80 }
81 
82 static int ms5611_read_prom(struct iio_dev *indio_dev)
83 {
84 	int ret, i;
85 	struct ms5611_state *st = iio_priv(indio_dev);
86 
87 	for (i = 0; i < MS5611_PROM_WORDS_NB; i++) {
88 		ret = st->read_prom_word(st, i, &st->chip_info->prom[i]);
89 		if (ret < 0) {
90 			dev_err(&indio_dev->dev,
91 				"failed to read prom at %d\n", i);
92 			return ret;
93 		}
94 	}
95 
96 	if (!ms5611_prom_is_valid(st->chip_info->prom, MS5611_PROM_WORDS_NB)) {
97 		dev_err(&indio_dev->dev, "PROM integrity check failed\n");
98 		return -ENODEV;
99 	}
100 
101 	return 0;
102 }
103 
104 static int ms5611_read_temp_and_pressure(struct iio_dev *indio_dev,
105 					 s32 *temp, s32 *pressure)
106 {
107 	int ret;
108 	struct ms5611_state *st = iio_priv(indio_dev);
109 
110 	ret = st->read_adc_temp_and_pressure(st, temp, pressure);
111 	if (ret < 0) {
112 		dev_err(&indio_dev->dev,
113 			"failed to read temperature and pressure\n");
114 		return ret;
115 	}
116 
117 	return st->chip_info->temp_and_pressure_compensate(st->chip_info,
118 							   temp, pressure);
119 }
120 
121 static int ms5611_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info,
122 					       s32 *temp, s32 *pressure)
123 {
124 	s32 t = *temp, p = *pressure;
125 	s64 off, sens, dt;
126 
127 	dt = t - (chip_info->prom[5] << 8);
128 	off = ((s64)chip_info->prom[2] << 16) + ((chip_info->prom[4] * dt) >> 7);
129 	sens = ((s64)chip_info->prom[1] << 15) + ((chip_info->prom[3] * dt) >> 8);
130 
131 	t = 2000 + ((chip_info->prom[6] * dt) >> 23);
132 	if (t < 2000) {
133 		s64 off2, sens2, t2;
134 
135 		t2 = (dt * dt) >> 31;
136 		off2 = (5 * (t - 2000) * (t - 2000)) >> 1;
137 		sens2 = off2 >> 1;
138 
139 		if (t < -1500) {
140 			s64 tmp = (t + 1500) * (t + 1500);
141 
142 			off2 += 7 * tmp;
143 			sens2 += (11 * tmp) >> 1;
144 		}
145 
146 		t -= t2;
147 		off -= off2;
148 		sens -= sens2;
149 	}
150 
151 	*temp = t;
152 	*pressure = (((p * sens) >> 21) - off) >> 15;
153 
154 	return 0;
155 }
156 
157 static int ms5607_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info,
158 					       s32 *temp, s32 *pressure)
159 {
160 	s32 t = *temp, p = *pressure;
161 	s64 off, sens, dt;
162 
163 	dt = t - (chip_info->prom[5] << 8);
164 	off = ((s64)chip_info->prom[2] << 17) + ((chip_info->prom[4] * dt) >> 6);
165 	sens = ((s64)chip_info->prom[1] << 16) + ((chip_info->prom[3] * dt) >> 7);
166 
167 	t = 2000 + ((chip_info->prom[6] * dt) >> 23);
168 	if (t < 2000) {
169 		s64 off2, sens2, t2, tmp;
170 
171 		t2 = (dt * dt) >> 31;
172 		tmp = (t - 2000) * (t - 2000);
173 		off2 = (61 * tmp) >> 4;
174 		sens2 = tmp << 1;
175 
176 		if (t < -1500) {
177 			tmp = (t + 1500) * (t + 1500);
178 			off2 += 15 * tmp;
179 			sens2 += 8 * tmp;
180 		}
181 
182 		t -= t2;
183 		off -= off2;
184 		sens -= sens2;
185 	}
186 
187 	*temp = t;
188 	*pressure = (((p * sens) >> 21) - off) >> 15;
189 
190 	return 0;
191 }
192 
193 static int ms5611_reset(struct iio_dev *indio_dev)
194 {
195 	int ret;
196 	struct ms5611_state *st = iio_priv(indio_dev);
197 
198 	ret = st->reset(st);
199 	if (ret < 0) {
200 		dev_err(&indio_dev->dev, "failed to reset device\n");
201 		return ret;
202 	}
203 
204 	usleep_range(3000, 4000);
205 
206 	return 0;
207 }
208 
209 static irqreturn_t ms5611_trigger_handler(int irq, void *p)
210 {
211 	struct iio_poll_func *pf = p;
212 	struct iio_dev *indio_dev = pf->indio_dev;
213 	struct ms5611_state *st = iio_priv(indio_dev);
214 	/* Ensure buffer elements are naturally aligned */
215 	struct {
216 		s32 channels[2];
217 		s64 ts __aligned(8);
218 	} scan;
219 	int ret;
220 
221 	mutex_lock(&st->lock);
222 	ret = ms5611_read_temp_and_pressure(indio_dev, &scan.channels[1],
223 					    &scan.channels[0]);
224 	mutex_unlock(&st->lock);
225 	if (ret < 0)
226 		goto err;
227 
228 	iio_push_to_buffers_with_timestamp(indio_dev, &scan,
229 					   iio_get_time_ns(indio_dev));
230 
231 err:
232 	iio_trigger_notify_done(indio_dev->trig);
233 
234 	return IRQ_HANDLED;
235 }
236 
237 static int ms5611_read_raw(struct iio_dev *indio_dev,
238 			   struct iio_chan_spec const *chan,
239 			   int *val, int *val2, long mask)
240 {
241 	int ret;
242 	s32 temp, pressure;
243 	struct ms5611_state *st = iio_priv(indio_dev);
244 
245 	switch (mask) {
246 	case IIO_CHAN_INFO_PROCESSED:
247 		mutex_lock(&st->lock);
248 		ret = ms5611_read_temp_and_pressure(indio_dev,
249 						    &temp, &pressure);
250 		mutex_unlock(&st->lock);
251 		if (ret < 0)
252 			return ret;
253 
254 		switch (chan->type) {
255 		case IIO_TEMP:
256 			*val = temp * 10;
257 			return IIO_VAL_INT;
258 		case IIO_PRESSURE:
259 			*val = pressure / 1000;
260 			*val2 = (pressure % 1000) * 1000;
261 			return IIO_VAL_INT_PLUS_MICRO;
262 		default:
263 			return -EINVAL;
264 		}
265 	case IIO_CHAN_INFO_SCALE:
266 		switch (chan->type) {
267 		case IIO_TEMP:
268 			*val = 10;
269 			return IIO_VAL_INT;
270 		case IIO_PRESSURE:
271 			*val = 0;
272 			*val2 = 1000;
273 			return IIO_VAL_INT_PLUS_MICRO;
274 		default:
275 			return -EINVAL;
276 		}
277 	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
278 		if (chan->type != IIO_TEMP && chan->type != IIO_PRESSURE)
279 			break;
280 		mutex_lock(&st->lock);
281 		if (chan->type == IIO_TEMP)
282 			*val = (int)st->temp_osr->rate;
283 		else
284 			*val = (int)st->pressure_osr->rate;
285 		mutex_unlock(&st->lock);
286 		return IIO_VAL_INT;
287 	}
288 
289 	return -EINVAL;
290 }
291 
292 static const struct ms5611_osr *ms5611_find_osr(int rate,
293 						const struct ms5611_osr *osr,
294 						size_t count)
295 {
296 	unsigned int r;
297 
298 	for (r = 0; r < count; r++)
299 		if ((unsigned short)rate == osr[r].rate)
300 			break;
301 	if (r >= count)
302 		return NULL;
303 	return &osr[r];
304 }
305 
306 static int ms5611_write_raw(struct iio_dev *indio_dev,
307 			    struct iio_chan_spec const *chan,
308 			    int val, int val2, long mask)
309 {
310 	struct ms5611_state *st = iio_priv(indio_dev);
311 	const struct ms5611_osr *osr = NULL;
312 	int ret;
313 
314 	if (mask != IIO_CHAN_INFO_OVERSAMPLING_RATIO)
315 		return -EINVAL;
316 
317 	if (chan->type == IIO_TEMP)
318 		osr = ms5611_find_osr(val, ms5611_avail_temp_osr,
319 				      ARRAY_SIZE(ms5611_avail_temp_osr));
320 	else if (chan->type == IIO_PRESSURE)
321 		osr = ms5611_find_osr(val, ms5611_avail_pressure_osr,
322 				      ARRAY_SIZE(ms5611_avail_pressure_osr));
323 	if (!osr)
324 		return -EINVAL;
325 
326 	ret = iio_device_claim_direct_mode(indio_dev);
327 	if (ret)
328 		return ret;
329 
330 	mutex_lock(&st->lock);
331 
332 	if (chan->type == IIO_TEMP)
333 		st->temp_osr = osr;
334 	else
335 		st->pressure_osr = osr;
336 
337 	mutex_unlock(&st->lock);
338 	iio_device_release_direct_mode(indio_dev);
339 
340 	return 0;
341 }
342 
343 static const unsigned long ms5611_scan_masks[] = {0x3, 0};
344 
345 static struct ms5611_chip_info chip_info_tbl[] = {
346 	[MS5611] = {
347 		.temp_and_pressure_compensate = ms5611_temp_and_pressure_compensate,
348 	},
349 	[MS5607] = {
350 		.temp_and_pressure_compensate = ms5607_temp_and_pressure_compensate,
351 	}
352 };
353 
354 static const struct iio_chan_spec ms5611_channels[] = {
355 	{
356 		.type = IIO_PRESSURE,
357 		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
358 			BIT(IIO_CHAN_INFO_SCALE) |
359 			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
360 		.scan_index = 0,
361 		.scan_type = {
362 			.sign = 's',
363 			.realbits = 32,
364 			.storagebits = 32,
365 			.endianness = IIO_CPU,
366 		},
367 	},
368 	{
369 		.type = IIO_TEMP,
370 		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
371 			BIT(IIO_CHAN_INFO_SCALE) |
372 			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
373 		.scan_index = 1,
374 		.scan_type = {
375 			.sign = 's',
376 			.realbits = 32,
377 			.storagebits = 32,
378 			.endianness = IIO_CPU,
379 		},
380 	},
381 	IIO_CHAN_SOFT_TIMESTAMP(2),
382 };
383 
384 static const struct iio_info ms5611_info = {
385 	.read_raw = &ms5611_read_raw,
386 	.write_raw = &ms5611_write_raw,
387 	.attrs = &ms5611_attribute_group,
388 };
389 
390 static int ms5611_init(struct iio_dev *indio_dev)
391 {
392 	int ret;
393 	struct ms5611_state *st = iio_priv(indio_dev);
394 
395 	/* Enable attached regulator if any. */
396 	st->vdd = devm_regulator_get(indio_dev->dev.parent, "vdd");
397 	if (IS_ERR(st->vdd))
398 		return PTR_ERR(st->vdd);
399 
400 	ret = regulator_enable(st->vdd);
401 	if (ret) {
402 		dev_err(indio_dev->dev.parent,
403 			"failed to enable Vdd supply: %d\n", ret);
404 		return ret;
405 	}
406 
407 	ret = ms5611_reset(indio_dev);
408 	if (ret < 0)
409 		goto err_regulator_disable;
410 
411 	ret = ms5611_read_prom(indio_dev);
412 	if (ret < 0)
413 		goto err_regulator_disable;
414 
415 	return 0;
416 
417 err_regulator_disable:
418 	regulator_disable(st->vdd);
419 	return ret;
420 }
421 
422 static void ms5611_fini(const struct iio_dev *indio_dev)
423 {
424 	const struct ms5611_state *st = iio_priv(indio_dev);
425 
426 	regulator_disable(st->vdd);
427 }
428 
429 int ms5611_probe(struct iio_dev *indio_dev, struct device *dev,
430 		 const char *name, int type)
431 {
432 	int ret;
433 	struct ms5611_state *st = iio_priv(indio_dev);
434 
435 	mutex_init(&st->lock);
436 	st->chip_info = &chip_info_tbl[type];
437 	st->temp_osr =
438 		&ms5611_avail_temp_osr[ARRAY_SIZE(ms5611_avail_temp_osr) - 1];
439 	st->pressure_osr =
440 		&ms5611_avail_pressure_osr[ARRAY_SIZE(ms5611_avail_pressure_osr)
441 					   - 1];
442 	indio_dev->name = name;
443 	indio_dev->info = &ms5611_info;
444 	indio_dev->channels = ms5611_channels;
445 	indio_dev->num_channels = ARRAY_SIZE(ms5611_channels);
446 	indio_dev->modes = INDIO_DIRECT_MODE;
447 	indio_dev->available_scan_masks = ms5611_scan_masks;
448 
449 	ret = ms5611_init(indio_dev);
450 	if (ret < 0)
451 		return ret;
452 
453 	ret = iio_triggered_buffer_setup(indio_dev, NULL,
454 					 ms5611_trigger_handler, NULL);
455 	if (ret < 0) {
456 		dev_err(dev, "iio triggered buffer setup failed\n");
457 		goto err_fini;
458 	}
459 
460 	ret = iio_device_register(indio_dev);
461 	if (ret < 0) {
462 		dev_err(dev, "unable to register iio device\n");
463 		goto err_buffer_cleanup;
464 	}
465 
466 	return 0;
467 
468 err_buffer_cleanup:
469 	iio_triggered_buffer_cleanup(indio_dev);
470 err_fini:
471 	ms5611_fini(indio_dev);
472 	return ret;
473 }
474 EXPORT_SYMBOL(ms5611_probe);
475 
476 void ms5611_remove(struct iio_dev *indio_dev)
477 {
478 	iio_device_unregister(indio_dev);
479 	iio_triggered_buffer_cleanup(indio_dev);
480 	ms5611_fini(indio_dev);
481 }
482 EXPORT_SYMBOL(ms5611_remove);
483 
484 MODULE_AUTHOR("Tomasz Duszynski <tduszyns@gmail.com>");
485 MODULE_DESCRIPTION("MS5611 core driver");
486 MODULE_LICENSE("GPL v2");
487