linux/drivers/platform/x86/hdaps.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * hdaps.c - driver for IBM's Hard Drive Active Protection System
 *
 * Copyright (C) 2005 Robert Love <[email protected]>
 * Copyright (C) 2005 Jesper Juhl <[email protected]>
 *
 * The HardDisk Active Protection System (hdaps) is present in IBM ThinkPads
 * starting with the R40, T41, and X40.  It provides a basic two-axis
 * accelerometer and other data, such as the device's temperature.
 *
 * This driver is based on the document by Mark A. Smith available at
 * http://www.almaden.ibm.com/cs/people/marksmith/tpaps.html and a lot of trial
 * and error.
 */

#define pr_fmt(fmt)

#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/kernel.h>
#include <linux/mutex.h>
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/dmi.h>
#include <linux/jiffies.h>
#include <linux/io.h>

#define HDAPS_LOW_PORT
#define HDAPS_NR_PORTS

#define HDAPS_PORT_STATE
#define HDAPS_PORT_YPOS
#define HDAPS_PORT_XPOS
#define HDAPS_PORT_TEMP1
#define HDAPS_PORT_YVAR
#define HDAPS_PORT_XVAR
#define HDAPS_PORT_TEMP2
#define HDAPS_PORT_UNKNOWN
#define HDAPS_PORT_KMACT

#define STATE_FRESH

#define KEYBD_MASK
#define MOUSE_MASK
#define KEYBD_ISSET(n)
#define MOUSE_ISSET(n)

#define INIT_TIMEOUT_MSECS
#define INIT_WAIT_MSECS

#define HDAPS_POLL_INTERVAL
#define HDAPS_INPUT_FUZZ
#define HDAPS_INPUT_FLAT

#define HDAPS_X_AXIS
#define HDAPS_Y_AXIS
#define HDAPS_BOTH_AXES

static struct platform_device *pdev;
static struct input_dev *hdaps_idev;
static unsigned int hdaps_invert;
static u8 km_activity;
static int rest_x;
static int rest_y;

static DEFINE_MUTEX(hdaps_mtx);

/*
 * __get_latch - Get the value from a given port.  Callers must hold hdaps_mtx.
 */
static inline u8 __get_latch(u16 port)
{}

/*
 * __check_latch - Check a port latch for a given value.  Returns zero if the
 * port contains the given value.  Callers must hold hdaps_mtx.
 */
static inline int __check_latch(u16 port, u8 val)
{}

/*
 * __wait_latch - Wait up to 100us for a port latch to get a certain value,
 * returning zero if the value is obtained.  Callers must hold hdaps_mtx.
 */
static int __wait_latch(u16 port, u8 val)
{}

/*
 * __device_refresh - request a refresh from the accelerometer.  Does not wait
 * for refresh to complete.  Callers must hold hdaps_mtx.
 */
static void __device_refresh(void)
{}

/*
 * __device_refresh_sync - request a synchronous refresh from the
 * accelerometer.  We wait for the refresh to complete.  Returns zero if
 * successful and nonzero on error.  Callers must hold hdaps_mtx.
 */
static int __device_refresh_sync(void)
{}

/*
 * __device_complete - indicate to the accelerometer that we are done reading
 * data, and then initiate an async refresh.  Callers must hold hdaps_mtx.
 */
static inline void __device_complete(void)
{}

/*
 * hdaps_readb_one - reads a byte from a single I/O port, placing the value in
 * the given pointer.  Returns zero on success or a negative error on failure.
 * Can sleep.
 */
static int hdaps_readb_one(unsigned int port, u8 *val)
{}

/* __hdaps_read_pair - internal lockless helper for hdaps_read_pair(). */
static int __hdaps_read_pair(unsigned int port1, unsigned int port2,
			     int *x, int *y)
{}

/*
 * hdaps_read_pair - reads the values from a pair of ports, placing the values
 * in the given pointers.  Returns zero on success.  Can sleep.
 */
static int hdaps_read_pair(unsigned int port1, unsigned int port2,
			   int *val1, int *val2)
{}

/*
 * hdaps_device_init - initialize the accelerometer.  Returns zero on success
 * and negative error code on failure.  Can sleep.
 */
static int hdaps_device_init(void)
{}


/* Device model stuff */

static int hdaps_probe(struct platform_device *dev)
{}

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

static SIMPLE_DEV_PM_OPS(hdaps_pm, NULL, hdaps_resume);

static struct platform_driver hdaps_driver =;

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

static void hdaps_mousedev_poll(struct input_dev *input_dev)
{}


/* Sysfs Files */

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

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

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

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

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

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

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

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

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

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

static DEVICE_ATTR(position, 0444, hdaps_position_show, NULL);
static DEVICE_ATTR(variance, 0444, hdaps_variance_show, NULL);
static DEVICE_ATTR(temp1, 0444, hdaps_temp1_show, NULL);
static DEVICE_ATTR(temp2, 0444, hdaps_temp2_show, NULL);
static DEVICE_ATTR(keyboard_activity, 0444, hdaps_keyboard_activity_show, NULL);
static DEVICE_ATTR(mouse_activity, 0444, hdaps_mouse_activity_show, NULL);
static DEVICE_ATTR(calibrate, 0644, hdaps_calibrate_show,hdaps_calibrate_store);
static DEVICE_ATTR(invert, 0644, hdaps_invert_show, hdaps_invert_store);

static struct attribute *hdaps_attributes[] =;

static const struct attribute_group hdaps_attribute_group =;


/* Module stuff */

/* hdaps_dmi_match - found a match.  return one, short-circuiting the hunt. */
static int __init hdaps_dmi_match(const struct dmi_system_id *id)
{}

/* hdaps_dmi_match_invert - found an inverted match. */
static int __init hdaps_dmi_match_invert(const struct dmi_system_id *id)
{}

#define HDAPS_DMI_MATCH_INVERT(vendor, model, axes)

#define HDAPS_DMI_MATCH_NORMAL(vendor, model)

/* Note that HDAPS_DMI_MATCH_NORMAL("ThinkPad T42") would match
   "ThinkPad T42p", so the order of the entries matters.
   If your ThinkPad is not recognized, please update to latest
   BIOS. This is especially the case for some R52 ThinkPads. */
static const struct dmi_system_id hdaps_whitelist[] __initconst =;

static int __init hdaps_init(void)
{}

static void __exit hdaps_exit(void)
{}

module_init();
module_exit(hdaps_exit);

module_param_named(invert, hdaps_invert, int, 0);
MODULE_PARM_DESC();

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