struct mt6370_adc_data { struct device *dev; struct regmap *regmap; /* * This mutex lock is for preventing the different ADC channels * from being read at the same time.
*/ struct mutex adc_lock; unsignedint vid;
};
staticint mt6370_adc_read_channel(struct mt6370_adc_data *priv, int chan, unsignedlong addr, int *val)
{ unsignedint reg_val;
__be16 be_val; int ret;
mutex_lock(&priv->adc_lock);
reg_val = MT6370_ADC_START_MASK |
FIELD_PREP(MT6370_ADC_IN_SEL_MASK, addr);
ret = regmap_write(priv->regmap, MT6370_REG_CHG_ADC, reg_val); if (ret) goto adc_unlock;
msleep(ADC_CONV_TIME_MS);
ret = regmap_read_poll_timeout(priv->regmap,
MT6370_REG_CHG_ADC, reg_val,
!(reg_val & MT6370_ADC_START_MASK),
ADC_CONV_POLLING_TIME_US,
ADC_CONV_TIME_MS * MILLI * 3); if (ret) {
dev_err(priv->dev, "Failed to read ADC register (%d)\n", ret); goto adc_unlock;
}
ret = regmap_raw_read(priv->regmap, MT6370_REG_ADC_DATA_H,
&be_val, sizeof(be_val)); if (ret) goto adc_unlock;
*val = be16_to_cpu(be_val);
ret = IIO_VAL_INT;
adc_unlock:
mutex_unlock(&priv->adc_lock);
return ret;
}
staticint mt6370_adc_get_ibus_scale(struct mt6370_adc_data *priv)
{ switch (priv->vid) { case MT6370_VID_RT5081: case MT6370_VID_RT5081A: case MT6370_VID_MT6370: return 3350; default: return 3875;
}
}
staticint mt6370_adc_get_ibat_scale(struct mt6370_adc_data *priv)
{ switch (priv->vid) { case MT6370_VID_RT5081: case MT6370_VID_RT5081A: case MT6370_VID_MT6370: return 2680; default: return 3870;
}
}
staticint mt6370_adc_read_scale(struct mt6370_adc_data *priv, int chan, int *val1, int *val2)
{ unsignedint reg_val; int ret;
switch (chan) { case MT6370_CHAN_VBAT: case MT6370_CHAN_VSYS: case MT6370_CHAN_CHG_VDDP:
*val1 = 5; return IIO_VAL_INT; case MT6370_CHAN_IBUS:
ret = regmap_read(priv->regmap, MT6370_REG_CHG_CTRL3, ®_val); if (ret) return ret;
reg_val = FIELD_GET(MT6370_AICR_ICHG_MASK, reg_val); switch (reg_val) { case MT6370_AICR_100_mA: case MT6370_AICR_150_mA: case MT6370_AICR_200_mA: case MT6370_AICR_250_mA: case MT6370_AICR_300_mA: case MT6370_AICR_350_mA:
*val1 = mt6370_adc_get_ibus_scale(priv); break; default:
*val1 = 5000; break;
}
*val2 = 100;
return IIO_VAL_FRACTIONAL; case MT6370_CHAN_IBAT:
ret = regmap_read(priv->regmap, MT6370_REG_CHG_CTRL7, ®_val); if (ret) return ret;
reg_val = FIELD_GET(MT6370_AICR_ICHG_MASK, reg_val); switch (reg_val) { case MT6370_ICHG_100_mA: case MT6370_ICHG_200_mA: case MT6370_ICHG_300_mA: case MT6370_ICHG_400_mA:
*val1 = 2375; break; case MT6370_ICHG_500_mA: case MT6370_ICHG_600_mA: case MT6370_ICHG_700_mA: case MT6370_ICHG_800_mA:
*val1 = mt6370_adc_get_ibat_scale(priv); break; default:
*val1 = 5000; break;
}
*val2 = 100;
return IIO_VAL_FRACTIONAL; case MT6370_CHAN_VBUSDIV5:
*val1 = 25; return IIO_VAL_INT; case MT6370_CHAN_VBUSDIV2:
*val1 = 10; return IIO_VAL_INT; case MT6370_CHAN_TS_BAT:
*val1 = 25;
*val2 = 10000; return IIO_VAL_FRACTIONAL; case MT6370_CHAN_TEMP_JC:
*val1 = 2000; return IIO_VAL_INT; default: return -EINVAL;
}
}
staticint mt6370_adc_read_offset(struct mt6370_adc_data *priv, int chan, int *val)
{
*val = -20;
return IIO_VAL_INT;
}
staticint mt6370_adc_read_raw(struct iio_dev *iio_dev, conststruct iio_chan_spec *chan, int *val, int *val2, long mask)
{ struct mt6370_adc_data *priv = iio_priv(iio_dev);
switch (mask) { case IIO_CHAN_INFO_RAW: return mt6370_adc_read_channel(priv, chan->channel,
chan->address, val); case IIO_CHAN_INFO_SCALE: return mt6370_adc_read_scale(priv, chan->channel, val, val2); case IIO_CHAN_INFO_OFFSET: return mt6370_adc_read_offset(priv, chan->channel, val); default: return -EINVAL;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.