linux/drivers/platform/x86/thinkpad_acpi.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  thinkpad_acpi.c - ThinkPad ACPI Extras
 *
 *  Copyright (C) 2004-2005 Borislav Deianov <[email protected]>
 *  Copyright (C) 2006-2009 Henrique de Moraes Holschuh <[email protected]>
 */

#define pr_fmt(fmt)

#define TPACPI_VERSION
#define TPACPI_SYSFS_VERSION

/*
 *  Changelog:
 *  2007-10-20		changelog trimmed down
 *
 *  2007-03-27  0.14	renamed to thinkpad_acpi and moved to
 *  			drivers/misc.
 *
 *  2006-11-22	0.13	new maintainer
 *  			changelog now lives in git commit history, and will
 *  			not be updated further in-file.
 *
 *  2005-03-17	0.11	support for 600e, 770x
 *			    thanks to Jamie Lentin <[email protected]>
 *
 *  2005-01-16	0.9	use MODULE_VERSION
 *			    thanks to Henrik Brix Andersen <[email protected]>
 *			fix parameter passing on module loading
 *			    thanks to Rusty Russell <[email protected]>
 *			    thanks to Jim Radford <[email protected]>
 *  2004-11-08	0.8	fix init error case, don't return from a macro
 *			    thanks to Chris Wright <[email protected]>
 */

#include <linux/acpi.h>
#include <linux/backlight.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/dmi.h>
#include <linux/fb.h>
#include <linux/freezer.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/input/sparse-keymap.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/leds.h>
#include <linux/list.h>
#include <linux/lockdep.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/nvram.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/platform_profile.h>
#include <linux/power_supply.h>
#include <linux/proc_fs.h>
#include <linux/rfkill.h>
#include <linux/sched.h>
#include <linux/sched/signal.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/string_helpers.h>
#include <linux/sysfs.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <linux/units.h>
#include <linux/workqueue.h>

#include <acpi/battery.h>
#include <acpi/video.h>

#include <drm/drm_privacy_screen_driver.h>

#include <sound/control.h>
#include <sound/core.h>
#include <sound/initval.h>

#include "dual_accel_detect.h"

/* ThinkPad CMOS commands */
#define TP_CMOS_VOLUME_DOWN
#define TP_CMOS_VOLUME_UP
#define TP_CMOS_VOLUME_MUTE
#define TP_CMOS_BRIGHTNESS_UP
#define TP_CMOS_BRIGHTNESS_DOWN
#define TP_CMOS_THINKLIGHT_ON
#define TP_CMOS_THINKLIGHT_OFF

/* NVRAM Addresses */
enum tp_nvram_addr {};

/* NVRAM bit masks */
enum {};

/* Misc NVRAM-related */
enum {};

/* ACPI HIDs */
#define TPACPI_ACPI_IBM_HKEY_HID
#define TPACPI_ACPI_LENOVO_HKEY_HID
#define TPACPI_ACPI_LENOVO_HKEY_V2_HID
#define TPACPI_ACPI_EC_HID

/* Input IDs */
#define TPACPI_HKEY_INPUT_PRODUCT
#define TPACPI_HKEY_INPUT_VERSION

/* ACPI \WGSV commands */
enum {};

/* TP_ACPI_WGSV_GET_STATE bits */
enum {};

/* HKEY events */
enum tpacpi_hkey_event_t {};

/****************************************************************************
 * Main driver
 */

#define TPACPI_NAME
#define TPACPI_DESC
#define TPACPI_FILE
#define TPACPI_URL
#define TPACPI_MAIL

#define TPACPI_PROC_DIR
#define TPACPI_ACPI_EVENT_PREFIX
#define TPACPI_DRVR_NAME
#define TPACPI_DRVR_SHORTNAME
#define TPACPI_HWMON_DRVR_NAME

#define TPACPI_NVRAM_KTHREAD_NAME
#define TPACPI_WORKQUEUE_NAME

#define TPACPI_MAX_ACPI_ARGS

/* Debugging printk groups */
#define TPACPI_DBG_ALL
#define TPACPI_DBG_DISCLOSETASK
#define TPACPI_DBG_INIT
#define TPACPI_DBG_EXIT
#define TPACPI_DBG_RFKILL
#define TPACPI_DBG_HKEY
#define TPACPI_DBG_FAN
#define TPACPI_DBG_BRGHT
#define TPACPI_DBG_MIXER

#define FAN_NOT_PRESENT

/****************************************************************************
 * Driver-wide structs and misc. variables
 */

struct ibm_struct;

struct tp_acpi_drv_struct {};

struct ibm_struct {};

struct ibm_init_struct {};

/* DMI Quirks */
struct quirk_entry {};

static struct quirk_entry quirk_btusb_bug =;

static struct {} tp_features;

static struct {} tp_warned;

struct thinkpad_id_data {};
static struct thinkpad_id_data thinkpad_id;

static enum {} tpacpi_lifecycle;

static int experimental;
static u32 dbg_level;

static struct workqueue_struct *tpacpi_wq;

enum led_status_t {};

/* tpacpi LED class */
struct tpacpi_led_classdev {};

/* brightness level capabilities */
static unsigned int bright_maxlvl;	/* 0 = unknown */

#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
static int dbg_wlswemul;
static bool tpacpi_wlsw_emulstate;
static int dbg_bluetoothemul;
static bool tpacpi_bluetooth_emulstate;
static int dbg_wwanemul;
static bool tpacpi_wwan_emulstate;
static int dbg_uwbemul;
static bool tpacpi_uwb_emulstate;
#endif


/*************************************************************************
 *  Debugging helpers
 */

#define dbg_printk(a_dbg_level, format, arg...)

#ifdef CONFIG_THINKPAD_ACPI_DEBUG
#define vdbg_printk
static const char *str_supported(int is_supported);
#else
static inline const char *str_supported(int is_supported) { return ""; }
#define vdbg_printk
#endif

static void tpacpi_log_usertask(const char * const what)
{}

#define tpacpi_disclose_usertask(what, format, arg...)

/*
 * Quirk handling helpers
 *
 * ThinkPad IDs and versions seen in the field so far are
 * two or three characters from the set [0-9A-Z], i.e. base 36.
 *
 * We use values well outside that range as specials.
 */

#define TPACPI_MATCH_ANY
#define TPACPI_MATCH_ANY_VERSION
#define TPACPI_MATCH_UNKNOWN

/* TPID('1', 'Y') == 0x3159 */
#define TPID(__c1, __c2)
#define TPID3(__c1, __c2, __c3)
#define TPVER

#define TPACPI_Q_IBM(__id1, __id2, __quirk)

#define TPACPI_Q_LNV(__id1, __id2, __quirk)

#define TPACPI_Q_LNV3(__id1, __id2, __id3, __quirk)

#define TPACPI_QEC_IBM(__id1, __id2, __quirk)

#define TPACPI_QEC_LNV(__id1, __id2, __quirk)

struct tpacpi_quirk {};

/**
 * tpacpi_check_quirks() - search BIOS/EC version on a list
 * @qlist:		array of &struct tpacpi_quirk
 * @qlist_size:		number of elements in @qlist
 *
 * Iterates over a quirks list until one is found that matches the
 * ThinkPad's vendor, BIOS and EC model.
 *
 * Returns: %0 if nothing matches, otherwise returns the quirks field of
 * the matching &struct tpacpi_quirk entry.
 *
 * The match criteria is: vendor, ec and bios must match.
 */
static unsigned long __init tpacpi_check_quirks(
			const struct tpacpi_quirk *qlist,
			unsigned int qlist_size)
{}

static inline bool __pure __init tpacpi_is_lenovo(void)
{}

static inline bool __pure __init tpacpi_is_ibm(void)
{}

/****************************************************************************
 ****************************************************************************
 *
 * ACPI Helpers and device model
 *
 ****************************************************************************
 ****************************************************************************/

/*************************************************************************
 * ACPI basic handles
 */

static acpi_handle root_handle;
static acpi_handle ec_handle;

#define TPACPI_HANDLE(object, parent, paths...)

TPACPI_HANDLE();	/* 570 */
TPACPI_HANDLE();	/* 570 */

TPACPI_HANDLE();			/* all others */

TPACPI_HANDLE();			/* 570 */

/*************************************************************************
 * ACPI helpers
 */

static int acpi_evalf(acpi_handle handle,
		      int *res, char *method, char *fmt, ...)
{}

static int acpi_ec_read(int i, u8 *p)
{}

static int acpi_ec_write(int i, u8 v)
{}

static int issue_thinkpad_cmos_command(int cmos_cmd)
{}

/*************************************************************************
 * ACPI device model
 */

#define TPACPI_ACPIHANDLE_INIT(object)

static void __init drv_acpi_handle_init(const char *name,
			   acpi_handle *handle, const acpi_handle parent,
			   char **paths, const int num_paths)
{}

static acpi_status __init tpacpi_acpi_handle_locate_callback(acpi_handle handle,
			u32 level, void *context, void **return_value)
{}

static void __init tpacpi_acpi_handle_locate(const char *name,
		const char *hid,
		acpi_handle *handle)
{}

static void dispatch_acpi_notify(acpi_handle handle, u32 event, void *data)
{}

static int __init setup_acpi_notify(struct ibm_struct *ibm)
{}

static int __init tpacpi_device_add(struct acpi_device *device)
{}

static int __init register_tpacpi_subdriver(struct ibm_struct *ibm)
{}


/****************************************************************************
 ****************************************************************************
 *
 * Procfs Helpers
 *
 ****************************************************************************
 ****************************************************************************/

static int dispatch_proc_show(struct seq_file *m, void *v)
{}

static int dispatch_proc_open(struct inode *inode, struct file *file)
{}

static ssize_t dispatch_proc_write(struct file *file,
			const char __user *userbuf,
			size_t count, loff_t *pos)
{}

static const struct proc_ops dispatch_proc_ops =;

/****************************************************************************
 ****************************************************************************
 *
 * Device model: input, hwmon and platform
 *
 ****************************************************************************
 ****************************************************************************/

static struct platform_device *tpacpi_pdev;
static struct platform_device *tpacpi_sensors_pdev;
static struct device *tpacpi_hwmon;
static struct input_dev *tpacpi_inputdev;
static struct mutex tpacpi_inputdev_send_mutex;
static LIST_HEAD(tpacpi_all_drivers);

#ifdef CONFIG_PM_SLEEP
static int tpacpi_suspend_handler(struct device *dev)
{}

static int tpacpi_resume_handler(struct device *dev)
{}
#endif

static SIMPLE_DEV_PM_OPS(tpacpi_pm,
			 tpacpi_suspend_handler, tpacpi_resume_handler);

static void tpacpi_shutdown_handler(struct platform_device *pdev)
{}

/*************************************************************************
 * sysfs support helpers
 */

static int parse_strtoul(const char *buf,
		unsigned long max, unsigned long *value)
{}

static void tpacpi_disable_brightness_delay(void)
{}

static void printk_deprecated_attribute(const char * const what,
					const char * const details)
{}

/*************************************************************************
 * rfkill and radio control support helpers
 */

/*
 * ThinkPad-ACPI firmware handling model:
 *
 * WLSW (master wireless switch) is event-driven, and is common to all
 * firmware-controlled radios.  It cannot be controlled, just monitored,
 * as expected.  It overrides all radio state in firmware
 *
 * The kernel, a masked-off hotkey, and WLSW can change the radio state
 * (TODO: verify how WLSW interacts with the returned radio state).
 *
 * The only time there are shadow radio state changes, is when
 * masked-off hotkeys are used.
 */

/*
 * Internal driver API for radio state:
 *
 * int: < 0 = error, otherwise enum tpacpi_rfkill_state
 * bool: true means radio blocked (off)
 */
enum tpacpi_rfkill_state {};

/* rfkill switches */
enum tpacpi_rfk_id {};

static const char *tpacpi_rfkill_names[] =;

/* ThinkPad-ACPI rfkill subdriver */
struct tpacpi_rfk {};

struct tpacpi_rfk_ops {};

static struct tpacpi_rfk *tpacpi_rfkill_switches[TPACPI_RFK_SW_MAX];

/* Query FW and update rfkill sw state for a given rfkill switch */
static int tpacpi_rfk_update_swstate(const struct tpacpi_rfk *tp_rfk)
{}

/*
 * Sync the HW-blocking state of all rfkill switches,
 * do notice it causes the rfkill core to schedule uevents
 */
static void tpacpi_rfk_update_hwblock_state(bool blocked)
{}

/* Call to get the WLSW state from the firmware */
static int hotkey_get_wlsw(void);

/* Call to query WLSW state and update all rfkill switches */
static bool tpacpi_rfk_check_hwblock_state(void)
{}

static int tpacpi_rfk_hook_set_block(void *data, bool blocked)
{}

static const struct rfkill_ops tpacpi_rfk_rfkill_ops =;

static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id,
			const struct tpacpi_rfk_ops *tp_rfkops,
			const enum rfkill_type rfktype,
			const char *name,
			const bool set_default)
{}

static void tpacpi_destroy_rfkill(const enum tpacpi_rfk_id id)
{}

static void printk_deprecated_rfkill_attribute(const char * const what)
{}

/* sysfs <radio> enable ------------------------------------------------ */
static ssize_t tpacpi_rfk_sysfs_enable_show(const enum tpacpi_rfk_id id,
					    struct device_attribute *attr,
					    char *buf)
{}

static ssize_t tpacpi_rfk_sysfs_enable_store(const enum tpacpi_rfk_id id,
			    struct device_attribute *attr,
			    const char *buf, size_t count)
{}

/* procfs -------------------------------------------------------------- */
static int tpacpi_rfk_procfs_read(const enum tpacpi_rfk_id id, struct seq_file *m)
{}

static int tpacpi_rfk_procfs_write(const enum tpacpi_rfk_id id, char *buf)
{}

/*************************************************************************
 * thinkpad-acpi driver attributes
 */

/* interface_version --------------------------------------------------- */
static ssize_t interface_version_show(struct device_driver *drv, char *buf)
{}
static DRIVER_ATTR_RO(interface_version);

/* debug_level --------------------------------------------------------- */
static ssize_t debug_level_show(struct device_driver *drv, char *buf)
{}

static ssize_t debug_level_store(struct device_driver *drv, const char *buf,
				 size_t count)
{}
static DRIVER_ATTR_RW(debug_level);

/* version ------------------------------------------------------------- */
static ssize_t version_show(struct device_driver *drv, char *buf)
{}
static DRIVER_ATTR_RO(version);

/* --------------------------------------------------------------------- */

#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES

/* wlsw_emulstate ------------------------------------------------------ */
static ssize_t wlsw_emulstate_show(struct device_driver *drv, char *buf)
{}

static ssize_t wlsw_emulstate_store(struct device_driver *drv, const char *buf,
				    size_t count)
{}
static DRIVER_ATTR_RW(wlsw_emulstate);

/* bluetooth_emulstate ------------------------------------------------- */
static ssize_t bluetooth_emulstate_show(struct device_driver *drv, char *buf)
{}

static ssize_t bluetooth_emulstate_store(struct device_driver *drv,
					 const char *buf, size_t count)
{}
static DRIVER_ATTR_RW(bluetooth_emulstate);

/* wwan_emulstate ------------------------------------------------- */
static ssize_t wwan_emulstate_show(struct device_driver *drv, char *buf)
{}

static ssize_t wwan_emulstate_store(struct device_driver *drv, const char *buf,
				    size_t count)
{}
static DRIVER_ATTR_RW(wwan_emulstate);

/* uwb_emulstate ------------------------------------------------- */
static ssize_t uwb_emulstate_show(struct device_driver *drv, char *buf)
{}

static ssize_t uwb_emulstate_store(struct device_driver *drv, const char *buf,
				   size_t count)
{}
static DRIVER_ATTR_RW(uwb_emulstate);
#endif

/*************************************************************************
 * Firmware Data
 */

/*
 * Table of recommended minimum BIOS versions
 *
 * Reasons for listing:
 *    1. Stable BIOS, listed because the unknown amount of
 *       bugs and bad ACPI behaviour on older versions
 *
 *    2. BIOS or EC fw with known bugs that trigger on Linux
 *
 *    3. BIOS with known reduced functionality in older versions
 *
 *  We recommend the latest BIOS and EC version.
 *  We only support the latest BIOS and EC fw version as a rule.
 *
 *  Sources: IBM ThinkPad Public Web Documents (update changelogs),
 *  Information from users in ThinkWiki
 *
 *  WARNING: we use this table also to detect that the machine is
 *  a ThinkPad in some cases, so don't remove entries lightly.
 */

#define TPV_Q

#define TPV_Q_X

#define TPV_QI0

/* Outdated IBM BIOSes often lack the EC id string */
#define TPV_QI1

/* Outdated IBM BIOSes often lack the EC id string */
#define TPV_QI2

#define TPV_QL0

#define TPV_QL1

#define TPV_QL2(__bid1, __bid2, __bv1, __bv2,		\
		__eid1, __eid2, __ev1, __ev2)

static const struct tpacpi_quirk tpacpi_bios_version_qtable[] __initconst =;

#undef TPV_QL1
#undef TPV_QL0
#undef TPV_QI2
#undef TPV_QI1
#undef TPV_QI0
#undef TPV_Q_X
#undef TPV_Q

static void __init tpacpi_check_outdated_fw(void)
{}

static bool __init tpacpi_is_fw_known(void)
{}

/****************************************************************************
 ****************************************************************************
 *
 * Subdrivers
 *
 ****************************************************************************
 ****************************************************************************/

/*************************************************************************
 * thinkpad-acpi metadata subdriver
 */

static int thinkpad_acpi_driver_read(struct seq_file *m)
{}

static struct ibm_struct thinkpad_acpi_driver_data =;

/*************************************************************************
 * Hotkey subdriver
 */

/*
 * ThinkPad firmware event model
 *
 * The ThinkPad firmware has two main event interfaces: normal ACPI
 * notifications (which follow the ACPI standard), and a private event
 * interface.
 *
 * The private event interface also issues events for the hotkeys.  As
 * the driver gained features, the event handling code ended up being
 * built around the hotkey subdriver.  This will need to be refactored
 * to a more formal event API eventually.
 *
 * Some "hotkeys" are actually supposed to be used as event reports,
 * such as "brightness has changed", "volume has changed", depending on
 * the ThinkPad model and how the firmware is operating.
 *
 * Unlike other classes, hotkey-class events have mask/unmask control on
 * non-ancient firmware.  However, how it behaves changes a lot with the
 * firmware model and version.
 */

enum {};

enum {};

enum {};

enum {};

#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
struct tp_nvram_state {};

/* kthread for the hotkey poller */
static struct task_struct *tpacpi_hotkey_task;

/*
 * Acquire mutex to write poller control variables as an
 * atomic block.
 *
 * Increment hotkey_config_change when changing them if you
 * want the kthread to forget old state.
 *
 * See HOTKEY_CONFIG_CRITICAL_START/HOTKEY_CONFIG_CRITICAL_END
 */
static struct mutex hotkey_thread_data_mutex;
static unsigned int hotkey_config_change;

/*
 * hotkey poller control variables
 *
 * Must be atomic or readers will also need to acquire mutex
 *
 * HOTKEY_CONFIG_CRITICAL_START/HOTKEY_CONFIG_CRITICAL_END
 * should be used only when the changes need to be taken as
 * a block, OR when one needs to force the kthread to forget
 * old state.
 */
static u32 hotkey_source_mask;		/* bit mask 0=ACPI,1=NVRAM */
static unsigned int hotkey_poll_freq =; /* Hz */

#define HOTKEY_CONFIG_CRITICAL_START
#define HOTKEY_CONFIG_CRITICAL_END

#else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */

#define hotkey_source_mask
#define HOTKEY_CONFIG_CRITICAL_START
#define HOTKEY_CONFIG_CRITICAL_END

#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */

static struct mutex hotkey_mutex;

static enum {} hotkey_wakeup_reason;

static int hotkey_autosleep_ack;

static u32 hotkey_orig_mask;		/* events the BIOS had enabled */
static u32 hotkey_all_mask;		/* all events supported in fw */
static u32 hotkey_adaptive_all_mask;	/* all adaptive events supported in fw */
static u32 hotkey_reserved_mask;	/* events better left disabled */
static u32 hotkey_driver_mask;		/* events needed by the driver */
static u32 hotkey_user_mask;		/* events visible to userspace */
static u32 hotkey_acpi_mask;		/* events enabled in firmware */

static bool tpacpi_driver_event(const unsigned int hkey_event);
static void hotkey_poll_setup(const bool may_warn);

/* HKEY.MHKG() return bits */
#define TP_HOTKEY_TABLET_MASK
enum {};

enum {};

static int hotkey_get_wlsw(void)
{}

static int hotkey_gmms_get_tablet_mode(int s, int *has_tablet_mode)
{}

static int hotkey_get_tablet_mode(int *status)
{}

/*
 * Reads current event mask from firmware, and updates
 * hotkey_acpi_mask accordingly.  Also resets any bits
 * from hotkey_user_mask that are unavailable to be
 * delivered (shadow requirement of the userspace ABI).
 */
static int hotkey_mask_get(void)
{}

static void hotkey_mask_warn_incomplete_mask(void)
{}

/*
 * Set the firmware mask when supported
 *
 * Also calls hotkey_mask_get to update hotkey_acpi_mask.
 *
 * NOTE: does not set bits in hotkey_user_mask, but may reset them.
 */
static int hotkey_mask_set(u32 mask)
{}

/*
 * Sets hotkey_user_mask and tries to set the firmware mask
 */
static int hotkey_user_mask_set(const u32 mask)
{}

/*
 * Sets the driver hotkey mask.
 *
 * Can be called even if the hotkey subdriver is inactive
 */
static int tpacpi_hotkey_driver_mask_set(const u32 mask)
{}

static int hotkey_status_get(int *status)
{}

static int hotkey_status_set(bool enable)
{}

static void tpacpi_input_send_tabletsw(void)
{}

static bool tpacpi_input_send_key(const u32 hkey, bool *send_acpi_ev)
{}

#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
static struct tp_acpi_drv_struct ibm_hotkey_acpidriver;

/* Do NOT call without validating scancode first */
static void tpacpi_hotkey_send_key(unsigned int scancode)
{}

static void hotkey_read_nvram(struct tp_nvram_state *n, const u32 m)
{}

#define TPACPI_COMPARE_KEY

#define TPACPI_MAY_SEND_KEY

static void issue_volchange(const unsigned int oldvol,
			    const unsigned int newvol,
			    const u32 event_mask)
{}

static void issue_brightnesschange(const unsigned int oldbrt,
				   const unsigned int newbrt,
				   const u32 event_mask)
{}

static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,
					   struct tp_nvram_state *newn,
					   const u32 event_mask)
{}

/*
 * Polling driver
 *
 * We track all events in hotkey_source_mask all the time, since
 * most of them are edge-based.  We only issue those requested by
 * hotkey_user_mask or hotkey_driver_mask, though.
 */
static int hotkey_kthread(void *data)
{}

static void hotkey_poll_stop_sync(void)
{}

static void hotkey_poll_setup(const bool may_warn)
{}

static void hotkey_poll_setup_safe(const bool may_warn)
{}

static void hotkey_poll_set_freq(unsigned int freq)
{}

#else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */

static void hotkey_poll_setup(const bool __unused)
{
}

static void hotkey_poll_setup_safe(const bool __unused)
{
}

static void hotkey_poll_stop_sync(void)
{
}
#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */

static int hotkey_inputdev_open(struct input_dev *dev)
{}

static void hotkey_inputdev_close(struct input_dev *dev)
{}

/* sysfs hotkey enable ------------------------------------------------- */
static ssize_t hotkey_enable_show(struct device *dev,
			   struct device_attribute *attr,
			   char *buf)
{}

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

static DEVICE_ATTR_RW(hotkey_enable);

/* sysfs hotkey mask --------------------------------------------------- */
static ssize_t hotkey_mask_show(struct device *dev,
			   struct device_attribute *attr,
			   char *buf)
{}

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

static DEVICE_ATTR_RW(hotkey_mask);

/* sysfs hotkey bios_enabled ------------------------------------------- */
static ssize_t hotkey_bios_enabled_show(struct device *dev,
			   struct device_attribute *attr,
			   char *buf)
{}

static DEVICE_ATTR_RO(hotkey_bios_enabled);

/* sysfs hotkey bios_mask ---------------------------------------------- */
static ssize_t hotkey_bios_mask_show(struct device *dev,
			   struct device_attribute *attr,
			   char *buf)
{}

static DEVICE_ATTR_RO(hotkey_bios_mask);

/* sysfs hotkey all_mask ----------------------------------------------- */
static ssize_t hotkey_all_mask_show(struct device *dev,
			   struct device_attribute *attr,
			   char *buf)
{}

static DEVICE_ATTR_RO(hotkey_all_mask);

/* sysfs hotkey all_mask ----------------------------------------------- */
static ssize_t hotkey_adaptive_all_mask_show(struct device *dev,
			   struct device_attribute *attr,
			   char *buf)
{}

static DEVICE_ATTR_RO(hotkey_adaptive_all_mask);

/* sysfs hotkey recommended_mask --------------------------------------- */
static ssize_t hotkey_recommended_mask_show(struct device *dev,
					    struct device_attribute *attr,
					    char *buf)
{}

static DEVICE_ATTR_RO(hotkey_recommended_mask);

#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL

/* sysfs hotkey hotkey_source_mask ------------------------------------- */
static ssize_t hotkey_source_mask_show(struct device *dev,
			   struct device_attribute *attr,
			   char *buf)
{}

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

static DEVICE_ATTR_RW(hotkey_source_mask);

/* sysfs hotkey hotkey_poll_freq --------------------------------------- */
static ssize_t hotkey_poll_freq_show(struct device *dev,
			   struct device_attribute *attr,
			   char *buf)
{}

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

static DEVICE_ATTR_RW(hotkey_poll_freq);

#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */

/* sysfs hotkey radio_sw (pollable) ------------------------------------ */
static ssize_t hotkey_radio_sw_show(struct device *dev,
			   struct device_attribute *attr,
			   char *buf)
{}

static DEVICE_ATTR_RO(hotkey_radio_sw);

static void hotkey_radio_sw_notify_change(void)
{}

/* sysfs hotkey tablet mode (pollable) --------------------------------- */
static ssize_t hotkey_tablet_mode_show(struct device *dev,
			   struct device_attribute *attr,
			   char *buf)
{}

static DEVICE_ATTR_RO(hotkey_tablet_mode);

static void hotkey_tablet_mode_notify_change(void)
{}

/* sysfs wakeup reason (pollable) -------------------------------------- */
static ssize_t hotkey_wakeup_reason_show(struct device *dev,
			   struct device_attribute *attr,
			   char *buf)
{}

static DEVICE_ATTR(wakeup_reason, S_IRUGO, hotkey_wakeup_reason_show, NULL);

static void hotkey_wakeup_reason_notify_change(void)
{}

/* sysfs wakeup hotunplug_complete (pollable) -------------------------- */
static ssize_t hotkey_wakeup_hotunplug_complete_show(struct device *dev,
			   struct device_attribute *attr,
			   char *buf)
{}

static DEVICE_ATTR(wakeup_hotunplug_complete, S_IRUGO,
		   hotkey_wakeup_hotunplug_complete_show, NULL);

static void hotkey_wakeup_hotunplug_complete_notify_change(void)
{}

/* sysfs adaptive kbd mode --------------------------------------------- */

static int adaptive_keyboard_get_mode(void);
static int adaptive_keyboard_set_mode(int new_mode);

enum ADAPTIVE_KEY_MODE {};

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

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

static DEVICE_ATTR_RW(adaptive_kbd_mode);

static struct attribute *adaptive_kbd_attributes[] =;

static umode_t hadaptive_kbd_attr_is_visible(struct kobject *kobj,
					     struct attribute *attr, int n)
{}

static const struct attribute_group adaptive_kbd_attr_group =;

/* --------------------------------------------------------------------- */

static struct attribute *hotkey_attributes[] =;

static umode_t hotkey_attr_is_visible(struct kobject *kobj,
				      struct attribute *attr, int n)
{}

static const struct attribute_group hotkey_attr_group =;

/*
 * Sync both the hw and sw blocking state of all switches
 */
static void tpacpi_send_radiosw_update(void)
{}

static void hotkey_exit(void)
{}

/*
 * HKEY quirks:
 *   TPACPI_HK_Q_INIMASK:	Supports FN+F3,FN+F4,FN+F12
 */

#define TPACPI_HK_Q_INIMASK

static const struct tpacpi_quirk tpacpi_hotkey_qtable[] __initconst =;

static int hotkey_init_tablet_mode(void)
{}

static const struct key_entry keymap_ibm[] __initconst =;

static const struct key_entry keymap_lenovo[] __initconst =;

static int __init hotkey_init(struct ibm_init_struct *iibm)
{}

/* Thinkpad X1 Carbon support 5 modes including Home mode, Web browser
 * mode, Web conference mode, Function mode and Lay-flat mode.
 * We support Home mode and Function mode currently.
 *
 * Will consider support rest of modes in future.
 *
 */
static const int adaptive_keyboard_modes[] =;

/* press Fn key a while second, it will switch to Function Mode. Then
 * release Fn key, previous mode be restored.
 */
static bool adaptive_keyboard_mode_is_saved;
static int adaptive_keyboard_prev_mode;

static int adaptive_keyboard_get_mode(void)
{}

static int adaptive_keyboard_set_mode(int new_mode)
{}

static int adaptive_keyboard_get_next_mode(int mode)
{}

static void adaptive_keyboard_change_row(void)
{}

static void adaptive_keyboard_s_quickview_row(void)
{}

/* 0x1000-0x1FFF: key presses */
static bool hotkey_notify_hotkey(const u32 hkey, bool *send_acpi_ev)
{}

/* 0x2000-0x2FFF: Wakeup reason */
static bool hotkey_notify_wakeup(const u32 hkey, bool *send_acpi_ev)
{}

/* 0x4000-0x4FFF: dock-related events */
static bool hotkey_notify_dockevent(const u32 hkey, bool *send_acpi_ev)
{}

/* 0x5000-0x5FFF: human interface helpers */
static bool hotkey_notify_usrevent(const u32 hkey, bool *send_acpi_ev)
{}

static void thermal_dump_all_sensors(void);
static void palmsensor_refresh(void);

/* 0x6000-0x6FFF: thermal alarms/notices and keyboard events */
static bool hotkey_notify_6xxx(const u32 hkey, bool *send_acpi_ev)
{}

static bool hotkey_notify_8xxx(const u32 hkey, bool *send_acpi_ev)
{}

static void hotkey_notify(struct ibm_struct *ibm, u32 event)
{}

static void hotkey_suspend(void)
{}

static void hotkey_resume(void)
{}

/* procfs -------------------------------------------------------------- */
static int hotkey_read(struct seq_file *m)
{}

static void hotkey_enabledisable_warn(bool enable)
{}

static int hotkey_write(char *buf)
{}

static const struct acpi_device_id ibm_htk_device_ids[] =;

static struct tp_acpi_drv_struct ibm_hotkey_acpidriver =;

static struct ibm_struct hotkey_driver_data =;

/*************************************************************************
 * Bluetooth subdriver
 */

enum {};

enum {};

#define TPACPI_RFK_BLUETOOTH_SW_NAME

static int bluetooth_get_status(void)
{}

static int bluetooth_set_status(enum tpacpi_rfkill_state state)
{}

/* sysfs bluetooth enable ---------------------------------------------- */
static ssize_t bluetooth_enable_show(struct device *dev,
			   struct device_attribute *attr,
			   char *buf)
{}

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

static DEVICE_ATTR_RW(bluetooth_enable);

/* --------------------------------------------------------------------- */

static struct attribute *bluetooth_attributes[] =;

static umode_t bluetooth_attr_is_visible(struct kobject *kobj,
					 struct attribute *attr, int n)
{}

static const struct attribute_group bluetooth_attr_group =;

static const struct tpacpi_rfk_ops bluetooth_tprfk_ops =;

static void bluetooth_shutdown(void)
{}

static void bluetooth_exit(void)
{}

static const struct dmi_system_id fwbug_list[] __initconst =;

static const struct pci_device_id fwbug_cards_ids[] __initconst =;


static int __init have_bt_fwbug(void)
{}

static int __init bluetooth_init(struct ibm_init_struct *iibm)
{}

/* procfs -------------------------------------------------------------- */
static int bluetooth_read(struct seq_file *m)
{}

static int bluetooth_write(char *buf)
{}

static struct ibm_struct bluetooth_driver_data =;

/*************************************************************************
 * Wan subdriver
 */

enum {};

#define TPACPI_RFK_WWAN_SW_NAME

static int wan_get_status(void)
{}

static int wan_set_status(enum tpacpi_rfkill_state state)
{}

/* sysfs wan enable ---------------------------------------------------- */
static ssize_t wan_enable_show(struct device *dev,
			   struct device_attribute *attr,
			   char *buf)
{}

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

static DEVICE_ATTR(wwan_enable, S_IWUSR | S_IRUGO,
		   wan_enable_show, wan_enable_store);

/* --------------------------------------------------------------------- */

static struct attribute *wan_attributes[] =;

static umode_t wan_attr_is_visible(struct kobject *kobj, struct attribute *attr,
				   int n)
{}

static const struct attribute_group wan_attr_group =;

static const struct tpacpi_rfk_ops wan_tprfk_ops =;

static void wan_shutdown(void)
{}

static void wan_exit(void)
{}

static int __init wan_init(struct ibm_init_struct *iibm)
{}

/* procfs -------------------------------------------------------------- */
static int wan_read(struct seq_file *m)
{}

static int wan_write(char *buf)
{}

static struct ibm_struct wan_driver_data =;

/*************************************************************************
 * UWB subdriver
 */

enum {};

#define TPACPI_RFK_UWB_SW_NAME

static int uwb_get_status(void)
{}

static int uwb_set_status(enum tpacpi_rfkill_state state)
{}

/* --------------------------------------------------------------------- */

static const struct tpacpi_rfk_ops uwb_tprfk_ops =;

static void uwb_exit(void)
{}

static int __init uwb_init(struct ibm_init_struct *iibm)
{}

static struct ibm_struct uwb_driver_data =;

/*************************************************************************
 * Video subdriver
 */

#ifdef CONFIG_THINKPAD_ACPI_VIDEO

enum video_access_mode {};

enum {};

enum {};

static enum video_access_mode video_supported;
static int video_orig_autosw;

static int video_autosw_get(void);
static int video_autosw_set(int enable);

TPACPI_HANDLE();				/* R30, R31 */

TPACPI_HANDLE();	/* G41 */

static int __init video_init(struct ibm_init_struct *iibm)
{}

static void video_exit(void)
{}

static int video_outputsw_get(void)
{}

static int video_outputsw_set(int status)
{}

static int video_autosw_get(void)
{}

static int video_autosw_set(int enable)
{}

static int video_outputsw_cycle(void)
{}

static int video_expand_toggle(void)
{}

static int video_read(struct seq_file *m)
{}

static int video_write(char *buf)
{}

static struct ibm_struct video_driver_data =;

#endif /* CONFIG_THINKPAD_ACPI_VIDEO */

/*************************************************************************
 * Keyboard backlight subdriver
 */

static enum led_brightness kbdlight_brightness;
static DEFINE_MUTEX(kbdlight_mutex);

static int kbdlight_set_level(int level)
{}

static int kbdlight_get_level(void)
{}

static bool kbdlight_is_supported(void)
{}

static int kbdlight_sysfs_set(struct led_classdev *led_cdev,
			enum led_brightness brightness)
{}

static enum led_brightness kbdlight_sysfs_get(struct led_classdev *led_cdev)
{}

static struct tpacpi_led_classdev tpacpi_led_kbdlight =;

static int __init kbdlight_init(struct ibm_init_struct *iibm)
{}

static void kbdlight_exit(void)
{}

static int kbdlight_set_level_and_update(int level)
{}

static int kbdlight_read(struct seq_file *m)
{}

static int kbdlight_write(char *buf)
{}

static void kbdlight_suspend(void)
{}

static void kbdlight_resume(void)
{}

static struct ibm_struct kbdlight_driver_data =;

/*************************************************************************
 * Light (thinklight) subdriver
 */

TPACPI_HANDLE();	/* A21e, A2xm/p, T20-22, X20-21 */
TPACPI_HANDLE();		/* G4x */

static int light_get_status(void)
{}

static int light_set_status(int status)
{}

static int light_sysfs_set(struct led_classdev *led_cdev,
			enum led_brightness brightness)
{}

static enum led_brightness light_sysfs_get(struct led_classdev *led_cdev)
{}

static struct tpacpi_led_classdev tpacpi_led_thinklight =;

static int __init light_init(struct ibm_init_struct *iibm)
{}

static void light_exit(void)
{}

static int light_read(struct seq_file *m)
{}

static int light_write(char *buf)
{}

static struct ibm_struct light_driver_data =;

/*************************************************************************
 * CMOS subdriver
 */

/* sysfs cmos_command -------------------------------------------------- */
static ssize_t cmos_command_store(struct device *dev,
			    struct device_attribute *attr,
			    const char *buf, size_t count)
{}

static DEVICE_ATTR_WO(cmos_command);

static struct attribute *cmos_attributes[] =;

static umode_t cmos_attr_is_visible(struct kobject *kobj,
				    struct attribute *attr, int n)
{}

static const struct attribute_group cmos_attr_group =;

/* --------------------------------------------------------------------- */

static int __init cmos_init(struct ibm_init_struct *iibm)
{}

static int cmos_read(struct seq_file *m)
{}

static int cmos_write(char *buf)
{}

static struct ibm_struct cmos_driver_data =;

/*************************************************************************
 * LED subdriver
 */

enum led_access_mode {};

enum {};

static enum led_access_mode led_supported;

static acpi_handle led_handle;

#define TPACPI_LED_NUMLEDS
static struct tpacpi_led_classdev *tpacpi_leds;
static enum led_status_t tpacpi_led_state_cache[TPACPI_LED_NUMLEDS];
static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] =;
#define TPACPI_SAFE_LEDS

static inline bool tpacpi_is_led_restricted(const unsigned int led)
{}

static int led_get_status(const unsigned int led)
{}

static int led_set_status(const unsigned int led,
			  const enum led_status_t ledstatus)
{}

static int led_sysfs_set(struct led_classdev *led_cdev,
			enum led_brightness brightness)
{}

static int led_sysfs_blink_set(struct led_classdev *led_cdev,
			unsigned long *delay_on, unsigned long *delay_off)
{}

static enum led_brightness led_sysfs_get(struct led_classdev *led_cdev)
{}

static void led_exit(void)
{}

static int __init tpacpi_init_led(unsigned int led)
{}

static const struct tpacpi_quirk led_useful_qtable[] __initconst =;

static enum led_access_mode __init led_init_detect_mode(void)
{}

static int __init led_init(struct ibm_init_struct *iibm)
{}

#define str_led_status(s)

static int led_read(struct seq_file *m)
{}

static int led_write(char *buf)
{}

static struct ibm_struct led_driver_data =;

/*************************************************************************
 * Beep subdriver
 */

TPACPI_HANDLE();	/* all except R30, R31 */

#define TPACPI_BEEP_Q1

static const struct tpacpi_quirk beep_quirk_table[] __initconst =;

static int __init beep_init(struct ibm_init_struct *iibm)
{}

static int beep_read(struct seq_file *m)
{}

static int beep_write(char *buf)
{}

static struct ibm_struct beep_driver_data =;

/*************************************************************************
 * Thermal subdriver
 */

enum thermal_access_mode {};

enum {};


#define TPACPI_MAX_THERMAL_SENSORS
struct ibm_thermal_sensors_struct {};

static const struct tpacpi_quirk thermal_quirk_table[] __initconst =;

static enum thermal_access_mode thermal_read_mode;
static bool thermal_use_labels;
static bool thermal_with_ns_address;	/* Non-standard thermal reg address */

/* Function to check thermal read mode */
static enum thermal_access_mode __init thermal_read_mode_check(void)
{}

/* idx is zero-based */
static int thermal_get_sensor(int idx, s32 *value)
{}

static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s)
{}

static void thermal_dump_all_sensors(void)
{}

/* sysfs temp##_input -------------------------------------------------- */

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

#define THERMAL_SENSOR_ATTR_TEMP

static struct sensor_device_attribute sensor_dev_attr_thermal_temp_input[] =;

#define THERMAL_ATTRS

static struct attribute *thermal_temp_input_attr[] =;

#define to_dev_attr(_attr)

static umode_t thermal_attr_is_visible(struct kobject *kobj,
				       struct attribute *attr, int n)
{}

static const struct attribute_group thermal_attr_group =;

#undef THERMAL_SENSOR_ATTR_TEMP
#undef THERMAL_ATTRS

static ssize_t temp1_label_show(struct device *dev, struct device_attribute *attr, char *buf)
{}
static DEVICE_ATTR_RO(temp1_label);

static ssize_t temp2_label_show(struct device *dev, struct device_attribute *attr, char *buf)
{}
static DEVICE_ATTR_RO(temp2_label);

static struct attribute *temp_label_attributes[] =;

static umode_t temp_label_attr_is_visible(struct kobject *kobj,
					  struct attribute *attr, int n)
{}

static const struct attribute_group temp_label_attr_group =;

/* --------------------------------------------------------------------- */

static int __init thermal_init(struct ibm_init_struct *iibm)
{}

static int thermal_read(struct seq_file *m)
{}

static struct ibm_struct thermal_driver_data =;

/*************************************************************************
 * Backlight/brightness subdriver
 */

#define TPACPI_BACKLIGHT_DEV_NAME

/*
 * ThinkPads can read brightness from two places: EC HBRV (0x31), or
 * CMOS NVRAM byte 0x5E, bits 0-3.
 *
 * EC HBRV (0x31) has the following layout
 *   Bit 7: unknown function
 *   Bit 6: unknown function
 *   Bit 5: Z: honour scale changes, NZ: ignore scale changes
 *   Bit 4: must be set to zero to avoid problems
 *   Bit 3-0: backlight brightness level
 *
 * brightness_get_raw returns status data in the HBRV layout
 *
 * WARNING: The X61 has been verified to use HBRV for something else, so
 * this should be used _only_ on IBM ThinkPads, and maybe with some careful
 * testing on the very early *60 Lenovo models...
 */

enum {};

enum tpacpi_brightness_access_mode {};

static struct backlight_device *ibm_backlight_device;

static enum tpacpi_brightness_access_mode brightness_mode =;

static unsigned int brightness_enable =; /* 2 = auto, 0 = no, 1 = yes */

static struct mutex brightness_mutex;

/* NVRAM brightness access */
static unsigned int tpacpi_brightness_nvram_get(void)
{}

static void tpacpi_brightness_checkpoint_nvram(void)
{}


static int tpacpi_brightness_get_raw(int *status)
{}

/* do NOT call with illegal backlight level value */
static int tpacpi_brightness_set_ec(unsigned int value)
{}

static int tpacpi_brightness_set_ucmsstep(unsigned int value)
{}

/* May return EINTR which can always be mapped to ERESTARTSYS */
static int brightness_set(unsigned int value)
{}

/* sysfs backlight class ----------------------------------------------- */

static int brightness_update_status(struct backlight_device *bd)
{}

static int brightness_get(struct backlight_device *bd)
{}

static void tpacpi_brightness_notify_change(void)
{}

static const struct backlight_ops ibm_backlight_data =;

/* --------------------------------------------------------------------- */

static int __init tpacpi_evaluate_bcl(struct acpi_device *adev, void *not_used)
{}

/*
 * Call _BCL method of video device.  On some ThinkPads this will
 * switch the firmware to the ACPI brightness control mode.
 */

static int __init tpacpi_query_bcl_levels(acpi_handle handle)
{}


/*
 * Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map
 */
static unsigned int __init tpacpi_check_std_acpi_brightness_support(void)
{}

/*
 * These are only useful for models that have only one possibility
 * of GPU.  If the BIOS model handles both ATI and Intel, don't use
 * these quirks.
 */
#define TPACPI_BRGHT_Q_NOEC
#define TPACPI_BRGHT_Q_EC
#define TPACPI_BRGHT_Q_ASK

static const struct tpacpi_quirk brightness_quirk_table[] __initconst =;

/*
 * Returns < 0 for error, otherwise sets tp_features.bright_*
 * and bright_maxlvl.
 */
static void __init tpacpi_detect_brightness_capabilities(void)
{}

static int __init brightness_init(struct ibm_init_struct *iibm)
{}

static void brightness_suspend(void)
{}

static void brightness_shutdown(void)
{}

static void brightness_exit(void)
{}

static int brightness_read(struct seq_file *m)
{}

static int brightness_write(char *buf)
{}

static struct ibm_struct brightness_driver_data =;

/*************************************************************************
 * Volume subdriver
 */

/*
 * IBM ThinkPads have a simple volume controller with MUTE gating.
 * Very early Lenovo ThinkPads follow the IBM ThinkPad spec.
 *
 * Since the *61 series (and probably also the later *60 series), Lenovo
 * ThinkPads only implement the MUTE gate.
 *
 * EC register 0x30
 *   Bit 6: MUTE (1 mutes sound)
 *   Bit 3-0: Volume
 *   Other bits should be zero as far as we know.
 *
 * This is also stored in CMOS NVRAM, byte 0x60, bit 6 (MUTE), and
 * bits 3-0 (volume).  Other bits in NVRAM may have other functions,
 * such as bit 7 which is used to detect repeated presses of MUTE,
 * and we leave them unchanged.
 *
 * On newer Lenovo ThinkPads, the EC can automatically change the volume
 * in response to user input.  Unfortunately, this rarely works well.
 * The laptop changes the state of its internal MUTE gate and, on some
 * models, sends KEY_MUTE, causing any user code that responds to the
 * mute button to get confused.  The hardware MUTE gate is also
 * unnecessary, since user code can handle the mute button without
 * kernel or EC help.
 *
 * To avoid confusing userspace, we simply disable all EC-based mute
 * and volume controls when possible.
 */

#ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT

#define TPACPI_ALSA_DRVNAME
#define TPACPI_ALSA_SHRTNAME
#define TPACPI_ALSA_MIXERNAME

#if SNDRV_CARDS <= 32
#define DEFAULT_ALSA_IDX
#else
#define DEFAULT_ALSA_IDX
#endif
static int alsa_index =; /* last three slots */
static char *alsa_id =;
static bool alsa_enable =;

struct tpacpi_alsa_data {};

static struct snd_card *alsa_card;

enum {};

enum tpacpi_volume_access_mode {};

enum tpacpi_volume_capabilities {};

enum tpacpi_mute_btn_mode {};

static enum tpacpi_volume_access_mode volume_mode =;

static enum tpacpi_volume_capabilities volume_capabilities;
static bool volume_control_allowed;
static bool software_mute_requested =;
static bool software_mute_active;
static int software_mute_orig_mode;

/*
 * Used to syncronize writers to TP_EC_AUDIO and
 * TP_NVRAM_ADDR_MIXER, as we need to do read-modify-write
 */
static struct mutex volume_mutex;

static void tpacpi_volume_checkpoint_nvram(void)
{}

static int volume_get_status_ec(u8 *status)
{}

static int volume_get_status(u8 *status)
{}

static int volume_set_status_ec(const u8 status)
{}

static int volume_set_status(const u8 status)
{}

/* returns < 0 on error, 0 on no change, 1 on change */
static int __volume_set_mute_ec(const bool mute)
{}

static int volume_alsa_set_mute(const bool mute)
{}

static int volume_set_mute(const bool mute)
{}

/* returns < 0 on error, 0 on no change, 1 on change */
static int __volume_set_volume_ec(const u8 vol)
{}

static int volume_set_software_mute(bool startup)
{}

static void volume_exit_software_mute(void)
{}

static int volume_alsa_set_volume(const u8 vol)
{}

static void volume_alsa_notify_change(void)
{}

static int volume_alsa_vol_info(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_info *uinfo)
{}

static int volume_alsa_vol_get(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{}

static int volume_alsa_vol_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{}

#define volume_alsa_mute_info

static int volume_alsa_mute_get(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{}

static int volume_alsa_mute_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{}

static struct snd_kcontrol_new volume_alsa_control_vol __initdata =;

static struct snd_kcontrol_new volume_alsa_control_mute __initdata =;

static void volume_suspend(void)
{}

static void volume_resume(void)
{}

static void volume_shutdown(void)
{}

static void volume_exit(void)
{}

static int __init volume_create_alsa_mixer(void)
{}

#define TPACPI_VOL_Q_MUTEONLY
#define TPACPI_VOL_Q_LEVEL

static const struct tpacpi_quirk volume_quirk_table[] __initconst =;

static int __init volume_init(struct ibm_init_struct *iibm)
{}

static int volume_read(struct seq_file *m)
{}

static int volume_write(char *buf)
{}

static struct ibm_struct volume_driver_data =;

#else /* !CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */

#define alsa_card

static inline void volume_alsa_notify_change(void)
{
}

static int __init volume_init(struct ibm_init_struct *iibm)
{
	pr_info("volume: disabled as there is no ALSA support in this kernel\n");

	return -ENODEV;
}

static struct ibm_struct volume_driver_data = {
	.name = "volume",
};

#endif /* CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */

/*************************************************************************
 * Fan subdriver
 */

/*
 * FAN ACCESS MODES
 *
 * TPACPI_FAN_RD_ACPI_GFAN:
 * 	ACPI GFAN method: returns fan level
 *
 * 	see TPACPI_FAN_WR_ACPI_SFAN
 * 	EC 0x2f (HFSP) not available if GFAN exists
 *
 * TPACPI_FAN_WR_ACPI_SFAN:
 * 	ACPI SFAN method: sets fan level, 0 (stop) to 7 (max)
 *
 * 	EC 0x2f (HFSP) might be available *for reading*, but do not use
 * 	it for writing.
 *
 * TPACPI_FAN_RD_ACPI_FANG:
 * 	ACPI FANG method: returns fan control register
 *
 *	Takes one parameter which is 0x8100 plus the offset to EC memory
 *	address 0xf500 and returns the byte at this address.
 *
 *	0xf500:
 *		When the value is less than 9 automatic mode is enabled
 *	0xf502:
 *		Contains the current fan speed from 0-100%
 *	0xf506:
 *		Bit 7 has to be set in order to enable manual control by
 *		writing a value >= 9 to 0xf500
 *
 * TPACPI_FAN_WR_ACPI_FANW:
 * 	ACPI FANW method: sets fan control registers
 *
 * 	Takes 0x8100 plus the offset to EC memory address 0xf500 and the
 * 	value to be written there as parameters.
 *
 *	see TPACPI_FAN_RD_ACPI_FANG
 *
 * TPACPI_FAN_WR_TPEC:
 * 	ThinkPad EC register 0x2f (HFSP): fan control loop mode
 * 	Supported on almost all ThinkPads
 *
 * 	Fan speed changes of any sort (including those caused by the
 * 	disengaged mode) are usually done slowly by the firmware as the
 * 	maximum amount of fan duty cycle change per second seems to be
 * 	limited.
 *
 * 	Reading is not available if GFAN exists.
 * 	Writing is not available if SFAN exists.
 *
 * 	Bits
 *	 7	automatic mode engaged;
 *  		(default operation mode of the ThinkPad)
 * 		fan level is ignored in this mode.
 *	 6	full speed mode (takes precedence over bit 7);
 *		not available on all thinkpads.  May disable
 *		the tachometer while the fan controller ramps up
 *		the speed (which can take up to a few *minutes*).
 *		Speeds up fan to 100% duty-cycle, which is far above
 *		the standard RPM levels.  It is not impossible that
 *		it could cause hardware damage.
 *	5-3	unused in some models.  Extra bits for fan level
 *		in others, but still useless as all values above
 *		7 map to the same speed as level 7 in these models.
 *	2-0	fan level (0..7 usually)
 *			0x00 = stop
 * 			0x07 = max (set when temperatures critical)
 * 		Some ThinkPads may have other levels, see
 * 		TPACPI_FAN_WR_ACPI_FANS (X31/X40/X41)
 *
 *	FIRMWARE BUG: on some models, EC 0x2f might not be initialized at
 *	boot. Apparently the EC does not initialize it, so unless ACPI DSDT
 *	does so, its initial value is meaningless (0x07).
 *
 *	For firmware bugs, refer to:
 *	https://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues
 *
 * 	----
 *
 *	ThinkPad EC register 0x84 (LSB), 0x85 (MSB):
 *	Main fan tachometer reading (in RPM)
 *
 *	This register is present on all ThinkPads with a new-style EC, and
 *	it is known not to be present on the A21m/e, and T22, as there is
 *	something else in offset 0x84 according to the ACPI DSDT.  Other
 *	ThinkPads from this same time period (and earlier) probably lack the
 *	tachometer as well.
 *
 *	Unfortunately a lot of ThinkPads with new-style ECs but whose firmware
 *	was never fixed by IBM to report the EC firmware version string
 *	probably support the tachometer (like the early X models), so
 *	detecting it is quite hard.  We need more data to know for sure.
 *
 *	FIRMWARE BUG: always read 0x84 first, otherwise incorrect readings
 *	might result.
 *
 *	FIRMWARE BUG: may go stale while the EC is switching to full speed
 *	mode.
 *
 *	For firmware bugs, refer to:
 *	https://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues
 *
 *	----
 *
 *	ThinkPad EC register 0x31 bit 0 (only on select models)
 *
 *	When bit 0 of EC register 0x31 is zero, the tachometer registers
 *	show the speed of the main fan.  When bit 0 of EC register 0x31
 *	is one, the tachometer registers show the speed of the auxiliary
 *	fan.
 *
 *	Fan control seems to affect both fans, regardless of the state
 *	of this bit.
 *
 *	So far, only the firmware for the X60/X61 non-tablet versions
 *	seem to support this (firmware TP-7M).
 *
 * TPACPI_FAN_WR_ACPI_FANS:
 *	ThinkPad X31, X40, X41.  Not available in the X60.
 *
 *	FANS ACPI handle: takes three arguments: low speed, medium speed,
 *	high speed.  ACPI DSDT seems to map these three speeds to levels
 *	as follows: STOP LOW LOW MED MED HIGH HIGH HIGH HIGH
 *	(this map is stored on FAN0..FAN8 as "0,1,1,2,2,3,3,3,3")
 *
 * 	The speeds are stored on handles
 * 	(FANA:FAN9), (FANC:FANB), (FANE:FAND).
 *
 * 	There are three default speed sets, accessible as handles:
 * 	FS1L,FS1M,FS1H; FS2L,FS2M,FS2H; FS3L,FS3M,FS3H
 *
 * 	ACPI DSDT switches which set is in use depending on various
 * 	factors.
 *
 * 	TPACPI_FAN_WR_TPEC is also available and should be used to
 * 	command the fan.  The X31/X40/X41 seems to have 8 fan levels,
 * 	but the ACPI tables just mention level 7.
 *
 * TPACPI_FAN_RD_TPEC_NS:
 *	This mode is used for a few ThinkPads (L13 Yoga Gen2, X13 Yoga Gen2 etc.)
 *	that are using non-standard EC locations for reporting fan speeds.
 *	Currently these platforms only provide fan rpm reporting.
 *
 */

#define FAN_RPM_CAL_CONST

#define FAN_NS_CTRL_STATUS
#define FAN_NS_CTRL

enum {};

enum fan_status_access_mode {};

enum fan_control_access_mode {};

enum fan_control_commands {};

static bool fan_control_allowed;

static enum fan_status_access_mode fan_status_access_mode;
static enum fan_control_access_mode fan_control_access_mode;
static enum fan_control_commands fan_control_commands;

static u8 fan_control_initial_status;
static u8 fan_control_desired_level;
static u8 fan_control_resume_level;
static int fan_watchdog_maxinterval;

static bool fan_with_ns_addr;

static struct mutex fan_mutex;

static void fan_watchdog_fire(struct work_struct *ignored);
static DECLARE_DELAYED_WORK(fan_watchdog_task, fan_watchdog_fire);

TPACPI_HANDLE();	/* X31, X40, X41 */
TPACPI_HANDLE();			/* all others */
TPACPI_HANDLE();			/* all others */
TPACPI_HANDLE();			/* all others */
TPACPI_HANDLE();			/* all others */

/*
 * Unitialized HFSP quirk: ACPI DSDT and EC fail to initialize the
 * HFSP register at boot, so it contains 0x07 but the Thinkpad could
 * be in auto mode (0x80).
 *
 * This is corrected by any write to HFSP either by the driver, or
 * by the firmware.
 *
 * We assume 0x07 really means auto mode while this quirk is active,
 * as this is far more likely than the ThinkPad being in level 7,
 * which is only used by the firmware during thermal emergencies.
 *
 * Enable for TP-1Y (T43), TP-78 (R51e), TP-76 (R52),
 * TP-70 (T43, R52), which are known to be buggy.
 */

static void fan_quirk1_setup(void)
{}

static void fan_quirk1_handle(u8 *fan_status)
{}

/* Select main fan on X60/X61, NOOP on others */
static bool fan_select_fan1(void)
{}

/* Select secondary fan on X60/X61 */
static bool fan_select_fan2(void)
{}

static void fan_update_desired_level(u8 status)
{}

static int fan_get_status(u8 *status)
{}

static int fan_get_status_safe(u8 *status)
{}

static int fan_get_speed(unsigned int *speed)
{}

static int fan2_get_speed(unsigned int *speed)
{}

static int fan_set_level(int level)
{}

static int fan_set_level_safe(int level)
{}

static int fan_set_enable(void)
{}

static int fan_set_disable(void)
{}

static int fan_set_speed(int speed)
{}

static void fan_watchdog_reset(void)
{}

static void fan_watchdog_fire(struct work_struct *ignored)
{}

/*
 * SYSFS fan layout: hwmon compatible (device)
 *
 * pwm*_enable:
 * 	0: "disengaged" mode
 * 	1: manual mode
 * 	2: native EC "auto" mode (recommended, hardware default)
 *
 * pwm*: set speed in manual mode, ignored otherwise.
 * 	0 is level 0; 255 is level 7. Intermediate points done with linear
 * 	interpolation.
 *
 * fan*_input: tachometer reading, RPM
 *
 *
 * SYSFS fan layout: extensions
 *
 * fan_watchdog (driver):
 * 	fan watchdog interval in seconds, 0 disables (default), max 120
 */

/* sysfs fan pwm1_enable ----------------------------------------------- */
static ssize_t fan_pwm1_enable_show(struct device *dev,
				    struct device_attribute *attr,
				    char *buf)
{}

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

static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
		   fan_pwm1_enable_show, fan_pwm1_enable_store);

/* sysfs fan pwm1 ------------------------------------------------------ */
static ssize_t fan_pwm1_show(struct device *dev,
			     struct device_attribute *attr,
			     char *buf)
{}

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

static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, fan_pwm1_show, fan_pwm1_store);

/* sysfs fan fan1_input ------------------------------------------------ */
static ssize_t fan_fan1_input_show(struct device *dev,
			   struct device_attribute *attr,
			   char *buf)
{}

static DEVICE_ATTR(fan1_input, S_IRUGO, fan_fan1_input_show, NULL);

/* sysfs fan fan2_input ------------------------------------------------ */
static ssize_t fan_fan2_input_show(struct device *dev,
			   struct device_attribute *attr,
			   char *buf)
{}

static DEVICE_ATTR(fan2_input, S_IRUGO, fan_fan2_input_show, NULL);

/* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */
static ssize_t fan_watchdog_show(struct device_driver *drv, char *buf)
{}

static ssize_t fan_watchdog_store(struct device_driver *drv, const char *buf,
				  size_t count)
{}
static DRIVER_ATTR_RW(fan_watchdog);

/* --------------------------------------------------------------------- */

static struct attribute *fan_attributes[] =;

static umode_t fan_attr_is_visible(struct kobject *kobj, struct attribute *attr,
				   int n)
{}

static const struct attribute_group fan_attr_group =;

static struct attribute *fan_driver_attributes[] =;

static const struct attribute_group fan_driver_attr_group =;

#define TPACPI_FAN_Q1
#define TPACPI_FAN_2FAN
#define TPACPI_FAN_2CTL
#define TPACPI_FAN_NOFAN
#define TPACPI_FAN_NS

static const struct tpacpi_quirk fan_quirk_table[] __initconst =;

static int __init fan_init(struct ibm_init_struct *iibm)
{}

static void fan_exit(void)
{}

static void fan_suspend(void)
{}

static void fan_resume(void)
{}

static int fan_read(struct seq_file *m)
{}

static int fan_write_cmd_level(const char *cmd, int *rc)
{}

static int fan_write_cmd_enable(const char *cmd, int *rc)
{}

static int fan_write_cmd_disable(const char *cmd, int *rc)
{}

static int fan_write_cmd_speed(const char *cmd, int *rc)
{}

static int fan_write_cmd_watchdog(const char *cmd, int *rc)
{}

static int fan_write(char *buf)
{}

static struct ibm_struct fan_driver_data =;

/*************************************************************************
 * Mute LED subdriver
 */

#define TPACPI_LED_MAX

struct tp_led_table {};

static struct tp_led_table led_tables[TPACPI_LED_MAX] =;

static int mute_led_on_off(struct tp_led_table *t, bool state)
{}

static int tpacpi_led_set(int whichled, bool on)
{}

static int tpacpi_led_mute_set(struct led_classdev *led_cdev,
			       enum led_brightness brightness)
{}

static int tpacpi_led_micmute_set(struct led_classdev *led_cdev,
				  enum led_brightness brightness)
{}

static struct led_classdev mute_led_cdev[TPACPI_LED_MAX] =;

static int mute_led_init(struct ibm_init_struct *iibm)
{}

static void mute_led_exit(void)
{}

static void mute_led_resume(void)
{}

static struct ibm_struct mute_led_driver_data =;

/*
 * Battery Wear Control Driver
 * Contact: Ognjen Galic <[email protected]>
 */

/* Metadata */

#define GET_START
#define SET_START
#define GET_STOP
#define SET_STOP
#define GET_DISCHARGE
#define SET_DISCHARGE
#define GET_INHIBIT
#define SET_INHIBIT

enum {};

enum {};

enum {};

struct tpacpi_battery_data {};

struct tpacpi_battery_driver_data {};

static struct tpacpi_battery_driver_data battery_info;

/* ACPI helpers/functions/probes */

/*
 * This evaluates a ACPI method call specific to the battery
 * ACPI extension. The specifics are that an error is marked
 * in the 32rd bit of the response, so we just check that here.
 */
static acpi_status tpacpi_battery_acpi_eval(char *method, int *ret, int param)
{}

static int tpacpi_battery_get(int what, int battery, int *ret)
{}

static int tpacpi_battery_set(int what, int battery, int value)
{}

static int tpacpi_battery_set_validate(int what, int battery, int value)
{}

static int tpacpi_battery_probe(int battery)
{}

/* General helper functions */

static int tpacpi_battery_get_id(const char *battery_name)
{}

/* sysfs interface */

static ssize_t tpacpi_battery_store(int what,
				    struct device *dev,
				    const char *buf, size_t count)
{}

static ssize_t tpacpi_battery_show(int what,
				   struct device *dev,
				   char *buf)
{}

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

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

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

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

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

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

static DEVICE_ATTR_RW(charge_control_start_threshold);
static DEVICE_ATTR_RW(charge_control_end_threshold);
static DEVICE_ATTR_RW(charge_behaviour);
static struct device_attribute dev_attr_charge_start_threshold =;
static struct device_attribute dev_attr_charge_stop_threshold =;

static struct attribute *tpacpi_battery_attrs[] =;

ATTRIBUTE_GROUPS();

/* ACPI battery hooking */

static int tpacpi_battery_add(struct power_supply *battery, struct acpi_battery_hook *hook)
{}

static int tpacpi_battery_remove(struct power_supply *battery, struct acpi_battery_hook *hook)
{}

static struct acpi_battery_hook battery_hook =;

/* Subdriver init/exit */

static const struct tpacpi_quirk battery_quirk_table[] __initconst =;

static int __init tpacpi_battery_init(struct ibm_init_struct *ibm)
{}

static void tpacpi_battery_exit(void)
{}

static struct ibm_struct battery_driver_data =;

/*************************************************************************
 * LCD Shadow subdriver, for the Lenovo PrivacyGuard feature
 */

static struct drm_privacy_screen *lcdshadow_dev;
static acpi_handle lcdshadow_get_handle;
static acpi_handle lcdshadow_set_handle;

static int lcdshadow_set_sw_state(struct drm_privacy_screen *priv,
				  enum drm_privacy_screen_status state)
{}

static void lcdshadow_get_hw_state(struct drm_privacy_screen *priv)
{}

static const struct drm_privacy_screen_ops lcdshadow_ops =;

static int tpacpi_lcdshadow_init(struct ibm_init_struct *iibm)
{}

static void lcdshadow_exit(void)
{}

static void lcdshadow_resume(void)
{}

static int lcdshadow_read(struct seq_file *m)
{}

static int lcdshadow_write(char *buf)
{}

static struct ibm_struct lcdshadow_driver_data =;

/*************************************************************************
 * Thinkpad sensor interfaces
 */

#define DYTC_CMD_QUERY
#define DYTC_QUERY_ENABLE_BIT
#define DYTC_QUERY_SUBREV_BIT
#define DYTC_QUERY_REV_BIT

#define DYTC_CMD_GET
#define DYTC_GET_LAPMODE_BIT

#define PALMSENSOR_PRESENT_BIT
#define PALMSENSOR_ON_BIT

static bool has_palmsensor;
static bool has_lapsensor;
static bool palm_state;
static bool lap_state;
static int dytc_version;

static int dytc_command(int command, int *output)
{}

static int lapsensor_get(bool *present, bool *state)
{}

static int palmsensor_get(bool *present, bool *state)
{}

static void lapsensor_refresh(void)
{}

static void palmsensor_refresh(void)
{}

static ssize_t dytc_lapmode_show(struct device *dev,
					struct device_attribute *attr,
					char *buf)
{}
static DEVICE_ATTR_RO(dytc_lapmode);

static ssize_t palmsensor_show(struct device *dev,
					struct device_attribute *attr,
					char *buf)
{}
static DEVICE_ATTR_RO(palmsensor);

static struct attribute *proxsensor_attributes[] =;

static umode_t proxsensor_attr_is_visible(struct kobject *kobj,
					  struct attribute *attr, int n)
{}

static const struct attribute_group proxsensor_attr_group =;

static int tpacpi_proxsensor_init(struct ibm_init_struct *iibm)
{}

static struct ibm_struct proxsensor_driver_data =;

/*************************************************************************
 * DYTC Platform Profile interface
 */

#define DYTC_CMD_SET
#define DYTC_CMD_MMC_GET
#define DYTC_CMD_RESET

#define DYTC_CMD_FUNC_CAP
#define DYTC_FC_MMC
#define DYTC_FC_PSC
#define DYTC_FC_AMT

#define DYTC_GET_FUNCTION_BIT
#define DYTC_GET_MODE_BIT

#define DYTC_SET_FUNCTION_BIT
#define DYTC_SET_MODE_BIT
#define DYTC_SET_VALID_BIT

#define DYTC_FUNCTION_STD
#define DYTC_FUNCTION_CQL
#define DYTC_FUNCTION_MMC
#define DYTC_FUNCTION_PSC
#define DYTC_FUNCTION_AMT

#define DYTC_MODE_AMT_ENABLE
#define DYTC_MODE_AMT_DISABLE

#define DYTC_MODE_MMC_PERFORM
#define DYTC_MODE_MMC_LOWPOWER
#define DYTC_MODE_MMC_BALANCE
#define DYTC_MODE_MMC_DEFAULT

#define DYTC_MODE_PSC_LOWPOWER
#define DYTC_MODE_PSC_BALANCE
#define DYTC_MODE_PSC_PERFORM

#define DYTC_ERR_MASK
#define DYTC_ERR_SUCCESS

#define DYTC_SET_COMMAND(function, mode, on)

#define DYTC_DISABLE_CQL
#define DYTC_ENABLE_CQL
static int dytc_control_amt(bool enable);
static bool dytc_amt_active;

static enum platform_profile_option dytc_current_profile;
static atomic_t dytc_ignore_event =;
static DEFINE_MUTEX(dytc_mutex);
static int dytc_capabilities;
static bool dytc_mmc_get_available;
static int profile_force;

static int convert_dytc_to_profile(int funcmode, int dytcmode,
		enum platform_profile_option *profile)
{}

static int convert_profile_to_dytc(enum platform_profile_option profile, int *perfmode)
{}

/*
 * dytc_profile_get: Function to register with platform_profile
 * handler. Returns current platform profile.
 */
static int dytc_profile_get(struct platform_profile_handler *pprof,
			    enum platform_profile_option *profile)
{}

static int dytc_control_amt(bool enable)
{}

/*
 * Helper function - check if we are in CQL mode and if we are
 *  -  disable CQL,
 *  - run the command
 *  - enable CQL
 *  If not in CQL mode, just run the command
 */
static int dytc_cql_command(int command, int *output)
{}

/*
 * dytc_profile_set: Function to register with platform_profile
 * handler. Sets current platform profile.
 */
static int dytc_profile_set(struct platform_profile_handler *pprof,
			    enum platform_profile_option profile)
{}

static void dytc_profile_refresh(void)
{}

static struct platform_profile_handler dytc_profile =;

static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm)
{}

static void dytc_profile_exit(void)
{}

static struct ibm_struct  dytc_profile_driver_data =;

/*************************************************************************
 * Keyboard language interface
 */

struct keyboard_lang_data {};

static const struct keyboard_lang_data keyboard_lang_data[] =;

static int set_keyboard_lang_command(int command)
{}

static int get_keyboard_lang(int *output)
{}

/* sysfs keyboard language entry */
static ssize_t keyboard_lang_show(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{}

static ssize_t keyboard_lang_store(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
{}
static DEVICE_ATTR_RW(keyboard_lang);

static struct attribute *kbdlang_attributes[] =;

static umode_t kbdlang_attr_is_visible(struct kobject *kobj,
				       struct attribute *attr, int n)
{}

static const struct attribute_group kbdlang_attr_group =;

static int tpacpi_kbdlang_init(struct ibm_init_struct *iibm)
{}

static struct ibm_struct kbdlang_driver_data =;

/*************************************************************************
 * DPRC(Dynamic Power Reduction Control) subdriver, for the Lenovo WWAN
 * and WLAN feature.
 */
#define DPRC_GET_WWAN_ANTENNA_TYPE
#define DPRC_WWAN_ANTENNA_TYPE_A_BIT
#define DPRC_WWAN_ANTENNA_TYPE_B_BIT
static bool has_antennatype;
static int wwan_antennatype;

static int dprc_command(int command, int *output)
{}

static int get_wwan_antenna(int *wwan_antennatype)
{}

/* sysfs wwan antenna type entry */
static ssize_t wwan_antenna_type_show(struct device *dev,
					struct device_attribute *attr,
					char *buf)
{}
static DEVICE_ATTR_RO(wwan_antenna_type);

static struct attribute *dprc_attributes[] =;

static umode_t dprc_attr_is_visible(struct kobject *kobj,
				    struct attribute *attr, int n)
{}

static const struct attribute_group dprc_attr_group =;

static int tpacpi_dprc_init(struct ibm_init_struct *iibm)
{}

static struct ibm_struct dprc_driver_data =;

/*
 * Auxmac
 *
 * This auxiliary mac address is enabled in the bios through the
 * MAC Address Pass-through feature. In most cases, there are three
 * possibilities: Internal Mac, Second Mac, and disabled.
 *
 */

#define AUXMAC_LEN
#define AUXMAC_START
#define AUXMAC_STRLEN
#define AUXMAC_BEGIN_MARKER
#define AUXMAC_END_MARKER

static char auxmac[AUXMAC_LEN + 1];

static int auxmac_init(struct ibm_init_struct *iibm)
{}

static struct ibm_struct auxmac_data =;

static DEVICE_STRING_ATTR_RO(auxmac, 0444, auxmac);

static umode_t auxmac_attr_is_visible(struct kobject *kobj,
				      struct attribute *attr, int n)
{}

static struct attribute *auxmac_attributes[] =;

static const struct attribute_group auxmac_attr_group =;

/* --------------------------------------------------------------------- */

static struct attribute *tpacpi_driver_attributes[] =;

#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
static umode_t tpacpi_attr_is_visible(struct kobject *kobj,
				      struct attribute *attr, int n)
{}
#endif

static const struct attribute_group tpacpi_driver_attr_group =;

static const struct attribute_group *tpacpi_driver_groups[] =;

static const struct attribute_group *tpacpi_groups[] =;

static const struct attribute_group *tpacpi_hwmon_groups[] =;

static const struct attribute_group *tpacpi_hwmon_driver_groups[] =;

/****************************************************************************
 ****************************************************************************
 *
 * Platform drivers
 *
 ****************************************************************************
 ****************************************************************************/

static struct platform_driver tpacpi_pdriver =;

static struct platform_driver tpacpi_hwmon_pdriver =;

/****************************************************************************
 ****************************************************************************
 *
 * Infrastructure
 *
 ****************************************************************************
 ****************************************************************************/

/*
 * HKEY event callout for other subdrivers go here
 * (yes, it is ugly, but it is quick, safe, and gets the job done
 */
static bool tpacpi_driver_event(const unsigned int hkey_event)
{}

/* --------------------------------------------------------------------- */

/* /proc support */
static struct proc_dir_entry *proc_dir;

/*
 * Module and infrastructure proble, init and exit handling
 */

static bool force_load;

#ifdef CONFIG_THINKPAD_ACPI_DEBUG
static const char * __init str_supported(int is_supported)
{}
#endif /* CONFIG_THINKPAD_ACPI_DEBUG */

static void ibm_exit(struct ibm_struct *ibm)
{}

static int __init ibm_init(struct ibm_init_struct *iibm)
{}

/* Probing */

static char __init tpacpi_parse_fw_id(const char * const s,
				      u32 *model, u16 *release)
{}

#define EC_FW_STRING_LEN

static void find_new_ec_fwstr(const struct dmi_header *dm, void *private)
{}

/* returns 0 - probe ok, or < 0 - probe error.
 * Probe ok doesn't mean thinkpad found.
 * On error, kfree() cleanup on tp->* is not performed, caller must do it */
static int __must_check __init get_thinkpad_model_data(
						struct thinkpad_id_data *tp)
{}

static int __init probe_for_thinkpad(void)
{}

static void __init thinkpad_acpi_init_banner(void)
{}

/* Module init, exit, parameters */

static struct ibm_init_struct ibms_init[] __initdata =;

static int __init set_ibm_param(const char *val, const struct kernel_param *kp)
{}

module_param(experimental, int, 0444);
MODULE_PARM_DESC();

module_param_named(debug, dbg_level, uint, 0);
MODULE_PARM_DESC();

module_param(force_load, bool, 0444);
MODULE_PARM_DESC();

module_param_named(fan_control, fan_control_allowed, bool, 0444);
MODULE_PARM_DESC();

module_param_named(brightness_mode, brightness_mode, uint, 0444);
MODULE_PARM_DESC();

module_param(brightness_enable, uint, 0444);
MODULE_PARM_DESC();

#ifdef CONFIG_THINKPAD_ACPI_ALSA_SUPPORT
module_param_named(volume_mode, volume_mode, uint, 0444);
MODULE_PARM_DESC();

module_param_named(volume_capabilities, volume_capabilities, uint, 0444);
MODULE_PARM_DESC();

module_param_named(volume_control, volume_control_allowed, bool, 0444);
MODULE_PARM_DESC();

module_param_named(software_mute, software_mute_requested, bool, 0444);
MODULE_PARM_DESC();

/* ALSA module API parameters */
module_param_named(index, alsa_index, int, 0444);
MODULE_PARM_DESC();
module_param_named(id, alsa_id, charp, 0444);
MODULE_PARM_DESC();
module_param_named(enable, alsa_enable, bool, 0444);
MODULE_PARM_DESC();
#endif /* CONFIG_THINKPAD_ACPI_ALSA_SUPPORT */

/* The module parameter can't be read back, that's why 0 is used here */
#define TPACPI_PARAM(feature)

TPACPI_PARAM(hotkey);
TPACPI_PARAM(bluetooth);
TPACPI_PARAM(video);
TPACPI_PARAM(light);
TPACPI_PARAM(cmos);
TPACPI_PARAM(led);
TPACPI_PARAM(beep);
TPACPI_PARAM(brightness);
TPACPI_PARAM(volume);
TPACPI_PARAM(fan);

#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
module_param(dbg_wlswemul, uint, 0444);
MODULE_PARM_DESC();
module_param_named(wlsw_state, tpacpi_wlsw_emulstate, bool, 0);
MODULE_PARM_DESC();

module_param(dbg_bluetoothemul, uint, 0444);
MODULE_PARM_DESC();
module_param_named(bluetooth_state, tpacpi_bluetooth_emulstate, bool, 0);
MODULE_PARM_DESC();

module_param(dbg_wwanemul, uint, 0444);
MODULE_PARM_DESC();
module_param_named(wwan_state, tpacpi_wwan_emulstate, bool, 0);
MODULE_PARM_DESC();

module_param(dbg_uwbemul, uint, 0444);
MODULE_PARM_DESC();
module_param_named(uwb_state, tpacpi_uwb_emulstate, bool, 0);
MODULE_PARM_DESC();
#endif

module_param(profile_force, int, 0444);
MODULE_PARM_DESC();

static void thinkpad_acpi_module_exit(void)
{}


static int __init thinkpad_acpi_module_init(void)
{}

MODULE_ALIAS();

/*
 * This will autoload the driver in almost every ThinkPad
 * in widespread use.
 *
 * Only _VERY_ old models, like the 240, 240x and 570 lack
 * the HKEY event interface.
 */
MODULE_DEVICE_TABLE(acpi, ibm_htk_device_ids);

/*
 * DMI matching for module autoloading
 *
 * See https://thinkwiki.org/wiki/List_of_DMI_IDs
 * See https://thinkwiki.org/wiki/BIOS_Upgrade_Downloads
 *
 * Only models listed in thinkwiki will be supported, so add yours
 * if it is not there yet.
 */
#define IBM_BIOS_MODULE_ALIAS(__type)

/* Ancient thinkpad BIOSes have to be identified by
 * BIOS type or model number, and there are far less
 * BIOS types than model numbers... */
IBM_BIOS_MODULE_ALIAS();		/* 570, 570e */

MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_VERSION();
MODULE_LICENSE();

module_init();
module_exit(thinkpad_acpi_module_exit);