diff --git a/target/linux/apm821xx/patches-4.4/901-hwmon-add-driver-for-Microchip-TC654-TC655-PWM-fan-c.patch b/target/linux/apm821xx/patches-4.4/901-hwmon-add-driver-for-Microchip-TC654-TC655-PWM-fan-c.patch
new file mode 100644
index 0000000..53b9bdb
--- /dev/null
+++ b/target/linux/apm821xx/patches-4.4/901-hwmon-add-driver-for-Microchip-TC654-TC655-PWM-fan-c.patch
@@ -0,0 +1,1037 @@
+From 5ea2e152d846bf60901107fefd81a58f792f3bc2 Mon Sep 17 00:00:00 2001
+From: Christian Lamparter <chunkeey@gmail.com>
+Date: Fri, 10 Jun 2016 03:00:46 +0200
+Subject: [PATCH] hwmon: add driver for Microchip TC654/TC655 PWM fan
+ controllers
+
+This patch adds a hwmon driver for the Microchip TC654 and TC655
+Dual SMBus PWM Fan Speed Controllers with Fan Fault detection.
+
+The chip is described in the DS2001734C Spec Document from Microchip.
+It supports:
+	- Shared PWM Fan Drive for two fans
+	- Provides RPM
+	- automatic PWM controller (needs additional
+	  NTC/PTC Thermistors.)
+	- Overtemperature alarm (when using NTC/PTC
+	  Thermistors)
+
+Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
+---
+ drivers/hwmon/Kconfig  |  10 +
+ drivers/hwmon/Makefile |   1 +
+ drivers/hwmon/tc654.c  | 969 +++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 980 insertions(+)
+ create mode 100644 drivers/hwmon/tc654.c
+
+diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
+index ff94007..941fe4951 100644
+--- a/drivers/hwmon/Kconfig
++++ b/drivers/hwmon/Kconfig
+@@ -1514,6 +1514,16 @@ config SENSORS_INA2XX
+ 	  This driver can also be built as a module.  If so, the module
+ 	  will be called ina2xx.
+ 
++config SENSORS_TC654
++	tristate "Microchip TC654 and TC655"
++	depends on I2C
++	help
++	  If you say yes here you get support for Microchip TC655 and TC654
++	  Dual PWM Fan Speed Controllers and sensor chips.
++
++	  This driver can also be built as a module.  If so, the module
++	  will be called tc654.
++
+ config SENSORS_TC74
+ 	tristate "Microchip TC74"
+ 	depends on I2C
+diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
+index 2ef5b7c..04270c7 100644
+--- a/drivers/hwmon/Makefile
++++ b/drivers/hwmon/Makefile
+@@ -145,6 +145,7 @@ obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
+ obj-$(CONFIG_SENSORS_SMSC47M1)	+= smsc47m1.o
+ obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
+ obj-$(CONFIG_SENSORS_AMC6821)	+= amc6821.o
++obj-$(CONFIG_SENSORS_TC654)	+= tc654.o
+ obj-$(CONFIG_SENSORS_TC74)	+= tc74.o
+ obj-$(CONFIG_SENSORS_THMC50)	+= thmc50.o
+ obj-$(CONFIG_SENSORS_TMP102)	+= tmp102.o
+diff --git a/drivers/hwmon/tc654.c b/drivers/hwmon/tc654.c
+new file mode 100644
+index 0000000..d584baf
+--- /dev/null
++++ b/drivers/hwmon/tc654.c
+@@ -0,0 +1,969 @@
++/*
++ * tc654.c - Support for Microchip TC654/TC655
++ * "A Dual SMBus PWM FAN Speed Controllers with Fan Fault Detection"
++ *
++ * Copyright (c) 2016 Christian Lamparter <chunkeey@gmail.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation version 2 of the License.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * The chip is described in the DS2001734C Spec Document from Microchip.
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/jiffies.h>
++#include <linux/i2c.h>
++#include <linux/hwmon.h>
++#include <linux/hwmon-sysfs.h>
++#include <linux/err.h>
++#include <linux/mutex.h>
++#include <linux/thermal.h>
++
++/* Hardware definitions */
++/* 5.1.4 Address Byte stats that TC654/TC655 are fixed at 0x1b */
++static const unsigned short normal_i2c[] = { 0x1b, I2C_CLIENT_END };
++
++enum TC654_REGS {
++	TC654_REG_RPM1 = 0x00,
++	TC654_REG_RPM2,
++	TC654_REG_FAN1_FAULT_THRESH,
++	TC654_REG_FAN2_FAULT_THRESH,
++	TC654_REG_CONFIG,
++	TC654_REG_STATUS,
++	TC654_REG_DUTY_CYCLE,
++	TC654_REG_MFR_ID,
++	TC654_REG_VER_ID,
++
++	/* keep last */
++	__TC654_REG_NUM,
++};
++
++#define TC654_MFR_ID_MICROCHIP		0x84
++#define TC654_VER_ID			0x00
++#define TC655_VER_ID			0x01
++
++enum TC654_CONTROL_BITS {
++	TC654_CTRL_SDM		= BIT(0),
++	TC654_CTRL_F1PPR_S	= 1,
++	TC654_CTRL_F1PPR_M	= (BIT(1) | BIT(2)),
++	TC654_CTRL_F2PPR_S	= 3,
++	TC654_CTRL_F2PPR_M	= (BIT(3) | BIT(4)),
++	TC654_CTRL_DUTYC	= BIT(5),
++	TC654_CTRL_RES		= BIT(6),
++	TC654_CTRL_FFCLR	= BIT(7),
++};
++
++enum TC654_STATUS_BITS {
++	TC654_STATUS_F1F	= BIT(0),
++	TC654_STATUS_F2F	= BIT(1),
++	TC654_STATUS_VSTAT	= BIT(2),
++	TC654_STATUS_R1CO	= BIT(3),
++	TC654_STATUS_R2CO	= BIT(4),
++	TC654_STATUS_OTF	= BIT(5),
++};
++
++enum TC654_FAN {
++	TC654_FAN1 = 0,
++	TC654_FAN2,
++
++	/* keep last */
++	__NUM_TC654_FAN,
++};
++
++enum TC654_FAN_MODE {
++	TC654_PWM_OFF,	/* Shutdown Mode - switch of both fans */
++	TC654_PWM_VIN,	/* Fans will be controlled via V_in analog input pin */
++	TC654_PWM_3000,	/* sets fans to 30% duty cycle */
++	TC654_PWM_3467,
++	TC654_PWM_3933, /* default case - if V_in pin is open */
++	TC654_PWM_4400,
++	TC654_PWM_4867,
++	TC654_PWM_5333,
++	TC654_PWM_5800,
++	TC654_PWM_6267,
++	TC654_PWM_6733,
++	TC654_PWM_7200,
++	TC654_PWM_7667,
++	TC654_PWM_8133,
++	TC654_PWM_8600,
++	TC654_PWM_9067,
++	TC654_PWM_9533,
++	TC654_PWM_10000, /* sets fans to 100% duty cycle */
++};
++
++enum TC654_ALARMS {
++	TC654_ALARM_FAN1_FAULT,
++	TC654_ALARM_FAN2_FAULT,
++	TC654_ALARM_FAN1_COUNTER_OVERFLOW,
++	TC654_ALARM_FAN2_COUNTER_OVERFLOW,
++	TC654_ALARM_OVER_TEMPERATURE,
++
++	/* KEEP LAST */
++	__NUM_TC654_ALARMS,
++};
++
++static const struct pwm_table_entry {
++	u8 min;
++	enum TC654_FAN_MODE mode;
++} pwm_table[] = {
++	{  0, TC654_PWM_OFF  },
++	{  1, TC654_PWM_3000 },
++	{ 88, TC654_PWM_3467 },
++	{101, TC654_PWM_3933 },
++	{113, TC654_PWM_4400 },
++	{125, TC654_PWM_4867 },
++	{137, TC654_PWM_5333 },
++	{148, TC654_PWM_5800 },
++	{160, TC654_PWM_6267 },
++	{172, TC654_PWM_6733 },
++	{184, TC654_PWM_7200 },
++	{196, TC654_PWM_7667 },
++	{208, TC654_PWM_8133 },
++	{220, TC654_PWM_8600 },
++	{232, TC654_PWM_9067 },
++	{244, TC654_PWM_9533 },
++	{255, TC654_PWM_10000 },
++};
++
++/* driver context */
++struct tc654 {
++	struct i2c_client	*client;
++
++	struct mutex		update_lock;
++
++	unsigned long		last_updated;	/* in jiffies */
++	u8			cached_regs[__TC654_REG_NUM];
++
++	bool			valid;	/* monitored registers are valid */
++	u16			fan_input[__NUM_TC654_FAN];
++	bool			alarms[__NUM_TC654_ALARMS];
++	bool			vin_status;
++	bool			pwm_manual;
++
++	/* optional cooling device */
++	struct thermal_cooling_device *cdev;
++};
++
++/* hardware accessors and functions */
++static int read_tc(struct tc654 *tc, u8 reg)
++{
++	s32 status;
++
++	if (reg <= TC654_REG_VER_ID) {
++		/* Table 6.1 states that all registers are readable */
++		status = i2c_smbus_read_byte_data(tc->client, reg);
++	} else
++		status = -EINVAL;
++
++	if (status < 0) {
++		dev_warn(&tc->client->dev, "can't read register 0x%02x due to error (%d)",
++			 reg, status);
++	} else {
++		tc->cached_regs[reg] = status;
++	}
++
++	return status;
++}
++
++static int write_tc(struct tc654 *tc, u8 i2c_reg, u8 val)
++{
++	s32 status;
++
++	/*
++	 * Table 6.1 states that both fan threshold registers,
++	 * the Config and Duty Cycle are writeable.
++	 */
++	switch (i2c_reg) {
++	case TC654_REG_FAN1_FAULT_THRESH:
++	case TC654_REG_FAN2_FAULT_THRESH:
++	case TC654_REG_DUTY_CYCLE:
++	case TC654_REG_CONFIG:
++		status = i2c_smbus_write_byte_data(tc->client, i2c_reg, val);
++		break;
++
++	default:
++		return -EINVAL;
++	}
++
++	if (status < 0) {
++		dev_warn(&tc->client->dev, "can't write register 0x%02x with value 0x%02x due to error (%d)",
++			 i2c_reg, val, status);
++	} else {
++		tc->cached_regs[i2c_reg] = val;
++	}
++
++	return status;
++}
++
++static int mod_config(struct tc654 *tc, u8 set, u8 clear)
++{
++	u8 val = 0;
++
++	/* a bit can't be set and cleared on the same time. */
++	if (set & clear)
++		return -EINVAL;
++
++	/* invalidate data to force re-read from hardware */
++	tc->valid = false;
++	val = (tc->cached_regs[TC654_REG_CONFIG] | set) & (~clear);
++	return write_tc(tc, TC654_REG_CONFIG, val);
++}
++
++static int read_fan_rpm(struct tc654 *tc, enum TC654_FAN fan)
++{
++	int ret;
++
++	/* 6.1 RPM-OUTPUT1 and RPM-OUTPUT2 registers */
++	ret = read_tc(tc, fan == TC654_FAN1 ? TC654_REG_RPM1 : TC654_REG_RPM2);
++	if (ret < 0)
++		return ret;
++
++	/*
++	 * The Resolution Selection Bit in 6.3 CONFIGURATION REGISTER
++	 * is needed to convert the raw value to the RPM.
++	 * 0 = RPM1 and RPM2 use (8-Bit) resolution => * 50 RPM
++	 * 1 = RPM1 and RPM2 use (9-Bit) resolution => * 25 RPM
++	 */
++	return ret * (25 <<
++		!(tc->cached_regs[TC654_REG_CONFIG] & TC654_CTRL_RES));
++}
++
++static int write_fan_fault_thresh(struct tc654 *tc, enum TC654_FAN fan,
++				  u16 rpm)
++{
++	u8 converted_rpm;
++
++	if (rpm > 12750)
++		return -EINVAL;
++
++	/*
++	 * 6.2 FAN_FAULT1 and FAN_FAULT2 Threshold registers
++	 *
++	 * Both registers operate in 50 RPM mode exclusively.
++	 */
++	converted_rpm = rpm / 50;
++
++	/* invalidate data to force re-read from hardware */
++	tc->valid = false;
++	return write_tc(tc, fan == TC654_FAN1 ? TC654_REG_FAN1_FAULT_THRESH :
++		TC654_REG_FAN2_FAULT_THRESH, converted_rpm);
++}
++
++
++static int read_fan_fault_thresh(struct tc654 *tc, enum TC654_FAN fan)
++{
++	/*
++	 * 6.2 FAN_FAULT1 and FAN_FAULT2 Threshold registers
++	 *
++	 * Both registers operate in 50 RPM mode exclusively.
++	 */
++	return read_tc(tc, fan == TC654_FAN1 ? TC654_REG_FAN1_FAULT_THRESH :
++		TC654_REG_FAN2_FAULT_THRESH) * 50;
++}
++
++static enum TC654_FAN_MODE get_fan_mode(struct tc654 *tc)
++{
++	if (tc->cached_regs[TC654_REG_CONFIG] & TC654_CTRL_SDM) {
++		return TC654_PWM_OFF;
++	} else if (tc->cached_regs[TC654_REG_CONFIG] & TC654_CTRL_DUTYC) {
++		return TC654_PWM_3000 + tc->cached_regs[TC654_REG_DUTY_CYCLE];
++	} else if (tc->vin_status == 0)
++		return TC654_PWM_VIN;
++
++	return -EINVAL;
++}
++
++static int write_fan_mode(struct tc654 *tc, enum TC654_FAN_MODE mode)
++{
++	int err;
++	u8 pwm_mode;
++	bool in_sdm;
++
++	in_sdm = !!(tc->cached_regs[TC654_REG_CONFIG] &
++		TC654_CTRL_SDM);
++
++	switch (mode) {
++	case TC654_PWM_OFF:
++		if (in_sdm)
++			return 0;
++
++		/* Enter Shutdown Mode - Switches off all fans */
++		err = mod_config(tc, TC654_CTRL_SDM, TC654_CTRL_DUTYC);
++		if (err)
++			return err;
++
++		return 0;
++
++	case TC654_PWM_VIN:
++		if (tc->vin_status) {
++			dev_err(&tc->client->dev,
++				"V_in pin is open, can't enable automatic mode.");
++			return -EINVAL;
++		}
++
++		err = mod_config(tc, 0, TC654_CTRL_SDM | TC654_CTRL_DUTYC);
++		if (err)
++			return err;
++
++		tc->pwm_manual = false;
++		return 0;
++
++	case TC654_PWM_3000:
++	case TC654_PWM_3467:
++	case TC654_PWM_3933:
++	case TC654_PWM_4400:
++	case TC654_PWM_4867:
++	case TC654_PWM_5333:
++	case TC654_PWM_5800:
++	case TC654_PWM_6267:
++	case TC654_PWM_6733:
++	case TC654_PWM_7200:
++	case TC654_PWM_7667:
++	case TC654_PWM_8133:
++	case TC654_PWM_8600:
++	case TC654_PWM_9067:
++	case TC654_PWM_9533:
++	case TC654_PWM_10000:
++		pwm_mode = mode - TC654_PWM_3000;
++		if (!in_sdm) {
++			err = write_tc(tc, TC654_REG_DUTY_CYCLE, pwm_mode);
++			if (err)
++				return err;
++		}
++
++		err = mod_config(tc, TC654_CTRL_DUTYC, TC654_CTRL_SDM);
++		if (err)
++			return err;
++
++		tc->pwm_manual = true;
++
++		if (in_sdm) {
++			/*
++			 * In case the TC654/TC655 was in SDM mode, the write
++			 * above into the TC654_REG_DUTY_CYCLE register will
++			 * have no effect because the chip was switched off.
++			 *
++			 * Note: The TC654/TC655 have a special "power-on"
++			 * feature where the PWM will be forced to 100% for
++			 * one full second in order to spin-up a resting fan.
++			 */
++			err = write_tc(tc, TC654_REG_DUTY_CYCLE, pwm_mode);
++			if (err)
++				return err;
++		}
++
++		return 0;
++
++	default:
++		return -EINVAL;
++	}
++}
++
++static struct tc654 *tc654_update_device(struct device *dev)
++{
++	struct tc654 *tc = dev_get_drvdata(dev);
++
++	mutex_lock(&tc->update_lock);
++
++	/*
++	 * In Chapter "1.0 Electrical Characteristics",
++	 * the "Fault Output Response Time" is specified as 2.4 seconds.
++	 */
++	if (time_after(jiffies, tc->last_updated + 2 * HZ + (HZ * 2) / 5)
++	    || !tc->valid) {
++		size_t i;
++		int ret;
++		bool alarm_triggered;
++
++		tc->valid = false;
++
++		for (i = 0; i < __NUM_TC654_FAN; i++) {
++			ret = read_fan_rpm(tc, i);
++			if (ret < 0)
++				goto out;
++
++			tc->fan_input[i] = ret;
++		}
++
++		ret = read_tc(tc, TC654_REG_STATUS);
++		if (ret < 0)
++			goto out;
++
++		alarm_triggered = !!(ret & (TC654_STATUS_F1F |
++			TC654_STATUS_F2F | TC654_STATUS_R1CO |
++			TC654_STATUS_R2CO | TC654_STATUS_OTF));
++
++		tc->alarms[TC654_ALARM_FAN1_FAULT] = !!(ret & TC654_STATUS_F1F);
++		tc->alarms[TC654_ALARM_FAN2_FAULT] = !!(ret & TC654_STATUS_F2F);
++		tc->alarms[TC654_ALARM_FAN1_COUNTER_OVERFLOW] =
++			!!(ret & TC654_STATUS_R1CO);
++		tc->alarms[TC654_ALARM_FAN2_COUNTER_OVERFLOW] =
++			!!(ret & TC654_STATUS_R2CO);
++		tc->alarms[TC654_ALARM_OVER_TEMPERATURE] =
++			!!(ret & TC654_STATUS_OTF);
++		tc->vin_status = !!(ret & TC654_STATUS_VSTAT);
++
++		/*
++		 * From 4.5 and 6.3
++		 *
++		 * ... "If the V_in pin is open when TC654_CTRL_DUTYC is not
++		 * selected, then V_out duty cycle will default to 39.33%.".
++		 *
++		 * and most importantly 6.5:
++		 * ... "V_in pin is open, the duty cycle will go to the default
++		 * setting of this register, which is 0010 (39.33%)."
++		 */
++		tc->pwm_manual |= tc->vin_status &&
++			(tc->cached_regs[TC654_REG_CONFIG] &
++			 TC654_CTRL_DUTYC);
++
++		if (alarm_triggered) {
++			/*
++			 * as the name implies, this FLAG needs to be
++			 * set in order to clear the FAN Fault error.
++			 */
++			ret = mod_config(tc, TC654_CTRL_FFCLR, 0);
++			if (ret < 0)
++				goto out;
++		}
++
++		tc->last_updated = jiffies;
++		tc->valid = true;
++	}
++
++out:
++	mutex_unlock(&tc->update_lock);
++	return tc;
++}
++
++static u8 get_fan_pulse(struct tc654 *tc, enum TC654_FAN fan)
++{
++	u8 fan_pulse_mask = fan == TC654_FAN1 ?
++		TC654_CTRL_F1PPR_M : TC654_CTRL_F2PPR_M;
++	u8 fan_pulse_shift = fan  == TC654_FAN1 ?
++		TC654_CTRL_F1PPR_S : TC654_CTRL_F2PPR_S;
++
++	return 1 << ((tc->cached_regs[TC654_REG_CONFIG] & fan_pulse_mask) >>
++		     fan_pulse_shift);
++}
++
++static int
++set_fan_pulse(struct tc654 *tc, enum TC654_FAN fan, int pulses)
++{
++	int old_pulses;
++	int err;
++	u8 new_pulse_per_rotation;
++	u8 fan_pulse_mask = fan == TC654_FAN1 ?
++		TC654_CTRL_F1PPR_M : TC654_CTRL_F2PPR_M;
++	u8 fan_pulse_shift = fan  == TC654_FAN1 ?
++		TC654_CTRL_F1PPR_S : TC654_CTRL_F2PPR_S;
++
++	switch (pulses) {
++	case 1:
++		new_pulse_per_rotation = 0;
++		break;
++	case 2:
++		new_pulse_per_rotation = 1;
++		break;
++	case 4:
++		new_pulse_per_rotation = 2;
++		break;
++	case 8:
++		new_pulse_per_rotation = 3;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	new_pulse_per_rotation <<= fan_pulse_shift;
++	new_pulse_per_rotation &= fan_pulse_mask;
++
++	old_pulses = tc->cached_regs[TC654_REG_CONFIG];
++	old_pulses &= fan_pulse_mask;
++
++	if (new_pulse_per_rotation == old_pulses)
++		return 0;
++
++	mutex_lock(&tc->update_lock);
++	err = mod_config(tc, new_pulse_per_rotation,
++			    old_pulses & (~new_pulse_per_rotation));
++	mutex_unlock(&tc->update_lock);
++
++	/* invalidate RPM data to force re-read from hardware */
++	tc->valid = false;
++
++	return err;
++}
++
++static int get_fan_speed(struct tc654 *tc)
++{
++	enum TC654_FAN_MODE mode;
++	size_t i;
++
++	mode = get_fan_mode(tc);
++	for (i = 0; i < ARRAY_SIZE(pwm_table); i++) {
++		if (mode == pwm_table[i].mode)
++			return pwm_table[i].min;
++	}
++
++	return -EINVAL;
++}
++
++static int set_fan_speed(struct tc654 *tc, int new_value)
++{
++	int result;
++	size_t i;
++
++	if (new_value > pwm_table[ARRAY_SIZE(pwm_table) - 1].min ||
++	    new_value < pwm_table[0].min)
++		return -EINVAL;
++
++	for (i = 0; i < ARRAY_SIZE(pwm_table); i++) {
++		/* exact match */
++		if (pwm_table[i].min == new_value)
++			break;
++
++		/* a little bit too big - go with the previous entry */
++		if (pwm_table[i].min > new_value) {
++			--i;
++			break;
++		}
++	}
++
++	mutex_lock(&tc->update_lock);
++	result = write_fan_mode(tc, pwm_table[i].mode);
++	mutex_unlock(&tc->update_lock);
++	if (result < 0)
++		return result;
++
++	return 0;
++}
++
++/* sysfs */
++
++static ssize_t
++show_fan_input(struct device *dev, struct device_attribute *da, char *buf)
++{
++	struct tc654 *tc = tc654_update_device(dev);
++	int nr = to_sensor_dev_attr(da)->index;
++
++	return sprintf(buf, "%d\n", tc->fan_input[nr]);
++}
++
++static ssize_t
++show_fan_min(struct device *dev, struct device_attribute *da, char *buf)
++{
++	struct tc654 *tc = dev_get_drvdata(dev);
++	int nr = to_sensor_dev_attr(da)->index;
++
++	return sprintf(buf, "%d\n", read_fan_fault_thresh(tc, nr));
++}
++
++static ssize_t
++show_fan_min_alarm(struct device *dev, struct device_attribute *da, char *buf)
++{
++	struct tc654 *tc = tc654_update_device(dev);
++	int nr = to_sensor_dev_attr(da)->index;
++
++	return sprintf(buf, "%d\n", nr == TC654_FAN1 ?
++		       tc->alarms[TC654_ALARM_FAN1_FAULT] :
++		       tc->alarms[TC654_ALARM_FAN2_FAULT]);
++}
++
++static ssize_t
++show_fan_max_alarm(struct device *dev, struct device_attribute *da, char *buf)
++{
++	struct tc654 *tc = tc654_update_device(dev);
++	int nr = to_sensor_dev_attr(da)->index;
++
++	return sprintf(buf, "%d\n", nr == TC654_FAN1 ?
++		       tc->alarms[TC654_ALARM_FAN1_COUNTER_OVERFLOW] :
++		       tc->alarms[TC654_ALARM_FAN2_COUNTER_OVERFLOW]);
++}
++
++static ssize_t
++set_fan_min(struct device *dev, struct device_attribute *da,
++	    const char *buf, size_t count)
++{
++	struct tc654 *tc = dev_get_drvdata(dev);
++	long new_min;
++	int nr = to_sensor_dev_attr(da)->index;
++	int old_min = read_fan_fault_thresh(tc, nr);
++	int status = kstrtol(buf, 10, &new_min);
++
++	if (status < 0)
++		return status;
++
++	new_min = (new_min / 50) * 50;
++	if (new_min == old_min) /* No change */
++		return count;
++
++	if (new_min < 0 || new_min > 12750)
++		return -EINVAL;
++
++	mutex_lock(&tc->update_lock);
++	status = write_fan_fault_thresh(tc, nr, new_min);
++	mutex_unlock(&tc->update_lock);
++	return count;
++}
++
++static ssize_t
++show_fan_max(struct device *dev, struct device_attribute *da, char *buf)
++{
++	struct tc654 *tc = dev_get_drvdata(dev);
++	int max_rpm = tc->cached_regs[TC654_REG_CONFIG] & TC654_CTRL_RES ?
++		(((1 << 9) - 1) * 25) /* ((2**9) - 1) * 25 RPM */:
++		(((1 << 8) - 1) * 50) /* ((2**8) - 1) * 50 RPM */;
++
++	return sprintf(buf, "%d\n", max_rpm);
++}
++
++static ssize_t
++show_fan_fault(struct device *dev, struct device_attribute *da, char *buf)
++{
++	struct tc654 *tc = tc654_update_device(dev);
++	int nr = to_sensor_dev_attr(da)->index;
++	u8 fan_fault_mask = nr == TC654_FAN1 ?
++		TC654_STATUS_F1F : TC654_STATUS_F2F;
++
++	return sprintf(buf, "%d\n",
++		!!(tc->cached_regs[TC654_REG_STATUS] & fan_fault_mask));
++}
++
++static ssize_t
++show_fan_pulses(struct device *dev, struct device_attribute *da, char *buf)
++{
++	struct tc654 *tc = dev_get_drvdata(dev);
++	int nr = to_sensor_dev_attr(da)->index;
++
++	return sprintf(buf, "%d\n", get_fan_pulse(tc, nr));
++}
++
++static ssize_t
++set_fan_pulses(struct device *dev, struct device_attribute *da,
++	      const char *buf, size_t count)
++{
++	struct tc654 *tc = dev_get_drvdata(dev);
++	long new_pulse;
++	int nr = to_sensor_dev_attr(da)->index;
++	int status = kstrtol(buf, 10, &new_pulse);
++
++	if (status < 0)
++		return status;
++
++	status = set_fan_pulse(tc, nr, new_pulse);
++	if (status < 0)
++		return status;
++
++	return count;
++}
++
++static ssize_t
++show_pwm_enable(struct device *dev, struct device_attribute *da, char *buf)
++{
++	struct tc654 *tc = tc654_update_device(dev);
++	int pwm_enabled;
++
++	if ((tc->cached_regs[TC654_REG_CONFIG] & TC654_CTRL_SDM) &&
++	    !tc->pwm_manual) {
++		pwm_enabled = 0; /* full off */
++	} else {
++		if (tc->valid && tc->vin_status == 0)
++			pwm_enabled = 2; /* automatic fan speed control */
++
++		pwm_enabled = 1; /* PWM Mode */
++	}
++
++	return sprintf(buf, "%d\n", pwm_enabled);
++}
++
++static ssize_t
++set_pwm_enable(struct device *dev, struct device_attribute *da,
++	       const char *buf, size_t count)
++{
++	struct tc654 *tc = dev_get_drvdata(dev);
++	long new_value;
++
++	int result = kstrtol(buf, 10, &new_value);
++
++	if (result < 0)
++		return result;
++
++	mutex_lock(&tc->update_lock);
++	switch (new_value) {
++	case 0: /* no fan control (i.e. is OFF) */
++		result = write_fan_mode(tc, TC654_PWM_OFF);
++		tc->pwm_manual = false;
++		break;
++
++	case 1: /* manual fan control enabled (using pwm) */
++		result = write_fan_mode(tc, TC654_PWM_10000);
++		break;
++
++	case 2: /* automatic fan speed control enabled */
++		result = write_fan_mode(tc, TC654_PWM_VIN);
++		break;
++
++	default:
++		result = -EINVAL;
++	}
++
++	mutex_unlock(&tc->update_lock);
++	return result < 0 ? result : count;
++}
++
++static ssize_t
++show_pwm(struct device *dev, struct device_attribute *da, char *buf)
++{
++	struct tc654 *tc = tc654_update_device(dev);
++	int ret;
++
++	ret = get_fan_speed(tc);
++	if (ret < 0)
++		return ret;
++
++	return sprintf(buf, "%d\n", ret);
++}
++
++static ssize_t
++set_pwm(struct device *dev, struct device_attribute *da,
++	const char *buf, size_t count)
++{
++	struct tc654 *tc = dev_get_drvdata(dev);
++	long new_value = -1;
++	int result = kstrtol(buf, 10, &new_value);
++
++	if (result < 0)
++		return result;
++
++	if (new_value < 0 || new_value > INT_MAX)
++		return -EINVAL;
++
++	if (!tc->pwm_manual)
++		return -EINVAL;
++
++	result = set_fan_speed(tc, new_value);
++	if (result < 0)
++		return result;
++
++	return count;
++}
++
++static ssize_t
++show_temp_alarm_otf(struct device *dev, struct device_attribute *da, char *buf)
++{
++	struct tc654 *tc = tc654_update_device(dev);
++
++	return sprintf(buf, "%d\n", tc->alarms[TC654_ALARM_OVER_TEMPERATURE]);
++}
++
++static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input,
++			  NULL, TC654_FAN1);
++static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO | S_IWUSR, show_fan_min,
++			  set_fan_min, TC654_FAN1);
++static SENSOR_DEVICE_ATTR(fan1_min_alarm, S_IRUGO, show_fan_min_alarm,
++			  NULL, TC654_FAN1);
++static SENSOR_DEVICE_ATTR(fan1_max_alarm, S_IRUGO, show_fan_max_alarm,
++			  NULL, TC654_FAN1);
++static SENSOR_DEVICE_ATTR(fan1_max, S_IRUGO, show_fan_max, NULL, TC654_FAN1);
++static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, show_fan_fault,
++			  NULL, TC654_FAN1);
++static SENSOR_DEVICE_ATTR(fan1_pulses, S_IRUGO | S_IWUSR, show_fan_pulses,
++			  set_fan_pulses, TC654_FAN1);
++static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input,
++			  NULL, TC654_FAN2);
++static SENSOR_DEVICE_ATTR(fan2_min, S_IRUGO | S_IWUSR, show_fan_min,
++			  set_fan_min, TC654_FAN2);
++static SENSOR_DEVICE_ATTR(fan2_max, S_IRUGO, show_fan_max,
++			  NULL, TC654_FAN2);
++static SENSOR_DEVICE_ATTR(fan2_min_alarm, S_IRUGO, show_fan_min_alarm,
++			  NULL, TC654_FAN2);
++static SENSOR_DEVICE_ATTR(fan2_max_alarm, S_IRUGO, show_fan_max_alarm,
++			  NULL, TC654_FAN2);
++static SENSOR_DEVICE_ATTR(fan2_fault, S_IRUGO, show_fan_fault,
++			  NULL, TC654_FAN2);
++static SENSOR_DEVICE_ATTR(fan2_pulses, S_IRUGO | S_IWUSR, show_fan_pulses,
++			  set_fan_pulses, TC654_FAN2);
++
++static DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, show_pwm_enable,
++	set_pwm_enable);
++static DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm);
++
++static DEVICE_ATTR(temp1_emergency_alarm, S_IRUGO, show_temp_alarm_otf, NULL);
++
++/* sensors present on all models */
++static struct attribute *tc654_attrs[] = {
++	&sensor_dev_attr_fan1_input.dev_attr.attr,
++	&sensor_dev_attr_fan1_min.dev_attr.attr,
++	&sensor_dev_attr_fan1_max.dev_attr.attr,
++	&sensor_dev_attr_fan1_min_alarm.dev_attr.attr,
++	&sensor_dev_attr_fan1_max_alarm.dev_attr.attr,
++	&sensor_dev_attr_fan1_fault.dev_attr.attr,
++	&sensor_dev_attr_fan1_pulses.dev_attr.attr,
++	&sensor_dev_attr_fan2_input.dev_attr.attr,
++	&sensor_dev_attr_fan2_min.dev_attr.attr,
++	&sensor_dev_attr_fan2_max.dev_attr.attr,
++	&sensor_dev_attr_fan2_min_alarm.dev_attr.attr,
++	&sensor_dev_attr_fan2_max_alarm.dev_attr.attr,
++	&sensor_dev_attr_fan2_fault.dev_attr.attr,
++	&sensor_dev_attr_fan2_pulses.dev_attr.attr,
++
++	&dev_attr_pwm1_enable.attr,
++	&dev_attr_pwm1.attr,
++
++	&dev_attr_temp1_emergency_alarm.attr,
++	NULL
++};
++
++ATTRIBUTE_GROUPS(tc654);
++
++/* cooling device */
++
++static int tc654_get_max_state(struct thermal_cooling_device *cdev,
++			       unsigned long *state)
++{
++	*state = 255;
++	return 0;
++}
++
++static int tc654_get_cur_state(struct thermal_cooling_device *cdev,
++			       unsigned long *state)
++{
++	struct tc654 *tc = cdev->devdata;
++	int ret;
++
++	if (!tc)
++		return -EINVAL;
++
++	ret = get_fan_speed(tc);
++	if (ret < 0)
++		return ret;
++
++	*state = ret;
++	return 0;
++}
++
++static int tc654_set_cur_state(struct thermal_cooling_device *cdev,
++			       unsigned long state)
++{
++	struct tc654 *tc = cdev->devdata;
++
++	if (!tc)
++		return -EINVAL;
++
++	if (state > INT_MAX)
++		return -EINVAL;
++
++	return set_fan_speed(tc, state);
++}
++
++static const struct thermal_cooling_device_ops tc654_fan_cool_ops = {
++	.get_max_state = tc654_get_max_state,
++	.get_cur_state = tc654_get_cur_state,
++	.set_cur_state = tc654_set_cur_state,
++};
++
++
++/* hardware probe and detection */
++
++static int
++tc654_probe(struct i2c_client *client, const struct i2c_device_id *id)
++{
++	struct tc654 *tc;
++	struct device *hwmon_dev;
++	int ret, i;
++
++	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
++		return -EIO;
++
++	tc = devm_kzalloc(&client->dev, sizeof(*tc), GFP_KERNEL);
++	if (!tc)
++		return -ENOMEM;
++
++	i2c_set_clientdata(client, tc);
++	tc->client = client;
++	mutex_init(&tc->update_lock);
++
++	/* cache all 8 registers */
++	for (i = 0; i < __TC654_REG_NUM; i++) {
++		ret = read_tc(tc, i);
++		if (ret < 0)
++			return ret;
++	}
++
++	/* sysfs hooks */
++	hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev,
++							   client->name, tc,
++							   tc654_groups);
++	if (IS_ERR(hwmon_dev))
++		return PTR_ERR(hwmon_dev);
++
++#if IS_ENABLED(CONFIG_OF)
++	/* Optional cooling device register for Device tree platforms */
++	tc->cdev = thermal_of_cooling_device_register(client->dev.of_node,
++						      "tc654", tc,
++						      &tc654_fan_cool_ops);
++#else /* CONFIG_OF */
++	/* Optional cooling device register for non Device tree platforms */
++	tc->cdev = thermal_cooling_device_register("tc654", tc,
++						   &tc654_fan_cool_ops);
++#endif /* CONFIG_OF */
++
++	dev_info(&client->dev, "%s: sensor '%s'\n",
++		 dev_name(hwmon_dev), client->name);
++
++	return 0;
++}
++
++static const struct i2c_device_id tc654_ids[] = {
++	{ "tc654", 0, },
++	{ }
++};
++MODULE_DEVICE_TABLE(i2c, tc654_ids);
++
++/* Return 0 if detection is successful, -ENODEV otherwise */
++static int
++tc654_detect(struct i2c_client *new_client, struct i2c_board_info *info)
++{
++	struct i2c_adapter *adapter = new_client->adapter;
++	int manufacturer, product;
++
++	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
++		return -ENODEV;
++
++	manufacturer = i2c_smbus_read_byte_data(new_client, TC654_REG_MFR_ID);
++	if (manufacturer != TC654_MFR_ID_MICROCHIP)
++		return -ENODEV;
++
++	product = i2c_smbus_read_byte_data(new_client, TC654_REG_VER_ID);
++	if (!((product == TC654_VER_ID) || (product == TC655_VER_ID)))
++		return -ENODEV;
++
++	strlcpy(info->type, "tc654", I2C_NAME_SIZE);
++	return 0;
++}
++
++static struct i2c_driver tc654_driver = {
++	.class		= I2C_CLASS_HWMON,
++	.driver = {
++		.name	= "tc654",
++	},
++	.probe		= tc654_probe,
++	.id_table	= tc654_ids,
++	.detect		= tc654_detect,
++	.address_list	= normal_i2c,
++};
++
++module_i2c_driver(tc654_driver);
++
++MODULE_AUTHOR("Christian Lamparter <chunkeey@gmail.com>");
++MODULE_DESCRIPTION("Microchip TC654/TC655 hwmon driver");
++MODULE_LICENSE("GPL");
+-- 
+2.8.1
+
