linux/drivers/hwmon/applesmc.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * 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 <[email protected]>
 * Copyright (C) 2010 Henrik Rydberg <[email protected]>
 *
 * Based on hdaps.c driver:
 * Copyright (C) 2005 Robert Love <[email protected]>
 * Copyright (C) 2005 Jesper Juhl <[email protected]>
 *
 * Fan control based on smcFanControl:
 * Copyright (C) 2006 Hendrik Holtmann <[email protected]>
 */

#define pr_fmt(fmt)

#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/dmi.h>
#include <linux/mutex.h>
#include <linux/hwmon-sysfs.h>
#include <linux/io.h>
#include <linux/leds.h>
#include <linux/hwmon.h>
#include <linux/workqueue.h>
#include <linux/err.h>
#include <linux/bits.h>

/* data port used by Apple SMC */
#define APPLESMC_DATA_PORT
/* command/status port used by Apple SMC */
#define APPLESMC_CMD_PORT

#define APPLESMC_NR_PORTS

#define APPLESMC_MAX_DATA_LENGTH

/* Apple SMC status bits */
#define SMC_STATUS_AWAITING_DATA
#define SMC_STATUS_IB_CLOSED
#define SMC_STATUS_BUSY

/* Initial wait is 8us */
#define APPLESMC_MIN_WAIT

#define APPLESMC_READ_CMD
#define APPLESMC_WRITE_CMD
#define APPLESMC_GET_KEY_BY_INDEX_CMD
#define APPLESMC_GET_KEY_TYPE_CMD

#define KEY_COUNT_KEY

#define LIGHT_SENSOR_LEFT_KEY
#define LIGHT_SENSOR_RIGHT_KEY
#define BACKLIGHT_KEY

#define CLAMSHELL_KEY

#define MOTION_SENSOR_X_KEY
#define MOTION_SENSOR_Y_KEY
#define MOTION_SENSOR_Z_KEY
#define MOTION_SENSOR_KEY

#define FANS_COUNT
#define FANS_MANUAL
#define FAN_ID_FMT

#define TEMP_SENSOR_TYPE

/* List of keys used to read/write fan speeds */
static const char *const fan_speed_fmt[] =;

#define INIT_TIMEOUT_MSECS
#define INIT_WAIT_MSECS

#define APPLESMC_POLL_INTERVAL
#define APPLESMC_INPUT_FUZZ
#define APPLESMC_INPUT_FLAT

#define to_index(attr)
#define to_option(attr)

/* Dynamic device node attributes */
struct applesmc_dev_attr {};

/* Dynamic device node group */
struct applesmc_node_group {};

/* AppleSMC entry - cached register information */
struct applesmc_entry {};

/* Register lookup and registers common to all SMCs */
static struct applesmc_registers {} smcreg =;

static const int debug;
static struct platform_device *pdev;
static s16 rest_x;
static s16 rest_y;
static u8 backlight_state[2];

static struct device *hwmon_dev;
static struct input_dev *applesmc_idev;

/*
 * Last index written to key_at_index sysfs file, and value to use for all other
 * key_at_index_* sysfs files.
 */
static unsigned int key_at_index;

static struct workqueue_struct *applesmc_led_wq;

/*
 * Wait for specific status bits with a mask on the SMC.
 * Used before all transactions.
 * This does 10 fast loops of 8us then exponentially backs off for a
 * minimum total wait of 262ms. Depending on usleep_range this could
 * run out past 500ms.
 */

static int wait_status(u8 val, u8 mask)
{}

/* send_byte - Write to SMC data port. Callers must hold applesmc_lock. */

static int send_byte(u8 cmd, u16 port)
{}

/* send_command - Write a command to the SMC. Callers must hold applesmc_lock. */

static int send_command(u8 cmd)
{}

/*
 * Based on logic from the Apple driver. This is issued before any interaction
 * If busy is stuck high, issue a read command to reset the SMC state machine.
 * If busy is stuck high after the command then the SMC is jammed.
 */

static int smc_sane(void)
{}

static int send_argument(const char *key)
{}

static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len)
{}

static int write_smc(u8 cmd, const char *key, const u8 *buffer, u8 len)
{}

static int read_register_count(unsigned int *count)
{}

/*
 * Serialized I/O
 *
 * Returns zero on success or a negative error on failure.
 * All functions below are concurrency safe - callers should NOT hold lock.
 */

static int applesmc_read_entry(const struct applesmc_entry *entry,
			       u8 *buf, u8 len)
{}

static int applesmc_write_entry(const struct applesmc_entry *entry,
				const u8 *buf, u8 len)
{}

static const struct applesmc_entry *applesmc_get_entry_by_index(int index)
{}

static int applesmc_get_lower_bound(unsigned int *lo, const char *key)
{}

static int applesmc_get_upper_bound(unsigned int *hi, const char *key)
{}

static const struct applesmc_entry *applesmc_get_entry_by_key(const char *key)
{}

static int applesmc_read_key(const char *key, u8 *buffer, u8 len)
{}

static int applesmc_write_key(const char *key, const u8 *buffer, u8 len)
{}

static int applesmc_has_key(const char *key, bool *value)
{}

/*
 * applesmc_read_s16 - Read 16-bit signed big endian register
 */
static int applesmc_read_s16(const char *key, s16 *value)
{}

/*
 * applesmc_device_init - initialize the accelerometer.  Can sleep.
 */
static void applesmc_device_init(void)
{}

static int applesmc_init_index(struct applesmc_registers *s)
{}

/*
 * applesmc_init_smcreg_try - Try to initialize register cache. Idempotent.
 */
static int applesmc_init_smcreg_try(void)
{}

static void applesmc_destroy_smcreg(void)
{}

/*
 * applesmc_init_smcreg - Initialize register cache.
 *
 * Retries until initialization is successful, or the operation times out.
 *
 */
static int applesmc_init_smcreg(void)
{}

/* Device model stuff */
static int applesmc_probe(struct platform_device *dev)
{}

/* Synchronize device with memorized backlight state */
static int applesmc_pm_resume(struct device *dev)
{}

/* Reinitialize device on resume from hibernation */
static int applesmc_pm_restore(struct device *dev)
{}

static const struct dev_pm_ops applesmc_pm_ops =;

static struct platform_driver applesmc_driver =;

/*
 * applesmc_calibrate - Set our "resting" values.  Callers must
 * hold applesmc_lock.
 */
static void applesmc_calibrate(void)
{}

static void applesmc_idev_poll(struct input_dev *idev)
{}

/* Sysfs Files */

static ssize_t applesmc_name_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
{}

static ssize_t applesmc_position_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
{}

static ssize_t applesmc_light_show(struct device *dev,
				struct device_attribute *attr, char *sysfsbuf)
{}

/* Displays sensor key as label */
static ssize_t applesmc_show_sensor_label(struct device *dev,
			struct device_attribute *devattr, char *sysfsbuf)
{}

/* Displays degree Celsius * 1000 */
static ssize_t applesmc_show_temperature(struct device *dev,
			struct device_attribute *devattr, char *sysfsbuf)
{}

static ssize_t applesmc_show_fan_speed(struct device *dev,
				struct device_attribute *attr, char *sysfsbuf)
{}

static ssize_t applesmc_store_fan_speed(struct device *dev,
					struct device_attribute *attr,
					const char *sysfsbuf, size_t count)
{}

static ssize_t applesmc_show_fan_manual(struct device *dev,
			struct device_attribute *attr, char *sysfsbuf)
{}

static ssize_t applesmc_store_fan_manual(struct device *dev,
					 struct device_attribute *attr,
					 const char *sysfsbuf, size_t count)
{}

static ssize_t applesmc_show_fan_position(struct device *dev,
				struct device_attribute *attr, char *sysfsbuf)
{}

static ssize_t applesmc_calibrate_show(struct device *dev,
				struct device_attribute *attr, char *sysfsbuf)
{}

static ssize_t applesmc_calibrate_store(struct device *dev,
	struct device_attribute *attr, const char *sysfsbuf, size_t count)
{}

static void applesmc_backlight_set(struct work_struct *work)
{}
static DECLARE_WORK(backlight_work, &applesmc_backlight_set);

static void applesmc_brightness_set(struct led_classdev *led_cdev,
						enum led_brightness value)
{}

static ssize_t applesmc_key_count_show(struct device *dev,
				struct device_attribute *attr, char *sysfsbuf)
{}

static ssize_t applesmc_key_at_index_read_show(struct device *dev,
				struct device_attribute *attr, char *sysfsbuf)
{}

static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
				struct device_attribute *attr, char *sysfsbuf)
{}

static ssize_t applesmc_key_at_index_type_show(struct device *dev,
				struct device_attribute *attr, char *sysfsbuf)
{}

static ssize_t applesmc_key_at_index_name_show(struct device *dev,
				struct device_attribute *attr, char *sysfsbuf)
{}

static ssize_t applesmc_key_at_index_show(struct device *dev,
				struct device_attribute *attr, char *sysfsbuf)
{}

static ssize_t applesmc_key_at_index_store(struct device *dev,
	struct device_attribute *attr, const char *sysfsbuf, size_t count)
{}

static struct led_classdev applesmc_backlight =;

static struct applesmc_node_group info_group[] =;

static struct applesmc_node_group accelerometer_group[] =;

static struct applesmc_node_group light_sensor_group[] =;

static struct applesmc_node_group fan_group[] =;

static struct applesmc_node_group temp_group[] =;

/* Module stuff */

/*
 * applesmc_destroy_nodes - remove files and free associated memory
 */
static void applesmc_destroy_nodes(struct applesmc_node_group *groups)
{}

/*
 * applesmc_create_nodes - create a two-dimensional group of sysfs files
 */
static int applesmc_create_nodes(struct applesmc_node_group *groups, int num)
{}

/* Create accelerometer resources */
static int applesmc_create_accelerometer(void)
{}

/* Release all resources used by the accelerometer */
static void applesmc_release_accelerometer(void)
{}

static int applesmc_create_light_sensor(void)
{}

static void applesmc_release_light_sensor(void)
{}

static int applesmc_create_key_backlight(void)
{}

static void applesmc_release_key_backlight(void)
{}

static int applesmc_dmi_match(const struct dmi_system_id *id)
{}

/*
 * Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
 * So we need to put "Apple MacBook Pro" before "Apple MacBook".
 */
static const struct dmi_system_id applesmc_whitelist[] __initconst =;

static int __init applesmc_init(void)
{}

static void __exit applesmc_exit(void)
{}

module_init();
module_exit(applesmc_exit);

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();
MODULE_DEVICE_TABLE(dmi, applesmc_whitelist);