root/drivers/iio/pressure/ms5637.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ms5637_read_raw
  2. ms5637_write_raw
  3. ms5637_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * ms5637.c - Support for Measurement-Specialties MS5637, MS5805
   4  *            MS5837 and MS8607 pressure & temperature sensor
   5  *
   6  * Copyright (c) 2015 Measurement-Specialties
   7  *
   8  * (7-bit I2C slave address 0x76)
   9  *
  10  * Datasheet:
  11  *  http://www.meas-spec.com/downloads/MS5637-02BA03.pdf
  12  * Datasheet:
  13  *  http://www.meas-spec.com/downloads/MS5805-02BA01.pdf
  14  * Datasheet:
  15  *  http://www.meas-spec.com/downloads/MS5837-30BA.pdf
  16  * Datasheet:
  17  *  http://www.meas-spec.com/downloads/MS8607-02BA01.pdf
  18  */
  19 
  20 #include <linux/init.h>
  21 #include <linux/device.h>
  22 #include <linux/kernel.h>
  23 #include <linux/stat.h>
  24 #include <linux/module.h>
  25 #include <linux/i2c.h>
  26 #include <linux/iio/iio.h>
  27 #include <linux/iio/sysfs.h>
  28 #include <linux/mutex.h>
  29 
  30 #include "../common/ms_sensors/ms_sensors_i2c.h"
  31 
  32 static const int ms5637_samp_freq[6] = { 960, 480, 240, 120, 60, 30 };
  33 /* String copy of the above const for readability purpose */
  34 static const char ms5637_show_samp_freq[] = "960 480 240 120 60 30";
  35 
  36 static int ms5637_read_raw(struct iio_dev *indio_dev,
  37                            struct iio_chan_spec const *channel, int *val,
  38                            int *val2, long mask)
  39 {
  40         int ret;
  41         int temperature;
  42         unsigned int pressure;
  43         struct ms_tp_dev *dev_data = iio_priv(indio_dev);
  44 
  45         switch (mask) {
  46         case IIO_CHAN_INFO_PROCESSED:
  47                 ret = ms_sensors_read_temp_and_pressure(dev_data,
  48                                                         &temperature,
  49                                                         &pressure);
  50                 if (ret)
  51                         return ret;
  52 
  53                 switch (channel->type) {
  54                 case IIO_TEMP:  /* in milli °C */
  55                         *val = temperature;
  56 
  57                         return IIO_VAL_INT;
  58                 case IIO_PRESSURE:      /* in kPa */
  59                         *val = pressure / 1000;
  60                         *val2 = (pressure % 1000) * 1000;
  61 
  62                         return IIO_VAL_INT_PLUS_MICRO;
  63                 default:
  64                         return -EINVAL;
  65                 }
  66         case IIO_CHAN_INFO_SAMP_FREQ:
  67                 *val = ms5637_samp_freq[dev_data->res_index];
  68 
  69                 return IIO_VAL_INT;
  70         default:
  71                 return -EINVAL;
  72         }
  73 }
  74 
  75 static int ms5637_write_raw(struct iio_dev *indio_dev,
  76                             struct iio_chan_spec const *chan,
  77                             int val, int val2, long mask)
  78 {
  79         struct ms_tp_dev *dev_data = iio_priv(indio_dev);
  80         int i;
  81 
  82         switch (mask) {
  83         case IIO_CHAN_INFO_SAMP_FREQ:
  84                 i = ARRAY_SIZE(ms5637_samp_freq);
  85                 while (i-- > 0)
  86                         if (val == ms5637_samp_freq[i])
  87                                 break;
  88                 if (i < 0)
  89                         return -EINVAL;
  90                 dev_data->res_index = i;
  91 
  92                 return 0;
  93         default:
  94                 return -EINVAL;
  95         }
  96 }
  97 
  98 static const struct iio_chan_spec ms5637_channels[] = {
  99         {
 100                 .type = IIO_TEMP,
 101                 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
 102                 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 103         },
 104         {
 105                 .type = IIO_PRESSURE,
 106                 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
 107                 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 108         }
 109 };
 110 
 111 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(ms5637_show_samp_freq);
 112 
 113 static struct attribute *ms5637_attributes[] = {
 114         &iio_const_attr_sampling_frequency_available.dev_attr.attr,
 115         NULL,
 116 };
 117 
 118 static const struct attribute_group ms5637_attribute_group = {
 119         .attrs = ms5637_attributes,
 120 };
 121 
 122 static const struct iio_info ms5637_info = {
 123         .read_raw = ms5637_read_raw,
 124         .write_raw = ms5637_write_raw,
 125         .attrs = &ms5637_attribute_group,
 126 };
 127 
 128 static int ms5637_probe(struct i2c_client *client,
 129                         const struct i2c_device_id *id)
 130 {
 131         struct ms_tp_dev *dev_data;
 132         struct iio_dev *indio_dev;
 133         int ret;
 134 
 135         if (!i2c_check_functionality(client->adapter,
 136                                      I2C_FUNC_SMBUS_READ_WORD_DATA |
 137                                      I2C_FUNC_SMBUS_WRITE_BYTE |
 138                                      I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
 139                 dev_err(&client->dev,
 140                         "Adapter does not support some i2c transaction\n");
 141                 return -EOPNOTSUPP;
 142         }
 143 
 144         indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*dev_data));
 145         if (!indio_dev)
 146                 return -ENOMEM;
 147 
 148         dev_data = iio_priv(indio_dev);
 149         dev_data->client = client;
 150         dev_data->res_index = 5;
 151         mutex_init(&dev_data->lock);
 152 
 153         indio_dev->info = &ms5637_info;
 154         indio_dev->name = id->name;
 155         indio_dev->dev.parent = &client->dev;
 156         indio_dev->modes = INDIO_DIRECT_MODE;
 157         indio_dev->channels = ms5637_channels;
 158         indio_dev->num_channels = ARRAY_SIZE(ms5637_channels);
 159 
 160         i2c_set_clientdata(client, indio_dev);
 161 
 162         ret = ms_sensors_reset(client, 0x1E, 3000);
 163         if (ret)
 164                 return ret;
 165 
 166         ret = ms_sensors_tp_read_prom(dev_data);
 167         if (ret)
 168                 return ret;
 169 
 170         return devm_iio_device_register(&client->dev, indio_dev);
 171 }
 172 
 173 static const struct i2c_device_id ms5637_id[] = {
 174         {"ms5637", 0},
 175         {"ms5805", 0},
 176         {"ms5837", 0},
 177         {"ms8607-temppressure", 0},
 178         {}
 179 };
 180 MODULE_DEVICE_TABLE(i2c, ms5637_id);
 181 
 182 static const struct of_device_id ms5637_of_match[] = {
 183         { .compatible = "meas,ms5637", },
 184         { .compatible = "meas,ms5805", },
 185         { .compatible = "meas,ms5837", },
 186         { .compatible = "meas,ms8607-temppressure", },
 187         { },
 188 };
 189 MODULE_DEVICE_TABLE(of, ms5637_of_match);
 190 
 191 static struct i2c_driver ms5637_driver = {
 192         .probe = ms5637_probe,
 193         .id_table = ms5637_id,
 194         .driver = {
 195                    .name = "ms5637",
 196                    .of_match_table = of_match_ptr(ms5637_of_match),
 197                    },
 198 };
 199 
 200 module_i2c_driver(ms5637_driver);
 201 
 202 MODULE_DESCRIPTION("Measurement-Specialties ms5637 temperature & pressure driver");
 203 MODULE_AUTHOR("William Markezana <william.markezana@meas-spec.com>");
 204 MODULE_AUTHOR("Ludovic Tancerel <ludovic.tancerel@maplehightech.com>");
 205 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */