root/drivers/iio/common/st_sensors/st_sensors_core.c

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

DEFINITIONS

This source file includes following definitions.
  1. st_sensors_get_unaligned_le24
  2. st_sensors_write_data_with_mask
  3. st_sensors_debugfs_reg_access
  4. st_sensors_match_odr
  5. st_sensors_set_odr
  6. st_sensors_match_fs
  7. st_sensors_set_fullscale
  8. st_sensors_set_enable
  9. st_sensors_set_axis_enable
  10. st_sensors_power_enable
  11. st_sensors_power_disable
  12. st_sensors_set_drdy_int_pin
  13. st_sensors_of_probe
  14. st_sensors_of_name_probe
  15. st_sensors_of_probe
  16. st_sensors_init_sensor
  17. st_sensors_set_dataready_irq
  18. st_sensors_set_fullscale_by_gain
  19. st_sensors_read_axis_data
  20. st_sensors_read_info_raw
  21. st_sensors_get_settings_index
  22. st_sensors_verify_id
  23. st_sensors_sysfs_sampling_frequency_avail
  24. st_sensors_sysfs_scale_avail

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * STMicroelectronics sensors core library driver
   4  *
   5  * Copyright 2012-2013 STMicroelectronics Inc.
   6  *
   7  * Denis Ciocca <denis.ciocca@st.com>
   8  */
   9 
  10 #include <linux/kernel.h>
  11 #include <linux/module.h>
  12 #include <linux/slab.h>
  13 #include <linux/delay.h>
  14 #include <linux/iio/iio.h>
  15 #include <linux/regulator/consumer.h>
  16 #include <linux/of.h>
  17 #include <linux/of_device.h>
  18 #include <linux/regmap.h>
  19 #include <asm/unaligned.h>
  20 #include <linux/iio/common/st_sensors.h>
  21 
  22 #include "st_sensors_core.h"
  23 
  24 static inline u32 st_sensors_get_unaligned_le24(const u8 *p)
  25 {
  26         return (s32)((p[0] | p[1] << 8 | p[2] << 16) << 8) >> 8;
  27 }
  28 
  29 int st_sensors_write_data_with_mask(struct iio_dev *indio_dev,
  30                                     u8 reg_addr, u8 mask, u8 data)
  31 {
  32         struct st_sensor_data *sdata = iio_priv(indio_dev);
  33 
  34         return regmap_update_bits(sdata->regmap,
  35                                   reg_addr, mask, data << __ffs(mask));
  36 }
  37 
  38 int st_sensors_debugfs_reg_access(struct iio_dev *indio_dev,
  39                                   unsigned reg, unsigned writeval,
  40                                   unsigned *readval)
  41 {
  42         struct st_sensor_data *sdata = iio_priv(indio_dev);
  43         int err;
  44 
  45         if (!readval)
  46                 return regmap_write(sdata->regmap, reg, writeval);
  47 
  48         err = regmap_read(sdata->regmap, reg, readval);
  49         if (err < 0)
  50                 return err;
  51 
  52         return 0;
  53 }
  54 EXPORT_SYMBOL(st_sensors_debugfs_reg_access);
  55 
  56 static int st_sensors_match_odr(struct st_sensor_settings *sensor_settings,
  57                         unsigned int odr, struct st_sensor_odr_avl *odr_out)
  58 {
  59         int i, ret = -EINVAL;
  60 
  61         for (i = 0; i < ST_SENSORS_ODR_LIST_MAX; i++) {
  62                 if (sensor_settings->odr.odr_avl[i].hz == 0)
  63                         goto st_sensors_match_odr_error;
  64 
  65                 if (sensor_settings->odr.odr_avl[i].hz == odr) {
  66                         odr_out->hz = sensor_settings->odr.odr_avl[i].hz;
  67                         odr_out->value = sensor_settings->odr.odr_avl[i].value;
  68                         ret = 0;
  69                         break;
  70                 }
  71         }
  72 
  73 st_sensors_match_odr_error:
  74         return ret;
  75 }
  76 
  77 int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr)
  78 {
  79         int err;
  80         struct st_sensor_odr_avl odr_out = {0, 0};
  81         struct st_sensor_data *sdata = iio_priv(indio_dev);
  82 
  83         if (!sdata->sensor_settings->odr.mask)
  84                 return 0;
  85 
  86         err = st_sensors_match_odr(sdata->sensor_settings, odr, &odr_out);
  87         if (err < 0)
  88                 goto st_sensors_match_odr_error;
  89 
  90         if ((sdata->sensor_settings->odr.addr ==
  91                                         sdata->sensor_settings->pw.addr) &&
  92                                 (sdata->sensor_settings->odr.mask ==
  93                                         sdata->sensor_settings->pw.mask)) {
  94                 if (sdata->enabled == true) {
  95                         err = st_sensors_write_data_with_mask(indio_dev,
  96                                 sdata->sensor_settings->odr.addr,
  97                                 sdata->sensor_settings->odr.mask,
  98                                 odr_out.value);
  99                 } else {
 100                         err = 0;
 101                 }
 102         } else {
 103                 err = st_sensors_write_data_with_mask(indio_dev,
 104                         sdata->sensor_settings->odr.addr,
 105                         sdata->sensor_settings->odr.mask,
 106                         odr_out.value);
 107         }
 108         if (err >= 0)
 109                 sdata->odr = odr_out.hz;
 110 
 111 st_sensors_match_odr_error:
 112         return err;
 113 }
 114 EXPORT_SYMBOL(st_sensors_set_odr);
 115 
 116 static int st_sensors_match_fs(struct st_sensor_settings *sensor_settings,
 117                                         unsigned int fs, int *index_fs_avl)
 118 {
 119         int i, ret = -EINVAL;
 120 
 121         for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) {
 122                 if (sensor_settings->fs.fs_avl[i].num == 0)
 123                         return ret;
 124 
 125                 if (sensor_settings->fs.fs_avl[i].num == fs) {
 126                         *index_fs_avl = i;
 127                         ret = 0;
 128                         break;
 129                 }
 130         }
 131 
 132         return ret;
 133 }
 134 
 135 static int st_sensors_set_fullscale(struct iio_dev *indio_dev, unsigned int fs)
 136 {
 137         int err, i = 0;
 138         struct st_sensor_data *sdata = iio_priv(indio_dev);
 139 
 140         if (sdata->sensor_settings->fs.addr == 0)
 141                 return 0;
 142 
 143         err = st_sensors_match_fs(sdata->sensor_settings, fs, &i);
 144         if (err < 0)
 145                 goto st_accel_set_fullscale_error;
 146 
 147         err = st_sensors_write_data_with_mask(indio_dev,
 148                                 sdata->sensor_settings->fs.addr,
 149                                 sdata->sensor_settings->fs.mask,
 150                                 sdata->sensor_settings->fs.fs_avl[i].value);
 151         if (err < 0)
 152                 goto st_accel_set_fullscale_error;
 153 
 154         sdata->current_fullscale = (struct st_sensor_fullscale_avl *)
 155                                         &sdata->sensor_settings->fs.fs_avl[i];
 156         return err;
 157 
 158 st_accel_set_fullscale_error:
 159         dev_err(&indio_dev->dev, "failed to set new fullscale.\n");
 160         return err;
 161 }
 162 
 163 int st_sensors_set_enable(struct iio_dev *indio_dev, bool enable)
 164 {
 165         u8 tmp_value;
 166         int err = -EINVAL;
 167         bool found = false;
 168         struct st_sensor_odr_avl odr_out = {0, 0};
 169         struct st_sensor_data *sdata = iio_priv(indio_dev);
 170 
 171         if (enable) {
 172                 tmp_value = sdata->sensor_settings->pw.value_on;
 173                 if ((sdata->sensor_settings->odr.addr ==
 174                                         sdata->sensor_settings->pw.addr) &&
 175                                 (sdata->sensor_settings->odr.mask ==
 176                                         sdata->sensor_settings->pw.mask)) {
 177                         err = st_sensors_match_odr(sdata->sensor_settings,
 178                                                         sdata->odr, &odr_out);
 179                         if (err < 0)
 180                                 goto set_enable_error;
 181                         tmp_value = odr_out.value;
 182                         found = true;
 183                 }
 184                 err = st_sensors_write_data_with_mask(indio_dev,
 185                                 sdata->sensor_settings->pw.addr,
 186                                 sdata->sensor_settings->pw.mask, tmp_value);
 187                 if (err < 0)
 188                         goto set_enable_error;
 189 
 190                 sdata->enabled = true;
 191 
 192                 if (found)
 193                         sdata->odr = odr_out.hz;
 194         } else {
 195                 err = st_sensors_write_data_with_mask(indio_dev,
 196                                 sdata->sensor_settings->pw.addr,
 197                                 sdata->sensor_settings->pw.mask,
 198                                 sdata->sensor_settings->pw.value_off);
 199                 if (err < 0)
 200                         goto set_enable_error;
 201 
 202                 sdata->enabled = false;
 203         }
 204 
 205 set_enable_error:
 206         return err;
 207 }
 208 EXPORT_SYMBOL(st_sensors_set_enable);
 209 
 210 int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable)
 211 {
 212         struct st_sensor_data *sdata = iio_priv(indio_dev);
 213         int err = 0;
 214 
 215         if (sdata->sensor_settings->enable_axis.addr)
 216                 err = st_sensors_write_data_with_mask(indio_dev,
 217                                 sdata->sensor_settings->enable_axis.addr,
 218                                 sdata->sensor_settings->enable_axis.mask,
 219                                 axis_enable);
 220         return err;
 221 }
 222 EXPORT_SYMBOL(st_sensors_set_axis_enable);
 223 
 224 int st_sensors_power_enable(struct iio_dev *indio_dev)
 225 {
 226         struct st_sensor_data *pdata = iio_priv(indio_dev);
 227         int err;
 228 
 229         /* Regulators not mandatory, but if requested we should enable them. */
 230         pdata->vdd = devm_regulator_get(indio_dev->dev.parent, "vdd");
 231         if (IS_ERR(pdata->vdd)) {
 232                 dev_err(&indio_dev->dev, "unable to get Vdd supply\n");
 233                 return PTR_ERR(pdata->vdd);
 234         }
 235         err = regulator_enable(pdata->vdd);
 236         if (err != 0) {
 237                 dev_warn(&indio_dev->dev,
 238                          "Failed to enable specified Vdd supply\n");
 239                 return err;
 240         }
 241 
 242         pdata->vdd_io = devm_regulator_get(indio_dev->dev.parent, "vddio");
 243         if (IS_ERR(pdata->vdd_io)) {
 244                 dev_err(&indio_dev->dev, "unable to get Vdd_IO supply\n");
 245                 err = PTR_ERR(pdata->vdd_io);
 246                 goto st_sensors_disable_vdd;
 247         }
 248         err = regulator_enable(pdata->vdd_io);
 249         if (err != 0) {
 250                 dev_warn(&indio_dev->dev,
 251                          "Failed to enable specified Vdd_IO supply\n");
 252                 goto st_sensors_disable_vdd;
 253         }
 254 
 255         return 0;
 256 
 257 st_sensors_disable_vdd:
 258         regulator_disable(pdata->vdd);
 259         return err;
 260 }
 261 EXPORT_SYMBOL(st_sensors_power_enable);
 262 
 263 void st_sensors_power_disable(struct iio_dev *indio_dev)
 264 {
 265         struct st_sensor_data *pdata = iio_priv(indio_dev);
 266 
 267         regulator_disable(pdata->vdd);
 268         regulator_disable(pdata->vdd_io);
 269 }
 270 EXPORT_SYMBOL(st_sensors_power_disable);
 271 
 272 static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev,
 273                                         struct st_sensors_platform_data *pdata)
 274 {
 275         struct st_sensor_data *sdata = iio_priv(indio_dev);
 276 
 277         /* Sensor does not support interrupts */
 278         if (!sdata->sensor_settings->drdy_irq.int1.addr &&
 279             !sdata->sensor_settings->drdy_irq.int2.addr) {
 280                 if (pdata->drdy_int_pin)
 281                         dev_info(&indio_dev->dev,
 282                                  "DRDY on pin INT%d specified, but sensor "
 283                                  "does not support interrupts\n",
 284                                  pdata->drdy_int_pin);
 285                 return 0;
 286         }
 287 
 288         switch (pdata->drdy_int_pin) {
 289         case 1:
 290                 if (!sdata->sensor_settings->drdy_irq.int1.mask) {
 291                         dev_err(&indio_dev->dev,
 292                                         "DRDY on INT1 not available.\n");
 293                         return -EINVAL;
 294                 }
 295                 sdata->drdy_int_pin = 1;
 296                 break;
 297         case 2:
 298                 if (!sdata->sensor_settings->drdy_irq.int2.mask) {
 299                         dev_err(&indio_dev->dev,
 300                                         "DRDY on INT2 not available.\n");
 301                         return -EINVAL;
 302                 }
 303                 sdata->drdy_int_pin = 2;
 304                 break;
 305         default:
 306                 dev_err(&indio_dev->dev, "DRDY on pdata not valid.\n");
 307                 return -EINVAL;
 308         }
 309 
 310         if (pdata->open_drain) {
 311                 if (!sdata->sensor_settings->drdy_irq.int1.addr_od &&
 312                     !sdata->sensor_settings->drdy_irq.int2.addr_od)
 313                         dev_err(&indio_dev->dev,
 314                                 "open drain requested but unsupported.\n");
 315                 else
 316                         sdata->int_pin_open_drain = true;
 317         }
 318 
 319         return 0;
 320 }
 321 
 322 #ifdef CONFIG_OF
 323 static struct st_sensors_platform_data *st_sensors_of_probe(struct device *dev,
 324                 struct st_sensors_platform_data *defdata)
 325 {
 326         struct st_sensors_platform_data *pdata;
 327         struct device_node *np = dev->of_node;
 328         u32 val;
 329 
 330         if (!np)
 331                 return NULL;
 332 
 333         pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
 334         if (!of_property_read_u32(np, "st,drdy-int-pin", &val) && (val <= 2))
 335                 pdata->drdy_int_pin = (u8) val;
 336         else
 337                 pdata->drdy_int_pin = defdata ? defdata->drdy_int_pin : 0;
 338 
 339         pdata->open_drain = of_property_read_bool(np, "drive-open-drain");
 340 
 341         return pdata;
 342 }
 343 
 344 /**
 345  * st_sensors_of_name_probe() - device tree probe for ST sensor name
 346  * @dev: driver model representation of the device.
 347  * @match: the OF match table for the device, containing compatible strings
 348  *      but also a .data field with the corresponding internal kernel name
 349  *      used by this sensor.
 350  * @name: device name buffer reference.
 351  * @len: device name buffer length.
 352  *
 353  * In effect this function matches a compatible string to an internal kernel
 354  * name for a certain sensor device, so that the rest of the autodetection can
 355  * rely on that name from this point on. I2C/SPI devices will be renamed
 356  * to match the internal kernel convention.
 357  */
 358 void st_sensors_of_name_probe(struct device *dev,
 359                               const struct of_device_id *match,
 360                               char *name, int len)
 361 {
 362         const struct of_device_id *of_id;
 363 
 364         of_id = of_match_device(match, dev);
 365         if (!of_id || !of_id->data)
 366                 return;
 367 
 368         /* The name from the OF match takes precedence if present */
 369         strlcpy(name, of_id->data, len);
 370 }
 371 EXPORT_SYMBOL(st_sensors_of_name_probe);
 372 #else
 373 static struct st_sensors_platform_data *st_sensors_of_probe(struct device *dev,
 374                 struct st_sensors_platform_data *defdata)
 375 {
 376         return NULL;
 377 }
 378 #endif
 379 
 380 int st_sensors_init_sensor(struct iio_dev *indio_dev,
 381                                         struct st_sensors_platform_data *pdata)
 382 {
 383         struct st_sensor_data *sdata = iio_priv(indio_dev);
 384         struct st_sensors_platform_data *of_pdata;
 385         int err = 0;
 386 
 387         /* If OF/DT pdata exists, it will take precedence of anything else */
 388         of_pdata = st_sensors_of_probe(indio_dev->dev.parent, pdata);
 389         if (of_pdata)
 390                 pdata = of_pdata;
 391 
 392         if (pdata) {
 393                 err = st_sensors_set_drdy_int_pin(indio_dev, pdata);
 394                 if (err < 0)
 395                         return err;
 396         }
 397 
 398         err = st_sensors_set_enable(indio_dev, false);
 399         if (err < 0)
 400                 return err;
 401 
 402         /* Disable DRDY, this might be still be enabled after reboot. */
 403         err = st_sensors_set_dataready_irq(indio_dev, false);
 404         if (err < 0)
 405                 return err;
 406 
 407         if (sdata->current_fullscale) {
 408                 err = st_sensors_set_fullscale(indio_dev,
 409                                                 sdata->current_fullscale->num);
 410                 if (err < 0)
 411                         return err;
 412         } else
 413                 dev_info(&indio_dev->dev, "Full-scale not possible\n");
 414 
 415         err = st_sensors_set_odr(indio_dev, sdata->odr);
 416         if (err < 0)
 417                 return err;
 418 
 419         /* set BDU */
 420         if (sdata->sensor_settings->bdu.addr) {
 421                 err = st_sensors_write_data_with_mask(indio_dev,
 422                                         sdata->sensor_settings->bdu.addr,
 423                                         sdata->sensor_settings->bdu.mask, true);
 424                 if (err < 0)
 425                         return err;
 426         }
 427 
 428         /* set DAS */
 429         if (sdata->sensor_settings->das.addr) {
 430                 err = st_sensors_write_data_with_mask(indio_dev,
 431                                         sdata->sensor_settings->das.addr,
 432                                         sdata->sensor_settings->das.mask, 1);
 433                 if (err < 0)
 434                         return err;
 435         }
 436 
 437         if (sdata->int_pin_open_drain) {
 438                 u8 addr, mask;
 439 
 440                 if (sdata->drdy_int_pin == 1) {
 441                         addr = sdata->sensor_settings->drdy_irq.int1.addr_od;
 442                         mask = sdata->sensor_settings->drdy_irq.int1.mask_od;
 443                 } else {
 444                         addr = sdata->sensor_settings->drdy_irq.int2.addr_od;
 445                         mask = sdata->sensor_settings->drdy_irq.int2.mask_od;
 446                 }
 447 
 448                 dev_info(&indio_dev->dev,
 449                          "set interrupt line to open drain mode on pin %d\n",
 450                          sdata->drdy_int_pin);
 451                 err = st_sensors_write_data_with_mask(indio_dev, addr,
 452                                                       mask, 1);
 453                 if (err < 0)
 454                         return err;
 455         }
 456 
 457         err = st_sensors_set_axis_enable(indio_dev, ST_SENSORS_ENABLE_ALL_AXIS);
 458 
 459         return err;
 460 }
 461 EXPORT_SYMBOL(st_sensors_init_sensor);
 462 
 463 int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable)
 464 {
 465         int err;
 466         u8 drdy_addr, drdy_mask;
 467         struct st_sensor_data *sdata = iio_priv(indio_dev);
 468 
 469         if (!sdata->sensor_settings->drdy_irq.int1.addr &&
 470             !sdata->sensor_settings->drdy_irq.int2.addr) {
 471                 /*
 472                  * there are some devices (e.g. LIS3MDL) where drdy line is
 473                  * routed to a given pin and it is not possible to select a
 474                  * different one. Take into account irq status register
 475                  * to understand if irq trigger can be properly supported
 476                  */
 477                 if (sdata->sensor_settings->drdy_irq.stat_drdy.addr)
 478                         sdata->hw_irq_trigger = enable;
 479                 return 0;
 480         }
 481 
 482         /* Enable/Disable the interrupt generator 1. */
 483         if (sdata->sensor_settings->drdy_irq.ig1.en_addr > 0) {
 484                 err = st_sensors_write_data_with_mask(indio_dev,
 485                                 sdata->sensor_settings->drdy_irq.ig1.en_addr,
 486                                 sdata->sensor_settings->drdy_irq.ig1.en_mask,
 487                                 (int)enable);
 488                 if (err < 0)
 489                         goto st_accel_set_dataready_irq_error;
 490         }
 491 
 492         if (sdata->drdy_int_pin == 1) {
 493                 drdy_addr = sdata->sensor_settings->drdy_irq.int1.addr;
 494                 drdy_mask = sdata->sensor_settings->drdy_irq.int1.mask;
 495         } else {
 496                 drdy_addr = sdata->sensor_settings->drdy_irq.int2.addr;
 497                 drdy_mask = sdata->sensor_settings->drdy_irq.int2.mask;
 498         }
 499 
 500         /* Flag to the poll function that the hardware trigger is in use */
 501         sdata->hw_irq_trigger = enable;
 502 
 503         /* Enable/Disable the interrupt generator for data ready. */
 504         err = st_sensors_write_data_with_mask(indio_dev, drdy_addr,
 505                                               drdy_mask, (int)enable);
 506 
 507 st_accel_set_dataready_irq_error:
 508         return err;
 509 }
 510 EXPORT_SYMBOL(st_sensors_set_dataready_irq);
 511 
 512 int st_sensors_set_fullscale_by_gain(struct iio_dev *indio_dev, int scale)
 513 {
 514         int err = -EINVAL, i;
 515         struct st_sensor_data *sdata = iio_priv(indio_dev);
 516 
 517         for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) {
 518                 if ((sdata->sensor_settings->fs.fs_avl[i].gain == scale) &&
 519                                 (sdata->sensor_settings->fs.fs_avl[i].gain != 0)) {
 520                         err = 0;
 521                         break;
 522                 }
 523         }
 524         if (err < 0)
 525                 goto st_sensors_match_scale_error;
 526 
 527         err = st_sensors_set_fullscale(indio_dev,
 528                                 sdata->sensor_settings->fs.fs_avl[i].num);
 529 
 530 st_sensors_match_scale_error:
 531         return err;
 532 }
 533 EXPORT_SYMBOL(st_sensors_set_fullscale_by_gain);
 534 
 535 static int st_sensors_read_axis_data(struct iio_dev *indio_dev,
 536                                      struct iio_chan_spec const *ch, int *data)
 537 {
 538         int err;
 539         u8 *outdata;
 540         struct st_sensor_data *sdata = iio_priv(indio_dev);
 541         unsigned int byte_for_channel;
 542 
 543         byte_for_channel = DIV_ROUND_UP(ch->scan_type.realbits +
 544                                         ch->scan_type.shift, 8);
 545         outdata = kmalloc(byte_for_channel, GFP_DMA | GFP_KERNEL);
 546         if (!outdata)
 547                 return -ENOMEM;
 548 
 549         err = regmap_bulk_read(sdata->regmap, ch->address,
 550                                outdata, byte_for_channel);
 551         if (err < 0)
 552                 goto st_sensors_free_memory;
 553 
 554         if (byte_for_channel == 1)
 555                 *data = (s8)*outdata;
 556         else if (byte_for_channel == 2)
 557                 *data = (s16)get_unaligned_le16(outdata);
 558         else if (byte_for_channel == 3)
 559                 *data = (s32)st_sensors_get_unaligned_le24(outdata);
 560 
 561 st_sensors_free_memory:
 562         kfree(outdata);
 563 
 564         return err;
 565 }
 566 
 567 int st_sensors_read_info_raw(struct iio_dev *indio_dev,
 568                                 struct iio_chan_spec const *ch, int *val)
 569 {
 570         int err;
 571         struct st_sensor_data *sdata = iio_priv(indio_dev);
 572 
 573         mutex_lock(&indio_dev->mlock);
 574         if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
 575                 err = -EBUSY;
 576                 goto out;
 577         } else {
 578                 err = st_sensors_set_enable(indio_dev, true);
 579                 if (err < 0)
 580                         goto out;
 581 
 582                 msleep((sdata->sensor_settings->bootime * 1000) / sdata->odr);
 583                 err = st_sensors_read_axis_data(indio_dev, ch, val);
 584                 if (err < 0)
 585                         goto out;
 586 
 587                 *val = *val >> ch->scan_type.shift;
 588 
 589                 err = st_sensors_set_enable(indio_dev, false);
 590         }
 591 out:
 592         mutex_unlock(&indio_dev->mlock);
 593 
 594         return err;
 595 }
 596 EXPORT_SYMBOL(st_sensors_read_info_raw);
 597 
 598 /*
 599  * st_sensors_get_settings_index() - get index of the sensor settings for a
 600  *                                   specific device from list of settings
 601  * @name: device name buffer reference.
 602  * @list: sensor settings list.
 603  * @list_length: length of sensor settings list.
 604  *
 605  * Return: non negative number on success (valid index),
 606  *         negative error code otherwise.
 607  */
 608 int st_sensors_get_settings_index(const char *name,
 609                                   const struct st_sensor_settings *list,
 610                                   const int list_length)
 611 {
 612         int i, n;
 613 
 614         for (i = 0; i < list_length; i++) {
 615                 for (n = 0; n < ST_SENSORS_MAX_4WAI; n++) {
 616                         if (strcmp(name, list[i].sensors_supported[n]) == 0)
 617                                 return i;
 618                 }
 619         }
 620 
 621         return -ENODEV;
 622 }
 623 EXPORT_SYMBOL(st_sensors_get_settings_index);
 624 
 625 /*
 626  * st_sensors_verify_id() - verify sensor ID (WhoAmI) is matching with the
 627  *                          expected value
 628  * @indio_dev: IIO device reference.
 629  *
 630  * Return: 0 on success (valid sensor ID), else a negative error code.
 631  */
 632 int st_sensors_verify_id(struct iio_dev *indio_dev)
 633 {
 634         struct st_sensor_data *sdata = iio_priv(indio_dev);
 635         int wai, err;
 636 
 637         if (sdata->sensor_settings->wai_addr) {
 638                 err = regmap_read(sdata->regmap,
 639                                   sdata->sensor_settings->wai_addr, &wai);
 640                 if (err < 0) {
 641                         dev_err(&indio_dev->dev,
 642                                 "failed to read Who-Am-I register.\n");
 643                         return err;
 644                 }
 645 
 646                 if (sdata->sensor_settings->wai != wai) {
 647                         dev_err(&indio_dev->dev,
 648                                 "%s: WhoAmI mismatch (0x%x).\n",
 649                                 indio_dev->name, wai);
 650                         return -EINVAL;
 651                 }
 652         }
 653 
 654         return 0;
 655 }
 656 EXPORT_SYMBOL(st_sensors_verify_id);
 657 
 658 ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev,
 659                                 struct device_attribute *attr, char *buf)
 660 {
 661         int i, len = 0;
 662         struct iio_dev *indio_dev = dev_get_drvdata(dev);
 663         struct st_sensor_data *sdata = iio_priv(indio_dev);
 664 
 665         mutex_lock(&indio_dev->mlock);
 666         for (i = 0; i < ST_SENSORS_ODR_LIST_MAX; i++) {
 667                 if (sdata->sensor_settings->odr.odr_avl[i].hz == 0)
 668                         break;
 669 
 670                 len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
 671                                 sdata->sensor_settings->odr.odr_avl[i].hz);
 672         }
 673         mutex_unlock(&indio_dev->mlock);
 674         buf[len - 1] = '\n';
 675 
 676         return len;
 677 }
 678 EXPORT_SYMBOL(st_sensors_sysfs_sampling_frequency_avail);
 679 
 680 ssize_t st_sensors_sysfs_scale_avail(struct device *dev,
 681                                 struct device_attribute *attr, char *buf)
 682 {
 683         int i, len = 0, q, r;
 684         struct iio_dev *indio_dev = dev_get_drvdata(dev);
 685         struct st_sensor_data *sdata = iio_priv(indio_dev);
 686 
 687         mutex_lock(&indio_dev->mlock);
 688         for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) {
 689                 if (sdata->sensor_settings->fs.fs_avl[i].num == 0)
 690                         break;
 691 
 692                 q = sdata->sensor_settings->fs.fs_avl[i].gain / 1000000;
 693                 r = sdata->sensor_settings->fs.fs_avl[i].gain % 1000000;
 694 
 695                 len += scnprintf(buf + len, PAGE_SIZE - len, "%u.%06u ", q, r);
 696         }
 697         mutex_unlock(&indio_dev->mlock);
 698         buf[len - 1] = '\n';
 699 
 700         return len;
 701 }
 702 EXPORT_SYMBOL(st_sensors_sysfs_scale_avail);
 703 
 704 MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
 705 MODULE_DESCRIPTION("STMicroelectronics ST-sensors core");
 706 MODULE_LICENSE("GPL v2");

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