1 // SPDX-License-Identifier: GPL-2.0
3 * MS5611 pressure and temperature sensor driver (I2C bus)
5 * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com>
7 * 7-bit I2C slave addresses:
14 #include <linux/delay.h>
15 #include <linux/i2c.h>
16 #include <linux/module.h>
17 #include <linux/of_device.h>
21 static int ms5611_i2c_reset(struct device
*dev
)
23 struct ms5611_state
*st
= iio_priv(dev_to_iio_dev(dev
));
25 return i2c_smbus_write_byte(st
->client
, MS5611_RESET
);
28 static int ms5611_i2c_read_prom_word(struct device
*dev
, int index
, u16
*word
)
31 struct ms5611_state
*st
= iio_priv(dev_to_iio_dev(dev
));
33 ret
= i2c_smbus_read_word_swapped(st
->client
,
34 MS5611_READ_PROM_WORD
+ (index
<< 1));
43 static int ms5611_i2c_read_adc(struct ms5611_state
*st
, s32
*val
)
48 ret
= i2c_smbus_read_i2c_block_data(st
->client
, MS5611_READ_ADC
,
53 *val
= (buf
[0] << 16) | (buf
[1] << 8) | buf
[2];
58 static int ms5611_i2c_read_adc_temp_and_pressure(struct device
*dev
,
59 s32
*temp
, s32
*pressure
)
62 struct ms5611_state
*st
= iio_priv(dev_to_iio_dev(dev
));
63 const struct ms5611_osr
*osr
= st
->temp_osr
;
65 ret
= i2c_smbus_write_byte(st
->client
, osr
->cmd
);
69 usleep_range(osr
->conv_usec
, osr
->conv_usec
+ (osr
->conv_usec
/ 10UL));
70 ret
= ms5611_i2c_read_adc(st
, temp
);
74 osr
= st
->pressure_osr
;
75 ret
= i2c_smbus_write_byte(st
->client
, osr
->cmd
);
79 usleep_range(osr
->conv_usec
, osr
->conv_usec
+ (osr
->conv_usec
/ 10UL));
80 return ms5611_i2c_read_adc(st
, pressure
);
83 static int ms5611_i2c_probe(struct i2c_client
*client
,
84 const struct i2c_device_id
*id
)
86 struct ms5611_state
*st
;
87 struct iio_dev
*indio_dev
;
89 if (!i2c_check_functionality(client
->adapter
,
90 I2C_FUNC_SMBUS_WRITE_BYTE
|
91 I2C_FUNC_SMBUS_READ_WORD_DATA
|
92 I2C_FUNC_SMBUS_READ_I2C_BLOCK
))
95 indio_dev
= devm_iio_device_alloc(&client
->dev
, sizeof(*st
));
99 st
= iio_priv(indio_dev
);
100 i2c_set_clientdata(client
, indio_dev
);
101 st
->reset
= ms5611_i2c_reset
;
102 st
->read_prom_word
= ms5611_i2c_read_prom_word
;
103 st
->read_adc_temp_and_pressure
= ms5611_i2c_read_adc_temp_and_pressure
;
106 return ms5611_probe(indio_dev
, &client
->dev
, id
->name
, id
->driver_data
);
109 static int ms5611_i2c_remove(struct i2c_client
*client
)
111 return ms5611_remove(i2c_get_clientdata(client
));
114 #if defined(CONFIG_OF)
115 static const struct of_device_id ms5611_i2c_matches
[] = {
116 { .compatible
= "meas,ms5611" },
117 { .compatible
= "meas,ms5607" },
120 MODULE_DEVICE_TABLE(of
, ms5611_i2c_matches
);
123 static const struct i2c_device_id ms5611_id
[] = {
124 { "ms5611", MS5611
},
125 { "ms5607", MS5607
},
128 MODULE_DEVICE_TABLE(i2c
, ms5611_id
);
130 static struct i2c_driver ms5611_driver
= {
133 .of_match_table
= of_match_ptr(ms5611_i2c_matches
)
135 .id_table
= ms5611_id
,
136 .probe
= ms5611_i2c_probe
,
137 .remove
= ms5611_i2c_remove
,
139 module_i2c_driver(ms5611_driver
);
141 MODULE_AUTHOR("Tomasz Duszynski <tduszyns@gmail.com>");
142 MODULE_DESCRIPTION("MS5611 i2c driver");
143 MODULE_LICENSE("GPL v2");