drivers/iio/adc/ab8500-gpadc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/ab8500-gpadc.c
Extension
.c
Size
36976 bytes
Lines
1203
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 ab8500_adc_cal_data {
	s64 gain;
	s64 offset;
	u16 otp_calib_hi;
	u16 otp_calib_lo;
};

/**
 * struct ab8500_gpadc_chan_info - per-channel GPADC info
 * @name: name of the channel
 * @id: the internal AB8500 ID number for the channel
 * @hardware_control: indicate that we want to use hardware ADC control
 * on this channel, the default is software ADC control. Hardware control
 * is normally only used to test the battery voltage during GSM bursts
 * and needs a hardware trigger on the GPADCTrig pin of the ASIC.
 * @falling_edge: indicate that we want to trigger on falling edge
 * rather than rising edge, rising edge is the default
 * @avg_sample: how many samples to average: must be 1, 4, 8 or 16.
 * @trig_timer: how long to wait for the trigger, in 32kHz periods:
 * 0 .. 255 periods
 */
struct ab8500_gpadc_chan_info {
	const char *name;
	u8 id;
	bool hardware_control;
	bool falling_edge;
	u8 avg_sample;
	u8 trig_timer;
};

/**
 * struct ab8500_gpadc - AB8500 GPADC device information
 * @dev: pointer to the containing device
 * @ab8500: pointer to the parent AB8500 device
 * @chans: internal per-channel information container
 * @nchans: number of channels
 * @complete: pointer to the completion that indicates
 * the completion of an gpadc conversion cycle
 * @vddadc: pointer to the regulator supplying VDDADC
 * @irq_sw: interrupt number that is used by gpadc for software ADC conversion
 * @irq_hw: interrupt number that is used by gpadc for hardware ADC conversion
 * @cal_data: array of ADC calibration data structs
 */
struct ab8500_gpadc {
	struct device *dev;
	struct ab8500 *ab8500;
	struct ab8500_gpadc_chan_info *chans;
	unsigned int nchans;
	struct completion complete;
	struct regulator *vddadc;
	int irq_sw;
	int irq_hw;
	struct ab8500_adc_cal_data cal_data[AB8500_CAL_NR];
};

static struct ab8500_gpadc_chan_info *
ab8500_gpadc_get_channel(struct ab8500_gpadc *gpadc, u8 chan)
{
	struct ab8500_gpadc_chan_info *ch;
	int i;

	for (i = 0; i < gpadc->nchans; i++) {
		ch = &gpadc->chans[i];
		if (ch->id == chan)
			break;
	}
	if (i == gpadc->nchans)
		return NULL;

	return ch;
}

/**
 * ab8500_gpadc_ad_to_voltage() - Convert a raw ADC value to a voltage
 * @gpadc: GPADC instance
 * @ch: the sampled channel this raw value is coming from
 * @ad_value: the raw value
 */
static int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc,
				      enum ab8500_gpadc_channel ch,
				      int ad_value)
{
	int res;

	switch (ch) {
	case AB8500_GPADC_CHAN_MAIN_CHARGER:
		/* No calibration data available: just interpolate */
		if (!gpadc->cal_data[AB8500_CAL_VMAIN].gain) {
			res = AB8500_ADC_CH_CHG_V_MIN + (AB8500_ADC_CH_CHG_V_MAX -
				AB8500_ADC_CH_CHG_V_MIN) * ad_value /

Annotation

Implementation Notes