drivers/iio/adc/sc27xx_adc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/sc27xx_adc.c
Extension
.c
Size
24493 bytes
Lines
955
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 sc27xx_adc_data {
	struct device *dev;
	struct regulator *volref;
	struct regmap *regmap;
	/* lock to protect against multiple access to the device */
	struct mutex lock;
	/*
	 * One hardware spinlock to synchronize between the multiple
	 * subsystems which will access the unique ADC controller.
	 */
	struct hwspinlock *hwlock;
	int channel_scale[SC27XX_ADC_CHANNEL_MAX];
	u32 base;
	int irq;
	const struct sc27xx_adc_variant_data *var_data;
};

/*
 * Since different PMICs of SC27xx series can have different
 * address and ratio, we should save ratio config and base
 * in the device data structure.
 */
struct sc27xx_adc_variant_data {
	u32 module_en;
	u32 clk_en;
	u32 scale_shift;
	u32 scale_mask;
	const struct sc27xx_adc_linear_graph *bscale_cal;
	const struct sc27xx_adc_linear_graph *sscale_cal;
	void (*init_scale)(struct sc27xx_adc_data *data);
	int (*get_ratio)(int channel, int scale);
	bool set_volref;
};

struct sc27xx_adc_linear_graph {
	int volt0;
	int adc0;
	int volt1;
	int adc1;
};

/*
 * According to the datasheet, we can convert one ADC value to one voltage value
 * through 2 points in the linear graph. If the voltage is less than 1.2v, we
 * should use the small-scale graph, and if more than 1.2v, we should use the
 * big-scale graph.
 */
static struct sc27xx_adc_linear_graph big_scale_graph = {
	4200, 3310,
	3600, 2832,
};

static struct sc27xx_adc_linear_graph small_scale_graph = {
	1000, 3413,
	100, 341,
};

static const struct sc27xx_adc_linear_graph sc2731_big_scale_graph_calib = {
	4200, 850,
	3600, 728,
};

static const struct sc27xx_adc_linear_graph sc2731_small_scale_graph_calib = {
	1000, 838,
	100, 84,
};

static const struct sc27xx_adc_linear_graph big_scale_graph_calib = {
	4200, 856,
	3600, 733,
};

static const struct sc27xx_adc_linear_graph small_scale_graph_calib = {
	1000, 833,
	100, 80,
};

static int sc27xx_adc_get_calib_data(u32 calib_data, int calib_adc)
{
	return ((calib_data & 0xff) + calib_adc - 128) * 4;
}

/* get the adc nvmem cell calibration data */
static int adc_nvmem_cell_calib_data(struct sc27xx_adc_data *data, const char *cell_name)
{
	struct nvmem_cell *cell;
	void *buf;
	u32 origin_calib_data = 0;
	size_t len;

Annotation

Implementation Notes