drivers/iio/adc/mt6370-adc.c

Source file repositories/reference/linux-study-clean/drivers/iio/adc/mt6370-adc.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/mt6370-adc.c
Extension
.c
Size
8647 bytes
Lines
355
Domain
Driver Families
Bucket
drivers/iio
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

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;
	unsigned int vid;
};

static int mt6370_adc_read_channel(struct mt6370_adc_data *priv, int chan,
				   unsigned long addr, int *val)
{
	unsigned int 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;
}

static int 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;
	}
}

static int 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;
	}
}

static int mt6370_adc_read_scale(struct mt6370_adc_data *priv,
				 int chan, int *val1, int *val2)
{
	unsigned int 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, &reg_val);

Annotation

Implementation Notes