drivers/iio/adc/da9150-gpadc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/da9150-gpadc.c
Extension
.c
Size
9649 bytes
Lines
359
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 da9150_gpadc {
	struct da9150 *da9150;
	struct device *dev;

	struct mutex lock;
	struct completion complete;
};


static irqreturn_t da9150_gpadc_irq(int irq, void *data)
{

	struct da9150_gpadc *gpadc = data;

	complete(&gpadc->complete);

	return IRQ_HANDLED;
}

static int da9150_gpadc_read_adc(struct da9150_gpadc *gpadc, int hw_chan)
{
	u8 result_regs[2];
	int result;

	mutex_lock(&gpadc->lock);

	/* Set channel & enable measurement */
	da9150_reg_write(gpadc->da9150, DA9150_GPADC_MAN,
			 (DA9150_GPADC_EN_MASK |
			  hw_chan << DA9150_GPADC_MUX_SHIFT));

	/* Consume left-over completion from a previous timeout */
	try_wait_for_completion(&gpadc->complete);

	/* Check for actual completion */
	wait_for_completion_timeout(&gpadc->complete, msecs_to_jiffies(5));

	/* Read result and status from device */
	da9150_bulk_read(gpadc->da9150, DA9150_GPADC_RES_A, 2, result_regs);

	mutex_unlock(&gpadc->lock);

	/* Check to make sure device really has completed reading */
	if (result_regs[1] & DA9150_GPADC_RUN_MASK) {
		dev_err(gpadc->dev, "Timeout on channel %d of GPADC\n",
			hw_chan);
		return -ETIMEDOUT;
	}

	/* LSBs - 2 bits */
	result = (result_regs[1] & DA9150_GPADC_RES_L_MASK) >>
		 DA9150_GPADC_RES_L_SHIFT;
	/* MSBs - 8 bits */
	result |= result_regs[0] << DA9150_GPADC_RES_L_BITS;

	return result;
}

static inline int da9150_gpadc_gpio_6v_voltage_now(int raw_val)
{
	/* Convert to mV */
	return (6 * ((raw_val * 1000) + 500)) / 1024;
}

static inline int da9150_gpadc_ibus_current_avg(int raw_val)
{
	/* Convert to mA */
	return (4 * ((raw_val * 1000) + 500)) / 2048;
}

static inline int da9150_gpadc_vbus_21v_voltage_now(int raw_val)
{
	/* Convert to mV */
	return (21 * ((raw_val * 1000) + 500)) / 1024;
}

static inline int da9150_gpadc_vsys_6v_voltage_now(int raw_val)
{
	/* Convert to mV */
	return (3 * ((raw_val * 1000) + 500)) / 512;
}

static int da9150_gpadc_read_processed(struct da9150_gpadc *gpadc, int channel,
				       int hw_chan, int *val)
{
	int raw_val;

	raw_val = da9150_gpadc_read_adc(gpadc, hw_chan);
	if (raw_val < 0)
		return raw_val;

Annotation

Implementation Notes