First set of IIO fixes for the 5.0 cycle.

Been a busy month, so these are rather later than they should have been.
 
 * atlas-ph-sensor:
   - Temperature scale didn't correspond to the ABI.
 * axp288:
   - A few different fixes around the TS-pin handling.
 * ti-ads8688
   - Not enough space in the buffer used to build the scan to allow for
     the timestamp.
 * tools - iio_generic_buffer
   - Make num_loops signed so that we really are running for ever
     rather than just a long time when we specify -1.
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCAAvFiEEbilms4eEBlKRJoGxVIU0mcT0FogFAlxV1XIRHGppYzIzQGtl
 cm5lbC5vcmcACgkQVIU0mcT0FogHVA/7BgI+H8bsVf3JpfmCvuptBiz5XREUC3Hr
 hN5jNwdMTkH8JkBLYMaC6wCph1x118Fc4UhGFx4NwSg3RfMw6tkDPd+PDI0QY0ii
 PUuTIDVMoo7+lKDvanm2yIjdkKwp18fceJRh1peLKBVJ3tQDLD9mJIzi5Ezc9/Y6
 Nq+xAv5v5ToE020Znm9oqhuY/lbKNjlcc+RKCy9Q5uFEPDfv2KZzymC/vpuTZ59J
 PoE9LRAJoag9/DgI/bskSR3aQbU+ESwKMzCLRvx73P2wZYjfwGFR2G4hCQ3tJbhJ
 m87qsnj8TxenLl9VTFvMrYp/c6XEpVp9lugYBlM1GMQV7SHV1DMXSFnnNFm3GHb4
 OtubvXD4S/279xlC7JhhH+b6r4TDL3P8rDW1tjmIzUmvczV9rzda+SWj4ea6Ry8d
 HtUY9RMrb+w1NEOEEMEYvykVxUS8SpzUVfEJKMKm9OspqjfCpELfVaBrHtomB6//
 F6z3oiNzDQPFcqIna/xri7PquFP6zmTmT/2ky+f11sBukukW5y0X/p4laVBHcVmw
 D6Au0BmtqB4NOdFcz1zsZNlbCKp3AGveZq5lMS7JQs3VWorJSYEQIQRKrVeSXgE2
 hbgLQkai+sVaYL8HSYEf83Mc0dm3/20+PW0oc9tRPysSFYwVIodPJb/1wV0qTKW6
 olFtou+Fg/U=
 =2R0k
 -----END PGP SIGNATURE-----

Merge tag 'iio-fixes-5.0a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-linus

Jonathan writes:

First set of IIO fixes for the 5.0 cycle.

Been a busy month, so these are rather later than they should have been.

* atlas-ph-sensor:
  - Temperature scale didn't correspond to the ABI.
* axp288:
  - A few different fixes around the TS-pin handling.
* ti-ads8688
  - Not enough space in the buffer used to build the scan to allow for
    the timestamp.
* tools - iio_generic_buffer
  - Make num_loops signed so that we really are running for ever
    rather than just a long time when we specify -1.

* tag 'iio-fixes-5.0a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio:
  iio: ti-ads8688: Update buffer allocation for timestamps
  tools: iio: iio_generic_buffer: make num_loops signed
  iio: adc: axp288: Fix TS-pin handling
  iio: chemical: atlas-ph-sensor: correct IIO_TEMP values to millicelsius
This commit is contained in:
Greg Kroah-Hartman 2019-02-03 13:10:41 +01:00
commit 6d923f8fe8
4 changed files with 66 additions and 22 deletions

View File

@ -27,9 +27,18 @@
#include <linux/iio/machine.h> #include <linux/iio/machine.h>
#include <linux/iio/driver.h> #include <linux/iio/driver.h>
#define AXP288_ADC_EN_MASK 0xF1 /*
#define AXP288_ADC_TS_PIN_GPADC 0xF2 * This mask enables all ADCs except for the battery temp-sensor (TS), that is
#define AXP288_ADC_TS_PIN_ON 0xF3 * left as-is to avoid breaking charging on devices without a temp-sensor.
*/
#define AXP288_ADC_EN_MASK 0xF0
#define AXP288_ADC_TS_ENABLE 0x01
#define AXP288_ADC_TS_CURRENT_ON_OFF_MASK GENMASK(1, 0)
#define AXP288_ADC_TS_CURRENT_OFF (0 << 0)
#define AXP288_ADC_TS_CURRENT_ON_WHEN_CHARGING (1 << 0)
#define AXP288_ADC_TS_CURRENT_ON_ONDEMAND (2 << 0)
#define AXP288_ADC_TS_CURRENT_ON (3 << 0)
enum axp288_adc_id { enum axp288_adc_id {
AXP288_ADC_TS, AXP288_ADC_TS,
@ -44,6 +53,7 @@ enum axp288_adc_id {
struct axp288_adc_info { struct axp288_adc_info {
int irq; int irq;
struct regmap *regmap; struct regmap *regmap;
bool ts_enabled;
}; };
static const struct iio_chan_spec axp288_adc_channels[] = { static const struct iio_chan_spec axp288_adc_channels[] = {
@ -115,21 +125,33 @@ static int axp288_adc_read_channel(int *val, unsigned long address,
return IIO_VAL_INT; return IIO_VAL_INT;
} }
static int axp288_adc_set_ts(struct regmap *regmap, unsigned int mode, /*
unsigned long address) * The current-source used for the battery temp-sensor (TS) is shared
* with the GPADC. For proper fuel-gauge and charger operation the TS
* current-source needs to be permanently on. But to read the GPADC we
* need to temporary switch the TS current-source to ondemand, so that
* the GPADC can use it, otherwise we will always read an all 0 value.
*/
static int axp288_adc_set_ts(struct axp288_adc_info *info,
unsigned int mode, unsigned long address)
{ {
int ret; int ret;
/* channels other than GPADC do not need to switch TS pin */ /* No need to switch the current-source if the TS pin is disabled */
if (!info->ts_enabled)
return 0;
/* Channels other than GPADC do not need the current source */
if (address != AXP288_GP_ADC_H) if (address != AXP288_GP_ADC_H)
return 0; return 0;
ret = regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, mode); ret = regmap_update_bits(info->regmap, AXP288_ADC_TS_PIN_CTRL,
AXP288_ADC_TS_CURRENT_ON_OFF_MASK, mode);
if (ret) if (ret)
return ret; return ret;
/* When switching to the GPADC pin give things some time to settle */ /* When switching to the GPADC pin give things some time to settle */
if (mode == AXP288_ADC_TS_PIN_GPADC) if (mode == AXP288_ADC_TS_CURRENT_ON_ONDEMAND)
usleep_range(6000, 10000); usleep_range(6000, 10000);
return 0; return 0;
@ -145,14 +167,14 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,
mutex_lock(&indio_dev->mlock); mutex_lock(&indio_dev->mlock);
switch (mask) { switch (mask) {
case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_RAW:
if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_GPADC, if (axp288_adc_set_ts(info, AXP288_ADC_TS_CURRENT_ON_ONDEMAND,
chan->address)) { chan->address)) {
dev_err(&indio_dev->dev, "GPADC mode\n"); dev_err(&indio_dev->dev, "GPADC mode\n");
ret = -EINVAL; ret = -EINVAL;
break; break;
} }
ret = axp288_adc_read_channel(val, chan->address, info->regmap); ret = axp288_adc_read_channel(val, chan->address, info->regmap);
if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_ON, if (axp288_adc_set_ts(info, AXP288_ADC_TS_CURRENT_ON,
chan->address)) chan->address))
dev_err(&indio_dev->dev, "TS pin restore\n"); dev_err(&indio_dev->dev, "TS pin restore\n");
break; break;
@ -164,13 +186,35 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,
return ret; return ret;
} }
static int axp288_adc_set_state(struct regmap *regmap) static int axp288_adc_initialize(struct axp288_adc_info *info)
{ {
/* ADC should be always enabled for internal FG to function */ int ret, adc_enable_val;
if (regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, AXP288_ADC_TS_PIN_ON))
return -EIO;
return regmap_write(regmap, AXP20X_ADC_EN1, AXP288_ADC_EN_MASK); /*
* Determine if the TS pin is enabled and set the TS current-source
* accordingly.
*/
ret = regmap_read(info->regmap, AXP20X_ADC_EN1, &adc_enable_val);
if (ret)
return ret;
if (adc_enable_val & AXP288_ADC_TS_ENABLE) {
info->ts_enabled = true;
ret = regmap_update_bits(info->regmap, AXP288_ADC_TS_PIN_CTRL,
AXP288_ADC_TS_CURRENT_ON_OFF_MASK,
AXP288_ADC_TS_CURRENT_ON);
} else {
info->ts_enabled = false;
ret = regmap_update_bits(info->regmap, AXP288_ADC_TS_PIN_CTRL,
AXP288_ADC_TS_CURRENT_ON_OFF_MASK,
AXP288_ADC_TS_CURRENT_OFF);
}
if (ret)
return ret;
/* Turn on the ADC for all channels except TS, leave TS as is */
return regmap_update_bits(info->regmap, AXP20X_ADC_EN1,
AXP288_ADC_EN_MASK, AXP288_ADC_EN_MASK);
} }
static const struct iio_info axp288_adc_iio_info = { static const struct iio_info axp288_adc_iio_info = {
@ -200,7 +244,7 @@ static int axp288_adc_probe(struct platform_device *pdev)
* Set ADC to enabled state at all time, including system suspend. * Set ADC to enabled state at all time, including system suspend.
* otherwise internal fuel gauge functionality may be affected. * otherwise internal fuel gauge functionality may be affected.
*/ */
ret = axp288_adc_set_state(axp20x->regmap); ret = axp288_adc_initialize(info);
if (ret) { if (ret) {
dev_err(&pdev->dev, "unable to enable ADC device\n"); dev_err(&pdev->dev, "unable to enable ADC device\n");
return ret; return ret;

View File

@ -41,6 +41,7 @@
#define ADS8688_VREF_MV 4096 #define ADS8688_VREF_MV 4096
#define ADS8688_REALBITS 16 #define ADS8688_REALBITS 16
#define ADS8688_MAX_CHANNELS 8
/* /*
* enum ads8688_range - ADS8688 reference voltage range * enum ads8688_range - ADS8688 reference voltage range
@ -385,7 +386,7 @@ static irqreturn_t ads8688_trigger_handler(int irq, void *p)
{ {
struct iio_poll_func *pf = p; struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev; struct iio_dev *indio_dev = pf->indio_dev;
u16 buffer[8]; u16 buffer[ADS8688_MAX_CHANNELS + sizeof(s64)/sizeof(u16)];
int i, j = 0; int i, j = 0;
for (i = 0; i < indio_dev->masklength; i++) { for (i = 0; i < indio_dev->masklength; i++) {

View File

@ -444,9 +444,8 @@ static int atlas_read_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
switch (chan->type) { switch (chan->type) {
case IIO_TEMP: case IIO_TEMP:
*val = 1; /* 0.01 */ *val = 10;
*val2 = 100; return IIO_VAL_INT;
break;
case IIO_PH: case IIO_PH:
*val = 1; /* 0.001 */ *val = 1; /* 0.001 */
*val2 = 1000; *val2 = 1000;
@ -477,7 +476,7 @@ static int atlas_write_raw(struct iio_dev *indio_dev,
int val, int val2, long mask) int val, int val2, long mask)
{ {
struct atlas_data *data = iio_priv(indio_dev); struct atlas_data *data = iio_priv(indio_dev);
__be32 reg = cpu_to_be32(val); __be32 reg = cpu_to_be32(val / 10);
if (val2 != 0 || val < 0 || val > 20000) if (val2 != 0 || val < 0 || val > 20000)
return -EINVAL; return -EINVAL;

View File

@ -330,7 +330,7 @@ static const struct option longopts[] = {
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
unsigned long long num_loops = 2; long long num_loops = 2;
unsigned long timedelay = 1000000; unsigned long timedelay = 1000000;
unsigned long buf_len = 128; unsigned long buf_len = 128;