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:
commit
6d923f8fe8
|
@ -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;
|
||||||
|
|
|
@ -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++) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue