Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Add ms5637 meas-spec driver support

Support for MS5637 temperature & pressure sensor

Signed-off-by: Ludovic Tancerel <ludovic.tancerel@maplehightech.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>

authored by

Ludovic Tancerel and committed by
Jonathan Cameron
64a70c65 2b5c53d2

+198
+11
drivers/iio/pressure/Kconfig
··· 79 79 To compile this driver as a module, choose M here: the module will 80 80 be called ms5611_spi. 81 81 82 + config MS5637 83 + tristate "Measurement Specialties MS5637 pressure & temperature sensor" 84 + depends on I2C 85 + select IIO_MS_SENSORS_I2C 86 + help 87 + If you say yes here you get support for the Measurement Specialties 88 + MS5637 pressure and temperature sensor. 89 + 90 + This driver can also be built as a module. If so, the module will 91 + be called ms5637. 92 + 82 93 config IIO_ST_PRESS 83 94 tristate "STMicroelectronics pressure sensor Driver" 84 95 depends on (I2C || SPI_MASTER) && SYSFS
+1
drivers/iio/pressure/Makefile
··· 10 10 obj-$(CONFIG_MS5611) += ms5611_core.o 11 11 obj-$(CONFIG_MS5611_I2C) += ms5611_i2c.o 12 12 obj-$(CONFIG_MS5611_SPI) += ms5611_spi.o 13 + obj-$(CONFIG_MS5637) += ms5637.o 13 14 obj-$(CONFIG_IIO_ST_PRESS) += st_pressure.o 14 15 st_pressure-y := st_pressure_core.o 15 16 st_pressure-$(CONFIG_IIO_BUFFER) += st_pressure_buffer.o
+186
drivers/iio/pressure/ms5637.c
··· 1 + /* 2 + * ms5637.c - Support for Measurement-Specialties ms5637 3 + * pressure & temperature sensor 4 + * 5 + * Copyright (c) 2015 Measurement-Specialties 6 + * 7 + * Licensed under the GPL-2. 8 + * 9 + * (7-bit I2C slave address 0x76) 10 + * 11 + * Datasheet: 12 + * http://www.meas-spec.com/downloads/MS5637-02BA03.pdf 13 + */ 14 + #include <linux/init.h> 15 + #include <linux/device.h> 16 + #include <linux/kernel.h> 17 + #include <linux/stat.h> 18 + #include <linux/module.h> 19 + #include <linux/i2c.h> 20 + #include <linux/iio/iio.h> 21 + #include <linux/iio/sysfs.h> 22 + #include <linux/mutex.h> 23 + 24 + #include "../common/ms_sensors/ms_sensors_i2c.h" 25 + 26 + static const int ms5637_samp_freq[6] = { 960, 480, 240, 120, 60, 30 }; 27 + /* String copy of the above const for readability purpose */ 28 + static const char ms5637_show_samp_freq[] = "960 480 240 120 60 30"; 29 + 30 + static int ms5637_read_raw(struct iio_dev *indio_dev, 31 + struct iio_chan_spec const *channel, int *val, 32 + int *val2, long mask) 33 + { 34 + int ret; 35 + int temperature; 36 + unsigned int pressure; 37 + struct ms_tp_dev *dev_data = iio_priv(indio_dev); 38 + 39 + switch (mask) { 40 + case IIO_CHAN_INFO_PROCESSED: 41 + ret = ms_sensors_read_temp_and_pressure(dev_data, 42 + &temperature, 43 + &pressure); 44 + if (ret) 45 + return ret; 46 + 47 + switch (channel->type) { 48 + case IIO_TEMP: /* in milli °C */ 49 + *val = temperature; 50 + 51 + return IIO_VAL_INT; 52 + case IIO_PRESSURE: /* in kPa */ 53 + *val = pressure / 1000; 54 + *val2 = (pressure % 1000) * 1000; 55 + 56 + return IIO_VAL_INT_PLUS_MICRO; 57 + default: 58 + return -EINVAL; 59 + } 60 + case IIO_CHAN_INFO_SAMP_FREQ: 61 + *val = ms5637_samp_freq[dev_data->res_index]; 62 + 63 + return IIO_VAL_INT; 64 + default: 65 + return -EINVAL; 66 + } 67 + } 68 + 69 + static int ms5637_write_raw(struct iio_dev *indio_dev, 70 + struct iio_chan_spec const *chan, 71 + int val, int val2, long mask) 72 + { 73 + struct ms_tp_dev *dev_data = iio_priv(indio_dev); 74 + int i; 75 + 76 + switch (mask) { 77 + case IIO_CHAN_INFO_SAMP_FREQ: 78 + i = ARRAY_SIZE(ms5637_samp_freq); 79 + while (i-- > 0) 80 + if (val == ms5637_samp_freq[i]) 81 + break; 82 + if (i < 0) 83 + return -EINVAL; 84 + dev_data->res_index = i; 85 + 86 + return 0; 87 + default: 88 + return -EINVAL; 89 + } 90 + } 91 + 92 + static const struct iio_chan_spec ms5637_channels[] = { 93 + { 94 + .type = IIO_TEMP, 95 + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), 96 + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), 97 + }, 98 + { 99 + .type = IIO_PRESSURE, 100 + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), 101 + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), 102 + } 103 + }; 104 + 105 + static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(ms5637_show_samp_freq); 106 + 107 + static struct attribute *ms5637_attributes[] = { 108 + &iio_const_attr_sampling_frequency_available.dev_attr.attr, 109 + NULL, 110 + }; 111 + 112 + static const struct attribute_group ms5637_attribute_group = { 113 + .attrs = ms5637_attributes, 114 + }; 115 + 116 + static const struct iio_info ms5637_info = { 117 + .read_raw = ms5637_read_raw, 118 + .write_raw = ms5637_write_raw, 119 + .attrs = &ms5637_attribute_group, 120 + .driver_module = THIS_MODULE, 121 + }; 122 + 123 + static int ms5637_probe(struct i2c_client *client, 124 + const struct i2c_device_id *id) 125 + { 126 + struct ms_tp_dev *dev_data; 127 + struct iio_dev *indio_dev; 128 + int ret; 129 + 130 + if (!i2c_check_functionality(client->adapter, 131 + I2C_FUNC_SMBUS_READ_WORD_DATA | 132 + I2C_FUNC_SMBUS_WRITE_BYTE | 133 + I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { 134 + dev_err(&client->dev, 135 + "Adapter does not support some i2c transaction\n"); 136 + return -ENODEV; 137 + } 138 + 139 + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*dev_data)); 140 + if (!indio_dev) 141 + return -ENOMEM; 142 + 143 + dev_data = iio_priv(indio_dev); 144 + dev_data->client = client; 145 + dev_data->res_index = 5; 146 + mutex_init(&dev_data->lock); 147 + 148 + indio_dev->info = &ms5637_info; 149 + indio_dev->name = id->name; 150 + indio_dev->dev.parent = &client->dev; 151 + indio_dev->modes = INDIO_DIRECT_MODE; 152 + indio_dev->channels = ms5637_channels; 153 + indio_dev->num_channels = ARRAY_SIZE(ms5637_channels); 154 + 155 + i2c_set_clientdata(client, indio_dev); 156 + 157 + ret = ms_sensors_reset(client, 0x1E, 3000); 158 + if (ret) 159 + return ret; 160 + 161 + ret = ms_sensors_tp_read_prom(dev_data); 162 + if (ret) 163 + return ret; 164 + 165 + return devm_iio_device_register(&client->dev, indio_dev); 166 + } 167 + 168 + static const struct i2c_device_id ms5637_id[] = { 169 + {"ms5637", 0}, 170 + {} 171 + }; 172 + 173 + static struct i2c_driver ms5637_driver = { 174 + .probe = ms5637_probe, 175 + .id_table = ms5637_id, 176 + .driver = { 177 + .name = "ms5637" 178 + }, 179 + }; 180 + 181 + module_i2c_driver(ms5637_driver); 182 + 183 + MODULE_DESCRIPTION("Measurement-Specialties ms5637 temperature & pressure driver"); 184 + MODULE_AUTHOR("William Markezana <william.markezana@meas-spec.com>"); 185 + MODULE_AUTHOR("Ludovic Tancerel <ludovic.tancerel@maplehightech.com>"); 186 + MODULE_LICENSE("GPL v2");