Commit e464f50c authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'staging-5.0-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging

Pull staging/IIO driver fixes from Greg KH:
 "Here are some small iio and staging driver fixes for 5.0-rc6.

  Nothing big, just resolve some reported IIO driver issues, and one
  staging driver bug. One staging driver patch was added and then
  reverted as well.

  All of these have been in linux-next for a while with no reported
  issues"

* tag 'staging-5.0-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging:
  Revert "staging: erofs: keep corrupted fs from crashing kernel in erofs_namei()"
  staging: erofs: keep corrupted fs from crashing kernel in erofs_namei()
  staging: octeon: fix broken phylib usage
  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
parents e22a15d1 6d923f8f
......@@ -27,9 +27,18 @@
#include <linux/iio/machine.h>
#include <linux/iio/driver.h>
#define AXP288_ADC_EN_MASK 0xF1
#define AXP288_ADC_TS_PIN_GPADC 0xF2
#define AXP288_ADC_TS_PIN_ON 0xF3
/*
* This mask enables all ADCs except for the battery temp-sensor (TS), that is
* 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 {
AXP288_ADC_TS,
......@@ -44,6 +53,7 @@ enum axp288_adc_id {
struct axp288_adc_info {
int irq;
struct regmap *regmap;
bool ts_enabled;
};
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;
}
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;
/* 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)
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)
return ret;
/* 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);
return 0;
......@@ -145,14 +167,14 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,
mutex_lock(&indio_dev->mlock);
switch (mask) {
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)) {
dev_err(&indio_dev->dev, "GPADC mode\n");
ret = -EINVAL;
break;
}
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))
dev_err(&indio_dev->dev, "TS pin restore\n");
break;
......@@ -164,13 +186,35 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,
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 */
if (regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, AXP288_ADC_TS_PIN_ON))
return -EIO;
int ret, adc_enable_val;
/*
* 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;
return regmap_write(regmap, AXP20X_ADC_EN1, AXP288_ADC_EN_MASK);
/* 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 = {
......@@ -200,7 +244,7 @@ static int axp288_adc_probe(struct platform_device *pdev)
* Set ADC to enabled state at all time, including system suspend.
* otherwise internal fuel gauge functionality may be affected.
*/
ret = axp288_adc_set_state(axp20x->regmap);
ret = axp288_adc_initialize(info);
if (ret) {
dev_err(&pdev->dev, "unable to enable ADC device\n");
return ret;
......
......@@ -41,6 +41,7 @@
#define ADS8688_VREF_MV 4096
#define ADS8688_REALBITS 16
#define ADS8688_MAX_CHANNELS 8
/*
* 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_dev *indio_dev = pf->indio_dev;
u16 buffer[8];
u16 buffer[ADS8688_MAX_CHANNELS + sizeof(s64)/sizeof(u16)];
int i, j = 0;
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:
switch (chan->type) {
case IIO_TEMP:
*val = 1; /* 0.01 */
*val2 = 100;
break;
*val = 10;
return IIO_VAL_INT;
case IIO_PH:
*val = 1; /* 0.001 */
*val2 = 1000;
......@@ -477,7 +476,7 @@ static int atlas_write_raw(struct iio_dev *indio_dev,
int val, int val2, long mask)
{
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)
return -EINVAL;
......
......@@ -170,7 +170,7 @@ int cvm_oct_phy_setup_device(struct net_device *dev)
return -ENODEV;
priv->last_link = 0;
phy_start_aneg(phydev);
phy_start(phydev);
return 0;
no_phy:
......
......@@ -330,7 +330,7 @@ static const struct option longopts[] = {
int main(int argc, char **argv)
{
unsigned long long num_loops = 2;
long long num_loops = 2;
unsigned long timedelay = 1000000;
unsigned long buf_len = 128;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment