1 /* 2 * t5403.c - Support for EPCOS T5403 pressure/temperature sensor 3 * 4 * Copyright (c) 2014 Peter Meerwald <pmeerw@pmeerw.net> 5 * 6 * This file is subject to the terms and conditions of version 2 of 7 * the GNU General Public License. See the file COPYING in the main 8 * directory of this archive for more details. 9 * 10 * (7-bit I2C slave address 0x77) 11 * 12 * TODO: end-of-conversion irq 13 */ 14 15 #include <linux/module.h> 16 #include <linux/i2c.h> 17 #include <linux/iio/iio.h> 18 #include <linux/iio/sysfs.h> 19 #include <linux/delay.h> 20 21 #define T5403_DATA 0xf5 /* data, LSB first, 16 bit */ 22 #define T5403_CALIB_DATA 0x8e /* 10 calibration coeff., LSB first, 16 bit */ 23 #define T5403_SLAVE_ADDR 0x88 /* I2C slave address, 0x77 */ 24 #define T5403_COMMAND 0xf1 25 26 /* command bits */ 27 #define T5403_MODE_SHIFT 3 /* conversion time: 2, 8, 16, 66 ms */ 28 #define T5403_PT BIT(1) /* 0 .. pressure, 1 .. temperature measurement */ 29 #define T5403_SCO BIT(0) /* start conversion */ 30 31 #define T5403_MODE_LOW 0 32 #define T5403_MODE_STANDARD 1 33 #define T5403_MODE_HIGH 2 34 #define T5403_MODE_ULTRA_HIGH 3 35 36 #define T5403_I2C_MASK (~BIT(7)) 37 #define T5403_I2C_ADDR 0x77 38 39 static const int t5403_pressure_conv_ms[] = {2, 8, 16, 66}; 40 41 struct t5403_data { 42 struct i2c_client *client; 43 struct mutex lock; 44 int mode; 45 __le16 c[10]; 46 }; 47 48 #define T5403_C_U16(i) le16_to_cpu(data->c[(i) - 1]) 49 #define T5403_C(i) sign_extend32(T5403_C_U16(i), 15) 50 51 static int t5403_read(struct t5403_data *data, bool pressure) 52 { 53 int wait_time = 3; /* wakeup time in ms */ 54 55 int ret = i2c_smbus_write_byte_data(data->client, T5403_COMMAND, 56 (pressure ? (data->mode << T5403_MODE_SHIFT) : T5403_PT) | 57 T5403_SCO); 58 if (ret < 0) 59 return ret; 60 61 wait_time += pressure ? t5403_pressure_conv_ms[data->mode] : 2; 62 63 msleep(wait_time); 64 65 return i2c_smbus_read_word_data(data->client, T5403_DATA); 66 } 67 68 static int t5403_comp_pressure(struct t5403_data *data, int *val, int *val2) 69 { 70 int ret; 71 s16 t_r; 72 u16 p_r; 73 s32 S, O, X; 74 75 mutex_lock(&data->lock); 76 77 ret = t5403_read(data, false); 78 if (ret < 0) 79 goto done; 80 t_r = ret; 81 82 ret = t5403_read(data, true); 83 if (ret < 0) 84 goto done; 85 p_r = ret; 86 87 /* see EPCOS application note */ 88 S = T5403_C_U16(3) + (s32) T5403_C_U16(4) * t_r / 0x20000 + 89 T5403_C(5) * t_r / 0x8000 * t_r / 0x80000 + 90 T5403_C(9) * t_r / 0x8000 * t_r / 0x8000 * t_r / 0x10000; 91 92 O = T5403_C(6) * 0x4000 + T5403_C(7) * t_r / 8 + 93 T5403_C(8) * t_r / 0x8000 * t_r / 16 + 94 T5403_C(9) * t_r / 0x8000 * t_r / 0x10000 * t_r; 95 96 X = (S * p_r + O) / 0x4000; 97 98 X += ((X - 75000) * (X - 75000) / 0x10000 - 9537) * 99 T5403_C(10) / 0x10000; 100 101 *val = X / 1000; 102 *val2 = (X % 1000) * 1000; 103 104 done: 105 mutex_unlock(&data->lock); 106 return ret; 107 } 108 109 static int t5403_comp_temp(struct t5403_data *data, int *val) 110 { 111 int ret; 112 s16 t_r; 113 114 mutex_lock(&data->lock); 115 ret = t5403_read(data, false); 116 if (ret < 0) 117 goto done; 118 t_r = ret; 119 120 /* see EPCOS application note */ 121 *val = ((s32) T5403_C_U16(1) * t_r / 0x100 + 122 (s32) T5403_C_U16(2) * 0x40) * 1000 / 0x10000; 123 124 done: 125 mutex_unlock(&data->lock); 126 return ret; 127 } 128 129 static int t5403_read_raw(struct iio_dev *indio_dev, 130 struct iio_chan_spec const *chan, 131 int *val, int *val2, long mask) 132 { 133 struct t5403_data *data = iio_priv(indio_dev); 134 int ret; 135 136 switch (mask) { 137 case IIO_CHAN_INFO_PROCESSED: 138 switch (chan->type) { 139 case IIO_PRESSURE: 140 ret = t5403_comp_pressure(data, val, val2); 141 if (ret < 0) 142 return ret; 143 return IIO_VAL_INT_PLUS_MICRO; 144 case IIO_TEMP: 145 ret = t5403_comp_temp(data, val); 146 if (ret < 0) 147 return ret; 148 return IIO_VAL_INT; 149 default: 150 return -EINVAL; 151 } 152 case IIO_CHAN_INFO_INT_TIME: 153 *val = 0; 154 *val2 = t5403_pressure_conv_ms[data->mode] * 1000; 155 return IIO_VAL_INT_PLUS_MICRO; 156 default: 157 return -EINVAL; 158 } 159 } 160 161 static int t5403_write_raw(struct iio_dev *indio_dev, 162 struct iio_chan_spec const *chan, 163 int val, int val2, long mask) 164 { 165 struct t5403_data *data = iio_priv(indio_dev); 166 int i; 167 168 switch (mask) { 169 case IIO_CHAN_INFO_INT_TIME: 170 if (val != 0) 171 return -EINVAL; 172 for (i = 0; i < ARRAY_SIZE(t5403_pressure_conv_ms); i++) 173 if (val2 == t5403_pressure_conv_ms[i] * 1000) { 174 mutex_lock(&data->lock); 175 data->mode = i; 176 mutex_unlock(&data->lock); 177 return 0; 178 } 179 return -EINVAL; 180 default: 181 return -EINVAL; 182 } 183 } 184 185 static const struct iio_chan_spec t5403_channels[] = { 186 { 187 .type = IIO_PRESSURE, 188 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | 189 BIT(IIO_CHAN_INFO_INT_TIME), 190 }, 191 { 192 .type = IIO_TEMP, 193 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), 194 }, 195 }; 196 197 static IIO_CONST_ATTR_INT_TIME_AVAIL("0.002 0.008 0.016 0.066"); 198 199 static struct attribute *t5403_attributes[] = { 200 &iio_const_attr_integration_time_available.dev_attr.attr, 201 NULL 202 }; 203 204 static const struct attribute_group t5403_attribute_group = { 205 .attrs = t5403_attributes, 206 }; 207 208 static const struct iio_info t5403_info = { 209 .read_raw = &t5403_read_raw, 210 .write_raw = &t5403_write_raw, 211 .attrs = &t5403_attribute_group, 212 .driver_module = THIS_MODULE, 213 }; 214 215 static int t5403_probe(struct i2c_client *client, 216 const struct i2c_device_id *id) 217 { 218 struct t5403_data *data; 219 struct iio_dev *indio_dev; 220 int ret; 221 222 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA | 223 I2C_FUNC_SMBUS_I2C_BLOCK)) 224 return -EOPNOTSUPP; 225 226 ret = i2c_smbus_read_byte_data(client, T5403_SLAVE_ADDR); 227 if (ret < 0) 228 return ret; 229 if ((ret & T5403_I2C_MASK) != T5403_I2C_ADDR) 230 return -ENODEV; 231 232 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 233 if (!indio_dev) 234 return -ENOMEM; 235 236 data = iio_priv(indio_dev); 237 data->client = client; 238 mutex_init(&data->lock); 239 240 i2c_set_clientdata(client, indio_dev); 241 indio_dev->info = &t5403_info; 242 indio_dev->name = id->name; 243 indio_dev->dev.parent = &client->dev; 244 indio_dev->modes = INDIO_DIRECT_MODE; 245 indio_dev->channels = t5403_channels; 246 indio_dev->num_channels = ARRAY_SIZE(t5403_channels); 247 248 data->mode = T5403_MODE_STANDARD; 249 250 ret = i2c_smbus_read_i2c_block_data(data->client, T5403_CALIB_DATA, 251 sizeof(data->c), (u8 *) data->c); 252 if (ret < 0) 253 return ret; 254 255 return devm_iio_device_register(&client->dev, indio_dev); 256 } 257 258 static const struct i2c_device_id t5403_id[] = { 259 { "t5403", 0 }, 260 { } 261 }; 262 MODULE_DEVICE_TABLE(i2c, t5403_id); 263 264 static struct i2c_driver t5403_driver = { 265 .driver = { 266 .name = "t5403", 267 }, 268 .probe = t5403_probe, 269 .id_table = t5403_id, 270 }; 271 module_i2c_driver(t5403_driver); 272 273 MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>"); 274 MODULE_DESCRIPTION("EPCOS T5403 pressure/temperature sensor driver"); 275 MODULE_LICENSE("GPL"); 276