drivers/hwmon/da9052-hwmon.c

Source file repositories/reference/linux-study-clean/drivers/hwmon/da9052-hwmon.c

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/da9052-hwmon.c
Extension
.c
Size
13617 bytes
Lines
488
Domain
Driver Families
Bucket
drivers/hwmon
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 da9052_hwmon {
	struct da9052		*da9052;
	struct mutex		hwmon_lock;
	bool			tsi_as_adc;
	int			tsiref_mv;
	struct completion	tsidone;
};

static const char * const input_names[] = {
	[DA9052_ADC_VDDOUT]	=	"VDDOUT",
	[DA9052_ADC_ICH]	=	"CHARGING CURRENT",
	[DA9052_ADC_TBAT]	=	"BATTERY TEMP",
	[DA9052_ADC_VBAT]	=	"BATTERY VOLTAGE",
	[DA9052_ADC_IN4]	=	"ADC IN4",
	[DA9052_ADC_IN5]	=	"ADC IN5",
	[DA9052_ADC_IN6]	=	"ADC IN6",
	[DA9052_ADC_TSI_XP]	=	"ADC TS X+",
	[DA9052_ADC_TSI_YP]	=	"ADC TS Y+",
	[DA9052_ADC_TSI_XN]	=	"ADC TS X-",
	[DA9052_ADC_TSI_YN]	=	"ADC TS Y-",
	[DA9052_ADC_TJUNC]	=	"BATTERY JUNCTION TEMP",
	[DA9052_ADC_VBBAT]	=	"BACK-UP BATTERY VOLTAGE",
};

/* Conversion function for VDDOUT and VBAT */
static inline int volt_reg_to_mv(int value)
{
	return DIV_ROUND_CLOSEST(value * 2000, 1023) + 2500;
}

/* Conversion function for ADC channels 4, 5 and 6 */
static inline int input_reg_to_mv(int value)
{
	return DIV_ROUND_CLOSEST(value * 2500, 1023);
}

/* Conversion function for VBBAT */
static inline int vbbat_reg_to_mv(int value)
{
	return DIV_ROUND_CLOSEST(value * 5000, 1023);
}

static inline int input_tsireg_to_mv(struct da9052_hwmon *hwmon, int value)
{
	return DIV_ROUND_CLOSEST(value * hwmon->tsiref_mv, 1023);
}

static inline int da9052_enable_vddout_channel(struct da9052 *da9052)
{
	return da9052_reg_update(da9052, DA9052_ADC_CONT_REG,
				 DA9052_ADCCONT_AUTOVDDEN,
				 DA9052_ADCCONT_AUTOVDDEN);
}

static inline int da9052_disable_vddout_channel(struct da9052 *da9052)
{
	return da9052_reg_update(da9052, DA9052_ADC_CONT_REG,
				 DA9052_ADCCONT_AUTOVDDEN, 0);
}

static ssize_t da9052_vddout_show(struct device *dev,
				  struct device_attribute *devattr, char *buf)
{
	struct da9052_hwmon *hwmon = dev_get_drvdata(dev);
	int ret, vdd;

	mutex_lock(&hwmon->hwmon_lock);

	ret = da9052_enable_vddout_channel(hwmon->da9052);
	if (ret < 0)
		goto hwmon_err;

	vdd = da9052_reg_read(hwmon->da9052, DA9052_VDD_RES_REG);
	if (vdd < 0) {
		ret = vdd;
		goto hwmon_err_release;
	}

	ret = da9052_disable_vddout_channel(hwmon->da9052);
	if (ret < 0)
		goto hwmon_err;

	mutex_unlock(&hwmon->hwmon_lock);
	return sprintf(buf, "%d\n", volt_reg_to_mv(vdd));

hwmon_err_release:
	da9052_disable_vddout_channel(hwmon->da9052);
hwmon_err:
	mutex_unlock(&hwmon->hwmon_lock);
	return ret;

Annotation

Implementation Notes