static inline unsigned int aspeed_adc_get_active_channels(const struct aspeed_adc_data *data)
{
+ /*
+ * For controllers with battery sensing capability, the last channel
+ * is reserved for battery sensing and should not be included in
+ * normal channel operations.
+ */
+ if (data->model_data->bat_sense_sup)
+ return data->model_data->num_channels - 1;
return data->model_data->num_channels;
}
ASPEED_ADC_CTRL_CHANNEL_ENABLE(0),
data->base + ASPEED_REG_ENGINE_CONTROL);
/*
- * After enable compensating sensing mode need to wait some time for ADC stable
- * Experiment result is 1ms.
+ * After enable compensating sensing mode need to wait some time for the
+ * ADC stablize. Experiment result is 1ms.
*/
fsleep(1000);
switch (mask) {
case IIO_CHAN_INFO_RAW:
+ adc_engine_control_reg_val = readl(data->base + ASPEED_REG_ENGINE_CONTROL);
+ /*
+ * For battery sensing capable controllers, we need to enable
+ * the specific channel before reading. This is required because
+ * the battery channel may not be enabled by default.
+ */
+ if (data->model_data->bat_sense_sup &&
+ chan->channel == ASPEED_ADC_BATTERY_CHANNEL) {
+ u32 ctrl_reg = adc_engine_control_reg_val & ~ASPEED_ADC_CTRL_CHANNEL;
+
+ ctrl_reg |= ASPEED_ADC_CTRL_CHANNEL_ENABLE(chan->channel);
+ writel(ctrl_reg, data->base + ASPEED_REG_ENGINE_CONTROL);
+ /*
+ * After enable a new channel need to wait some time for ADC stable
+ * Experiment result is 1ms.
+ */
+ fsleep(1000);
+ }
+
if (data->battery_sensing && chan->channel == ASPEED_ADC_BATTERY_CHANNEL) {
- adc_engine_control_reg_val =
- readl(data->base + ASPEED_REG_ENGINE_CONTROL);
writel(adc_engine_control_reg_val |
FIELD_PREP(ASPEED_ADC_CH7_MODE,
ASPEED_ADC_CH7_BAT) |
*val = readw(data->base + chan->address);
*val = (*val * data->battery_mode_gain.mult) /
data->battery_mode_gain.div;
- /* Restore control register value */
- writel(adc_engine_control_reg_val,
- data->base + ASPEED_REG_ENGINE_CONTROL);
} else
*val = readw(data->base + chan->address);
+ /* Restore control register value */
+ writel(adc_engine_control_reg_val,
+ data->base + ASPEED_REG_ENGINE_CONTROL);
return IIO_VAL_INT;
case IIO_CHAN_INFO_OFFSET: