iio: adc: meson: support reading from channel 7 mux inputs
Add IIO channel for all muxed inputs of channel 7. Meson saradc channel 7 is connected to a mux that can switch input to well-known sources like Vdd, GND and several Vdd dividers. Signed-off-by: George Stark <GNStark@sberdevices.ru> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Link: https://lore.kernel.org/r/20230714114010.293440-7-gnstark@sberdevices.ru Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This commit is contained in:
parent
b593ce5db2
commit
3a06b2845a
|
@ -163,6 +163,7 @@
|
|||
#define MESON_SAR_ADC_MAX_FIFO_SIZE 32
|
||||
#define MESON_SAR_ADC_TIMEOUT 100 /* ms */
|
||||
#define MESON_SAR_ADC_VOLTAGE_AND_TEMP_CHANNEL 6
|
||||
#define MESON_SAR_ADC_VOLTAGE_AND_MUX_CHANNEL 7
|
||||
#define MESON_SAR_ADC_TEMP_OFFSET 27
|
||||
|
||||
/* temperature sensor calibration information in eFuse */
|
||||
|
@ -202,6 +203,19 @@
|
|||
.datasheet_name = "TEMP_SENSOR", \
|
||||
}
|
||||
|
||||
#define MESON_SAR_ADC_MUX(_chan, _sel) { \
|
||||
.type = IIO_VOLTAGE, \
|
||||
.channel = _chan, \
|
||||
.indexed = 1, \
|
||||
.address = MESON_SAR_ADC_VOLTAGE_AND_MUX_CHANNEL, \
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
|
||||
BIT(IIO_CHAN_INFO_AVERAGE_RAW), \
|
||||
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
|
||||
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_CALIBBIAS) | \
|
||||
BIT(IIO_CHAN_INFO_CALIBSCALE), \
|
||||
.datasheet_name = "SAR_ADC_MUX_"#_sel, \
|
||||
}
|
||||
|
||||
enum meson_sar_adc_avg_mode {
|
||||
NO_AVERAGING = 0x0,
|
||||
MEAN_AVERAGING = 0x1,
|
||||
|
@ -234,6 +248,27 @@ enum meson_sar_adc_channel_index {
|
|||
NUM_CHAN_6,
|
||||
NUM_CHAN_7,
|
||||
NUM_CHAN_TEMP,
|
||||
NUM_MUX_0_VSS,
|
||||
NUM_MUX_1_VDD_DIV4,
|
||||
NUM_MUX_2_VDD_DIV2,
|
||||
NUM_MUX_3_VDD_MUL3_DIV4,
|
||||
NUM_MUX_4_VDD,
|
||||
};
|
||||
|
||||
static enum meson_sar_adc_chan7_mux_sel chan7_mux_values[] = {
|
||||
CHAN7_MUX_VSS,
|
||||
CHAN7_MUX_VDD_DIV4,
|
||||
CHAN7_MUX_VDD_DIV2,
|
||||
CHAN7_MUX_VDD_MUL3_DIV4,
|
||||
CHAN7_MUX_VDD,
|
||||
};
|
||||
|
||||
static const char * const chan7_mux_names[] = {
|
||||
[CHAN7_MUX_VSS] = "gnd",
|
||||
[CHAN7_MUX_VDD_DIV4] = "0.25vdd",
|
||||
[CHAN7_MUX_VDD_DIV2] = "0.5vdd",
|
||||
[CHAN7_MUX_VDD_MUL3_DIV4] = "0.75vdd",
|
||||
[CHAN7_MUX_VDD] = "vdd",
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec meson_sar_adc_iio_channels[] = {
|
||||
|
@ -245,6 +280,11 @@ static const struct iio_chan_spec meson_sar_adc_iio_channels[] = {
|
|||
MESON_SAR_ADC_CHAN(NUM_CHAN_5),
|
||||
MESON_SAR_ADC_CHAN(NUM_CHAN_6),
|
||||
MESON_SAR_ADC_CHAN(NUM_CHAN_7),
|
||||
MESON_SAR_ADC_MUX(NUM_MUX_0_VSS, 0),
|
||||
MESON_SAR_ADC_MUX(NUM_MUX_1_VDD_DIV4, 1),
|
||||
MESON_SAR_ADC_MUX(NUM_MUX_2_VDD_DIV2, 2),
|
||||
MESON_SAR_ADC_MUX(NUM_MUX_3_VDD_MUL3_DIV4, 3),
|
||||
MESON_SAR_ADC_MUX(NUM_MUX_4_VDD, 4),
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec meson_sar_adc_and_temp_iio_channels[] = {
|
||||
|
@ -257,6 +297,11 @@ static const struct iio_chan_spec meson_sar_adc_and_temp_iio_channels[] = {
|
|||
MESON_SAR_ADC_CHAN(NUM_CHAN_6),
|
||||
MESON_SAR_ADC_CHAN(NUM_CHAN_7),
|
||||
MESON_SAR_ADC_TEMP_CHAN(NUM_CHAN_TEMP),
|
||||
MESON_SAR_ADC_MUX(NUM_MUX_0_VSS, 0),
|
||||
MESON_SAR_ADC_MUX(NUM_MUX_1_VDD_DIV4, 1),
|
||||
MESON_SAR_ADC_MUX(NUM_MUX_2_VDD_DIV2, 2),
|
||||
MESON_SAR_ADC_MUX(NUM_MUX_3_VDD_MUL3_DIV4, 3),
|
||||
MESON_SAR_ADC_MUX(NUM_MUX_4_VDD, 4),
|
||||
};
|
||||
|
||||
struct meson_sar_adc_param {
|
||||
|
@ -295,6 +340,7 @@ struct meson_sar_adc_priv {
|
|||
bool temperature_sensor_calibrated;
|
||||
u8 temperature_sensor_coefficient;
|
||||
u16 temperature_sensor_adc_val;
|
||||
enum meson_sar_adc_chan7_mux_sel chan7_mux_sel;
|
||||
};
|
||||
|
||||
static const struct regmap_config meson_sar_adc_regmap_config_gxbb = {
|
||||
|
@ -311,6 +357,17 @@ static const struct regmap_config meson_sar_adc_regmap_config_meson8 = {
|
|||
.max_register = MESON_SAR_ADC_DELTA_10,
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec *
|
||||
find_channel_by_num(struct iio_dev *indio_dev, int num)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < indio_dev->num_channels; i++)
|
||||
if (indio_dev->channels[i].channel == num)
|
||||
return &indio_dev->channels[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static unsigned int meson_sar_adc_get_fifo_count(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
|
||||
|
@ -359,6 +416,8 @@ static void meson_sar_adc_set_chan7_mux(struct iio_dev *indio_dev,
|
|||
MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK, regval);
|
||||
|
||||
usleep_range(10, 20);
|
||||
|
||||
priv->chan7_mux_sel = sel;
|
||||
}
|
||||
|
||||
static int meson_sar_adc_read_raw_sample(struct iio_dev *indio_dev,
|
||||
|
@ -454,6 +513,15 @@ static void meson_sar_adc_enable_channel(struct iio_dev *indio_dev,
|
|||
regmap_update_bits(priv->regmap,
|
||||
MESON_SAR_ADC_DELTA_10,
|
||||
MESON_SAR_ADC_DELTA_10_TEMP_SEL, regval);
|
||||
} else if (chan->address == MESON_SAR_ADC_VOLTAGE_AND_MUX_CHANNEL) {
|
||||
enum meson_sar_adc_chan7_mux_sel sel;
|
||||
|
||||
if (chan->channel == NUM_CHAN_7)
|
||||
sel = CHAN7_MUX_CH7_INPUT;
|
||||
else
|
||||
sel = chan7_mux_values[chan->channel - NUM_MUX_0_VSS];
|
||||
if (sel != priv->chan7_mux_sel)
|
||||
meson_sar_adc_set_chan7_mux(indio_dev, sel);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1026,7 +1094,8 @@ static int meson_sar_adc_calib(struct iio_dev *indio_dev)
|
|||
meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_VDD_DIV4);
|
||||
usleep_range(10, 20);
|
||||
ret = meson_sar_adc_get_sample(indio_dev,
|
||||
&indio_dev->channels[7],
|
||||
find_channel_by_num(indio_dev,
|
||||
NUM_MUX_1_VDD_DIV4),
|
||||
MEAN_AVERAGING, EIGHT_SAMPLES, &value0);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
@ -1034,7 +1103,8 @@ static int meson_sar_adc_calib(struct iio_dev *indio_dev)
|
|||
meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_VDD_MUL3_DIV4);
|
||||
usleep_range(10, 20);
|
||||
ret = meson_sar_adc_get_sample(indio_dev,
|
||||
&indio_dev->channels[7],
|
||||
find_channel_by_num(indio_dev,
|
||||
NUM_MUX_3_VDD_MUL3_DIV4),
|
||||
MEAN_AVERAGING, EIGHT_SAMPLES, &value1);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
@ -1061,6 +1131,9 @@ static int read_label(struct iio_dev *indio_dev,
|
|||
{
|
||||
if (chan->type == IIO_TEMP)
|
||||
return sprintf(label, "temp-sensor\n");
|
||||
if (chan->type == IIO_VOLTAGE && chan->channel >= NUM_MUX_0_VSS)
|
||||
return sprintf(label, "%s\n",
|
||||
chan7_mux_names[chan->channel - NUM_MUX_0_VSS]);
|
||||
if (chan->type == IIO_VOLTAGE)
|
||||
return sprintf(label, "channel-%d\n", chan->channel);
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue