/*
* abituguru3.c
*
* Copyright (c) 2006-2008 Hans de Goede <hdegoede@redhat.com>
* Copyright (c) 2008 Alistair John Strachan <alistair@devzero.co.uk>
*
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This driver supports the sensor part of revision 3 of the custom Abit uGuru
* chip found on newer Abit uGuru motherboards. Note: because of lack of specs
* only reading the sensors and their settings is supported.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/mutex.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/dmi.h>
#include <linux/io.h>
/* uGuru3 bank addresses */
#define ABIT_UGURU3_SETTINGS_BANK 0x01
#define ABIT_UGURU3_SENSORS_BANK 0x08
#define ABIT_UGURU3_MISC_BANK 0x09
#define ABIT_UGURU3_ALARMS_START 0x1E
#define ABIT_UGURU3_SETTINGS_START 0x24
#define ABIT_UGURU3_VALUES_START 0x80
#define ABIT_UGURU3_BOARD_ID 0x0A
/* uGuru3 sensor bank flags */ /* Alarm if: */
#define ABIT_UGURU3_TEMP_HIGH_ALARM_ENABLE 0x01 /* temp over warn */
#define ABIT_UGURU3_VOLT_HIGH_ALARM_ENABLE 0x02 /* volt over max */
#define ABIT_UGURU3_VOLT_LOW_ALARM_ENABLE 0x04 /* volt under min */
#define ABIT_UGURU3_TEMP_HIGH_ALARM_FLAG 0x10 /* temp is over warn */
#define ABIT_UGURU3_VOLT_HIGH_ALARM_FLAG 0x20 /* volt is over max */
#define ABIT_UGURU3_VOLT_LOW_ALARM_FLAG 0x40 /* volt is under min */
#define ABIT_UGURU3_FAN_LOW_ALARM_ENABLE 0x01 /* fan under min */
#define ABIT_UGURU3_BEEP_ENABLE 0x08 /* beep if alarm */
#define ABIT_UGURU3_SHUTDOWN_ENABLE 0x80 /* shutdown if alarm */
/* sensor types */
#define ABIT_UGURU3_IN_SENSOR 0
#define ABIT_UGURU3_TEMP_SENSOR 1
#define ABIT_UGURU3_FAN_SENSOR 2
/*
* Timeouts / Retries, if these turn out to need a lot of fiddling we could
* convert them to params. Determined by trial and error. I assume this is
* cpu-speed independent, since the ISA-bus and not the CPU should be the
* bottleneck.
*/
#define ABIT_UGURU3_WAIT_TIMEOUT 250
/*
* Normally the 0xAC at the end of synchronize() is reported after the
* first read, but sometimes not and we need to poll
*/
#define ABIT_UGURU3_SYNCHRONIZE_TIMEOUT 5
/* utility macros */
#define ABIT_UGURU3_NAME "abituguru3"
#define ABIT_UGURU3_DEBUG(format, arg...) \
if (verbose) \
printk(KERN_DEBUG ABIT_UGURU3_NAME ": " format , ## arg)
/* Macros to help calculate the sysfs_names array length */
#define ABIT_UGURU3_MAX_NO_SENSORS 26
/*
* sum of strlen +1 of: in??_input\0, in??_{min,max}\0, in??_{min,max}_alarm\0,
* in??_{min,max}_alarm_enable\0, in??_beep\0, in??_shutdown\0, in??_label\0
*/
#define ABIT_UGURU3_IN_NAMES_LENGTH \
(11 + 2 * 9 + 2 * 15 + 2 * 22 + 10 + 14 + 11)
/*
* sum of strlen +1 of: temp??_input\0, temp??_max\0, temp??_crit\0,
* temp??_alarm\0, temp??_alarm_enable\0, temp??_beep\0, temp??_shutdown\0,
* temp??_label\0
*/
#define ABIT_UGURU3_TEMP_NAMES_LENGTH (13 + 11 + 12 + 13 + 20 + 12 + 16 + 13)
/*
* sum of strlen +1 of: fan??_input\0, fan??_min\0, fan??_alarm\0,
* fan??_alarm_enable\0, fan??_beep\0, fan??_shutdown\0, fan??_label\0
*/
#define ABIT_UGURU3_FAN_NAMES_LENGTH (12 + 10 + 12 + 19 + 11 + 15 + 12)
/*
* Worst case scenario 16 in sensors (longest names_length) and the rest
* temp sensors (second longest names_length).
*/
#define ABIT_UGURU3_SYSFS_NAMES_LENGTH (16 * ABIT_UGURU3_IN_NAMES_LENGTH + \
(ABIT_UGURU3_MAX_NO_SENSORS - 16) * ABIT_UGURU3_TEMP_NAMES_LENGTH)
/*
* All the macros below are named identical to the openguru2 program
* reverse engineered by Louis Kruger, hence the names might not be 100%
* logical. I could come up with better names, but I prefer keeping the names
* identical so that this driver can be compared with his work more easily.
*/
/* Two i/o-ports are used by uGuru */
#define ABIT_UGURU3_BASE 0x00E0
#define ABIT_UGURU3_CMD 0x00
#define ABIT_UGURU3_DATA 0x04
#define ABIT_UGURU3_REGION_LENGTH 5
/*
* The wait_xxx functions return this on success and the last contents
* of the DATA register (0-255) on failure.
*/
#define ABIT_UGURU3_SUCCESS -1
/* uGuru status flags */
#define ABIT_UGURU3_STATUS_READY_FOR_READ 0x01
#define ABIT_UGURU3_STATUS_BUSY 0x02
/* Structures */
struct abituguru3_sensor_info {
const char *name;
int port;
int type;
int multiplier;
int divisor;
int offset;
};
/* Avoid use of flexible array members */
#define ABIT_UGURU3_MAX_DMI_NAMES 2
struct abituguru3_motherboard_info {
u16 id;
const char *dmi_name[ABIT_UGURU3_MAX_DMI_NAMES + 1];
/* + 1 -> end of sensors indicated by a sensor with name == NULL */
struct abituguru3_sensor_info sensors[ABIT_UGURU3_MAX_NO_SENSORS