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