/*
* drivers/hwmon/applesmc.c - driver for Apple's SMC (accelerometer, temperature
* sensors, fan control, keyboard backlight control) used in Intel-based Apple
* computers.
*
* Copyright (C) 2007 Nicolas Boichat <nicolas@boichat.ch>
*
* Based on hdaps.c driver:
* Copyright (C) 2005 Robert Love <rml@novell.com>
* Copyright (C) 2005 Jesper Juhl <jesper.juhl@gmail.com>
*
* Fan control based on smcFanControl:
* Copyright (C) 2006 Hendrik Holtmann <holtmann@mac.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License v2 as published by the
* Free Software Foundation.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/input-polldev.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/dmi.h>
#include <linux/mutex.h>
#include <linux/hwmon-sysfs.h>
#include <asm/io.h>
#include <linux/leds.h>
#include <linux/hwmon.h>
#include <linux/workqueue.h>
/* data port used by Apple SMC */
#define APPLESMC_DATA_PORT 0x300
/* command/status port used by Apple SMC */
#define APPLESMC_CMD_PORT 0x304
#define APPLESMC_NR_PORTS 32 /* 0x300-0x31f */
#define APPLESMC_MAX_DATA_LENGTH 32
#define APPLESMC_STATUS_MASK 0x0f
#define APPLESMC_READ_CMD 0x10
#define APPLESMC_WRITE_CMD 0x11
#define APPLESMC_GET_KEY_BY_INDEX_CMD 0x12
#define APPLESMC_GET_KEY_TYPE_CMD 0x13
#define KEY_COUNT_KEY "#KEY" /* r-o ui32 */
#define LIGHT_SENSOR_LEFT_KEY "ALV0" /* r-o {alv (6 bytes) */
#define LIGHT_SENSOR_RIGHT_KEY "ALV1" /* r-o {alv (6 bytes) */
#define BACKLIGHT_KEY "LKSB" /* w-o {lkb (2 bytes) */
#define CLAMSHELL_KEY "MSLD" /* r-o ui8 (unused) */
#define MOTION_SENSOR_X_KEY "MO_X" /* r-o sp78 (2 bytes) */
#define MOTION_SENSOR_Y_KEY "MO_Y" /* r-o sp78 (2 bytes) */
#define MOTION_SENSOR_Z_KEY "MO_Z" /* r-o sp78 (2 bytes) */
#define MOTION_SENSOR_KEY "MOCN" /* r/w ui16 */
#define FANS_COUNT "FNum" /* r-o ui8 */
#define FANS_MANUAL "FS! " /* r-w ui16 */
#define FAN_ACTUAL_SPEED "F0Ac" /* r-o fpe2 (2 bytes) */
#define FAN_MIN_SPEED "F0Mn" /* r-o fpe2 (2 bytes) */
#define FAN_MAX_SPEED "F0Mx" /* r-o fpe2 (2 bytes) */
#define FAN_SAFE_SPEED "F0Sf" /* r-o fpe2 (2 bytes) */
#define FAN_TARGET_SPEED "F0Tg" /* r-w fpe2 (2 bytes) */
#define FAN_POSITION "F0ID" /* r-o char[16] */
/*
* Temperature sensors keys (sp78 - 2 bytes).
* First set for Macbook(Pro), second for Macmini.
*/
static const char* temperature_sensors_sets[][13] = {
{ "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H",
"Th1H", "Tm0P", "Ts0P", "Ts1P", NULL },
{ "TC0D", "TC0P", NULL }
};
/* List of keys used to read/write fan speeds */
static const char* fan_speed_keys[] = {
FAN_ACTUAL_SPEED,
FAN_MIN_SPEED,
FAN_MAX_SPEED,
FAN_SAFE_SPEED,
FAN_TARGET_SPEED
};
#define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
#define INIT_WAIT_MSECS 50 /* ... in 50ms increments */
#define APPLESMC_POLL_INTERVAL 50 /* msecs */
#define APPLESMC_INPUT_FUZZ 4 /* input event threshold */
#define APPLESMC_INPUT_FLAT 4
#define SENSOR_X 0
#define SENSOR_Y 1
#define SENSOR_Z 2
/* Structure to be passed to DMI_MATCH function */
struct dmi_match_data {
/* Indicates whether this computer has an accelerometer. */
int accelerometer;
/* Indicates whether this computer has light sensors and keyboard backlight. */
int light;
/* Indicates which temperature sensors set to use. */
int temperature_set;
};
static const int debug;
static struct platform_device *pdev;
static s16 rest_x;
static