2 * MS5611 pressure and temperature sensor driver (I2C bus)
4 * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com>
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.
10 * 7-bit I2C slave addresses:
17 #include <linux/delay.h>
18 #include <linux/i2c.h>
19 #include <linux/module.h>
20 #include <linux/of_device.h>
24 static int ms5611_i2c_reset(struct device
*dev
)
26 struct ms5611_state
*st
= iio_priv(dev_to_iio_dev(dev
));
28 return i2c_smbus_write_byte(st
->client
, MS5611_RESET
);
31 static int ms5611_i2c_read_prom_word(struct device
*dev
, int index
, u16
*word
)
34 struct ms5611_state
*st
= iio_priv(dev_to_iio_dev(dev
));
36 ret
= i2c_smbus_read_word_swapped(st
->client
,
37 MS5611_READ_PROM_WORD
+ (index
<< 1));
46 static int ms5611_i2c_read_adc(struct ms5611_state
*st
, s32
*val
)
51 ret
= i2c_smbus_read_i2c_block_data(st
->client
, MS5611_READ_ADC
,
56 *val
= (buf
[0] << 16) | (buf
[1] << 8) | buf
[2];
61 static int ms5611_i2c_read_adc_temp_and_pressure(struct device
*dev
,
62 s32
*temp
, s32
*pressure
)
65 struct ms5611_state
*st
= iio_priv(dev_to_iio_dev(dev
));
66 const struct ms5611_osr
*osr
= st
->temp_osr
;
68 ret
= i2c_smbus_write_byte(st
->client
, osr
->cmd
);
72 usleep_range(osr
->conv_usec
, osr
->conv_usec
+ (osr
->conv_usec
/ 10UL));
73 ret
= ms5611_i2c_read_adc(st
, temp
);
77 osr
= st
->pressure_osr
;
78 ret
= i2c_smbus_write_byte(st
->client
, osr
->cmd
);
82 usleep_range(osr
->conv_usec
, osr
->conv_usec
+ (osr
->conv_usec
/ 10UL));
83 return ms5611_i2c_read_adc(st
, pressure
);
86 static int ms5611_i2c_probe(struct i2c_client
*client
,
87 const struct i2c_device_id
*id
)
89 struct ms5611_state
*st
;
90 struct iio_dev
*indio_dev
;
92 if (!i2c_check_functionality(client
->adapter
,
93 I2C_FUNC_SMBUS_WRITE_BYTE
|
94 I2C_FUNC_SMBUS_READ_WORD_DATA
|
95 I2C_FUNC_SMBUS_READ_I2C_BLOCK
))
98 indio_dev
= devm_iio_device_alloc(&client
->dev
, sizeof(*st
));
102 st
= iio_priv(indio_dev
);
103 i2c_set_clientdata(client
, indio_dev
);
104 st
->reset
= ms5611_i2c_reset
;
105 st
->read_prom_word
= ms5611_i2c_read_prom_word
;
106 st
->read_adc_temp_and_pressure
= ms5611_i2c_read_adc_temp_and_pressure
;
109 return ms5611_probe(indio_dev
, &client
->dev
, id
->name
, id
->driver_data
);
112 static int ms5611_i2c_remove(struct i2c_client
*client
)
114 return ms5611_remove(i2c_get_clientdata(client
));
117 #if defined(CONFIG_OF)
118 static const struct of_device_id ms5611_i2c_matches
[] = {
119 { .compatible
= "meas,ms5611" },
120 { .compatible
= "ms5611" },
121 { .compatible
= "meas,ms5607" },
122 { .compatible
= "ms5607" },
125 MODULE_DEVICE_TABLE(of
, ms5611_i2c_matches
);
128 static const struct i2c_device_id ms5611_id
[] = {
129 { "ms5611", MS5611
},
130 { "ms5607", MS5607
},
133 MODULE_DEVICE_TABLE(i2c
, ms5611_id
);
135 static struct i2c_driver ms5611_driver
= {
138 .of_match_table
= of_match_ptr(ms5611_i2c_matches
)
140 .id_table
= ms5611_id
,
141 .probe
= ms5611_i2c_probe
,
142 .remove
= ms5611_i2c_remove
,
144 module_i2c_driver(ms5611_driver
);
146 MODULE_AUTHOR("Tomasz Duszynski <tduszyns@gmail.com>");
147 MODULE_DESCRIPTION("MS5611 i2c driver");
148 MODULE_LICENSE("GPL v2");