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

iio: dps310: Temperature measurement errata

Add a manufacturer's suggested workaround to deal with early revisions
of chip that don't indicate correct temperature. Readings can be in the
~60C range when they should be in the ~20's.

Signed-off-by: Christopher Bostic <cbostic@linux.vnet.ibm.com>
Signed-off-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Eddie James <eajames@linux.ibm.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Christopher Bostic and committed by
Jonathan Cameron
cc8baffe ba6ec48e

+50 -2
+50 -2
drivers/iio/pressure/dps310.c
··· 53 53 #define DPS310_RESET 0x0c 54 54 #define DPS310_RESET_MAGIC 0x09 55 55 #define DPS310_COEF_BASE 0x10 56 - #define DPS310_COEF_SRC 0x28 57 56 58 57 /* Make sure sleep time is <= 20ms for usleep_range */ 59 58 #define DPS310_POLL_SLEEP_US(t) min(20000, (t) / 8) ··· 233 234 case DPS310_MEAS_CFG: 234 235 case DPS310_CFG_REG: 235 236 case DPS310_RESET: 237 + /* No documentation available on the registers below */ 238 + case 0x0e: 239 + case 0x0f: 240 + case 0x62: 236 241 return true; 237 242 default: 238 243 return false; ··· 253 250 case DPS310_TMP_B1: 254 251 case DPS310_TMP_B2: 255 252 case DPS310_MEAS_CFG: 253 + case 0x32: /* No documentation available on this register */ 256 254 return true; 257 255 default: 258 256 return false; ··· 364 360 .writeable_reg = dps310_is_writeable_reg, 365 361 .volatile_reg = dps310_is_volatile_reg, 366 362 .cache_type = REGCACHE_RBTREE, 367 - .max_register = DPS310_COEF_SRC, 363 + .max_register = 0x62, /* No documentation available on this register */ 368 364 }; 369 365 370 366 static const struct iio_info dps310_info = { 371 367 .read_raw = dps310_read_raw, 372 368 .write_raw = dps310_write_raw, 373 369 }; 370 + 371 + /* 372 + * Some verions of chip will read temperatures in the ~60C range when 373 + * its actually ~20C. This is the manufacturer recommended workaround 374 + * to correct the issue. The registers used below are undocumented. 375 + */ 376 + static int dps310_temp_workaround(struct dps310_data *data) 377 + { 378 + int rc; 379 + int reg; 380 + 381 + rc = regmap_read(data->regmap, 0x32, &reg); 382 + if (rc < 0) 383 + return rc; 384 + 385 + /* 386 + * If bit 1 is set then the device is okay, and the workaround does not 387 + * need to be applied 388 + */ 389 + if (reg & BIT(1)) 390 + return 0; 391 + 392 + rc = regmap_write(data->regmap, 0x0e, 0xA5); 393 + if (rc < 0) 394 + return rc; 395 + 396 + rc = regmap_write(data->regmap, 0x0f, 0x96); 397 + if (rc < 0) 398 + return rc; 399 + 400 + rc = regmap_write(data->regmap, 0x62, 0x02); 401 + if (rc < 0) 402 + return rc; 403 + 404 + rc = regmap_write(data->regmap, 0x0e, 0x00); 405 + if (rc < 0) 406 + return rc; 407 + 408 + return regmap_write(data->regmap, 0x0f, 0x00); 409 + } 374 410 375 411 static int dps310_probe(struct i2c_client *client, 376 412 const struct i2c_device_id *id) ··· 480 436 return rc; 481 437 482 438 rc = dps310_get_temp_coef(data); 439 + if (rc < 0) 440 + return rc; 441 + 442 + rc = dps310_temp_workaround(data); 483 443 if (rc < 0) 484 444 return rc; 485 445