Commit ed645ccc authored by Andrey Gusakov's avatar Andrey Gusakov Committed by Lee Jones
Browse files

hwmon: MC13783: Add uid and die temperature sensor inputs



The uid and die temperature can be read out on the ADIN7 using
input mux. Map uid and die temperature sensor to channels 16
and 17.

Signed-off-by: default avatarAndrey Gusakov <andrey.gusakov@cogentembedded.com>
Acked-by: default avatarGuenter Roeck <linux@roeck-us.net>
Signed-off-by: default avatarLee Jones <lee.jones@linaro.org>
parent 60cc43fc
Loading
Loading
Loading
Loading
+60 −0
Original line number Diff line number Diff line
@@ -63,6 +63,10 @@ static int mc13783_adc_read(struct device *dev,
	if (ret)
		return ret;

	/* ADIN7 subchannels */
	if (channel >= 16)
		channel = 7;

	channel &= 0x7;

	*val = (sample[channel % 4] >> (channel > 3 ? 14 : 2)) & 0x3ff;
@@ -111,6 +115,57 @@ static ssize_t mc13783_adc_read_gp(struct device *dev,
	return sprintf(buf, "%u\n", val);
}

static ssize_t mc13783_adc_read_uid(struct device *dev,
		struct device_attribute *devattr, char *buf)
{
	unsigned int val;
	struct platform_device *pdev = to_platform_device(dev);
	kernel_ulong_t driver_data = platform_get_device_id(pdev)->driver_data;
	int ret = mc13783_adc_read(dev, devattr, &val);

	if (ret)
		return ret;

	if (driver_data & MC13783_ADC_BPDIV2)
		/* MC13892 have 1/2 divider, input range is [0, 4.800V] */
		val = DIV_ROUND_CLOSEST(val * 4800, 1024);
	else
		/* MC13783 have 0.9 divider, input range is [0, 2.555V] */
		val = DIV_ROUND_CLOSEST(val * 2555, 1024);

	return sprintf(buf, "%u\n", val);
}

static ssize_t mc13783_adc_read_temp(struct device *dev,
		struct device_attribute *devattr, char *buf)
{
	unsigned int val;
	struct platform_device *pdev = to_platform_device(dev);
	kernel_ulong_t driver_data = platform_get_device_id(pdev)->driver_data;
	int ret = mc13783_adc_read(dev, devattr, &val);

	if (ret)
		return ret;

	if (driver_data & MC13783_ADC_BPDIV2) {
		/*
		 * MC13892:
		 * Die Temperature Read Out Code at 25C 680
		 * Temperature change per LSB +0.4244C
		 */
		ret = DIV_ROUND_CLOSEST(-2635920 + val * 4244, 10);
	} else {
		/*
		 * MC13783:
		 * Die Temperature Read Out Code at 25C 282
		 * Temperature change per LSB -1.14C
		 */
		ret = 346480 - 1140 * val;
	}

	return sprintf(buf, "%d\n", ret);
}

static DEVICE_ATTR_RO(name);
static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, mc13783_adc_read_bp, NULL, 2);
static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, mc13783_adc_read_gp, NULL, 5);
@@ -124,6 +179,9 @@ static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, mc13783_adc_read_gp, NULL, 12);
static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, mc13783_adc_read_gp, NULL, 13);
static SENSOR_DEVICE_ATTR(in14_input, S_IRUGO, mc13783_adc_read_gp, NULL, 14);
static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, mc13783_adc_read_gp, NULL, 15);
static SENSOR_DEVICE_ATTR(in16_input, S_IRUGO, mc13783_adc_read_uid, NULL, 16);
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
			  mc13783_adc_read_temp, NULL, 17);

static struct attribute *mc13783_attr_base[] = {
	&dev_attr_name.attr,
@@ -131,6 +189,8 @@ static struct attribute *mc13783_attr_base[] = {
	&sensor_dev_attr_in5_input.dev_attr.attr,
	&sensor_dev_attr_in6_input.dev_attr.attr,
	&sensor_dev_attr_in7_input.dev_attr.attr,
	&sensor_dev_attr_in16_input.dev_attr.attr,
	&sensor_dev_attr_temp1_input.dev_attr.attr,
	NULL
};

+14 −1
Original line number Diff line number Diff line
@@ -279,8 +279,21 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode,
	adc0 = MC13XXX_ADC0_ADINC1 | MC13XXX_ADC0_ADINC2;
	adc1 = MC13XXX_ADC1_ADEN | MC13XXX_ADC1_ADTRIGIGN | MC13XXX_ADC1_ASC;

	if (channel > 7)
	/*
	 * Channels mapped through ADIN7:
	 * 7  - General purpose ADIN7
	 * 16 - UID
	 * 17 - Die temperature
	 */
	if (channel > 7 && channel < 16) {
		adc1 |= MC13XXX_ADC1_ADSEL;
	} else if (channel == 16) {
		adc0 |= MC13XXX_ADC0_ADIN7SEL_UID;
		channel = 7;
	} else if (channel == 17) {
		adc0 |= MC13XXX_ADC0_ADIN7SEL_DIE;
		channel = 7;
	}

	switch (mode) {
	case MC13XXX_ADC_MODE_TS:
+2 −0
Original line number Diff line number Diff line
@@ -243,6 +243,8 @@ struct mc13xxx_platform_data {
#define MC13XXX_ADC0_LICELLCON		(1 << 0)
#define MC13XXX_ADC0_CHRGICON		(1 << 1)
#define MC13XXX_ADC0_BATICON		(1 << 2)
#define MC13XXX_ADC0_ADIN7SEL_DIE	(1 << 4)
#define MC13XXX_ADC0_ADIN7SEL_UID	(2 << 4)
#define MC13XXX_ADC0_ADREFEN		(1 << 10)
#define MC13XXX_ADC0_TSMOD0		(1 << 12)
#define MC13XXX_ADC0_TSMOD1		(1 << 13)