linux/drivers/input/serio/i8042.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 *  i8042 keyboard and mouse controller driver for Linux
 *
 *  Copyright (c) 1999-2004 Vojtech Pavlik
 */


#define pr_fmt(fmt)

#include <linux/types.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/serio.h>
#include <linux/err.h>
#include <linux/rcupdate.h>
#include <linux/platform_device.h>
#include <linux/i8042.h>
#include <linux/slab.h>
#include <linux/suspend.h>
#include <linux/property.h>

#include <asm/io.h>

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

static bool i8042_nokbd;
module_param_named(nokbd, i8042_nokbd, bool, 0);
MODULE_PARM_DESC();

static bool i8042_noaux;
module_param_named(noaux, i8042_noaux, bool, 0);
MODULE_PARM_DESC();

static bool i8042_nomux;
module_param_named(nomux, i8042_nomux, bool, 0);
MODULE_PARM_DESC();

static bool i8042_unlock;
module_param_named(unlock, i8042_unlock, bool, 0);
MODULE_PARM_DESC();

static bool i8042_probe_defer;
module_param_named(probe_defer, i8042_probe_defer, bool, 0);
MODULE_PARM_DESC();

enum i8042_controller_reset_mode {};
static enum i8042_controller_reset_mode i8042_reset =;
static int i8042_set_reset(const char *val, const struct kernel_param *kp)
{}

static const struct kernel_param_ops param_ops_reset_param =;
#define param_check_reset_param(name, p)
module_param_named(reset, i8042_reset, reset_param, 0);
MODULE_PARM_DESC();

static bool i8042_direct;
module_param_named(direct, i8042_direct, bool, 0);
MODULE_PARM_DESC();

static bool i8042_dumbkbd;
module_param_named(dumbkbd, i8042_dumbkbd, bool, 0);
MODULE_PARM_DESC();

static bool i8042_noloop;
module_param_named(noloop, i8042_noloop, bool, 0);
MODULE_PARM_DESC();

static bool i8042_notimeout;
module_param_named(notimeout, i8042_notimeout, bool, 0);
MODULE_PARM_DESC();

static bool i8042_kbdreset;
module_param_named(kbdreset, i8042_kbdreset, bool, 0);
MODULE_PARM_DESC();

#ifdef CONFIG_X86
static bool i8042_dritek;
module_param_named(dritek, i8042_dritek, bool, 0);
MODULE_PARM_DESC();
#endif

#ifdef CONFIG_PNP
static bool i8042_nopnp;
module_param_named(nopnp, i8042_nopnp, bool, 0);
MODULE_PARM_DESC();
#endif

static bool i8042_forcenorestore;
module_param_named(forcenorestore, i8042_forcenorestore, bool, 0);
MODULE_PARM_DESC();

#define DEBUG
#ifdef DEBUG
static bool i8042_debug;
module_param_named(debug, i8042_debug, bool, 0600);
MODULE_PARM_DESC();

static bool i8042_unmask_kbd_data;
module_param_named(unmask_kbd_data, i8042_unmask_kbd_data, bool, 0600);
MODULE_PARM_DESC();
#endif

static bool i8042_present;
static bool i8042_bypass_aux_irq_test;
static char i8042_kbd_firmware_id[128];
static char i8042_aux_firmware_id[128];
static struct fwnode_handle *i8042_kbd_fwnode;

#include "i8042.h"

/*
 * i8042_lock protects serialization between i8042_command and
 * the interrupt handler.
 */
static DEFINE_SPINLOCK(i8042_lock);

/*
 * Writers to AUX and KBD ports as well as users issuing i8042_command
 * directly should acquire i8042_mutex (by means of calling
 * i8042_lock_chip() and i8042_unlock_chip() helpers) to ensure that
 * they do not disturb each other (unfortunately in many i8042
 * implementations write to one of the ports will immediately abort
 * command that is being processed by another port).
 */
static DEFINE_MUTEX(i8042_mutex);

struct i8042_port {};

#define I8042_KBD_PORT_NO
#define I8042_AUX_PORT_NO
#define I8042_MUX_PORT_NO
#define I8042_NUM_PORTS

static struct i8042_port i8042_ports[I8042_NUM_PORTS];

static unsigned char i8042_initial_ctr;
static unsigned char i8042_ctr;
static bool i8042_mux_present;
static bool i8042_kbd_irq_registered;
static bool i8042_aux_irq_registered;
static unsigned char i8042_suppress_kbd_ack;
static struct platform_device *i8042_platform_device;
static struct notifier_block i8042_kbd_bind_notifier_block;

static irqreturn_t i8042_interrupt(int irq, void *dev_id);
static bool (*i8042_platform_filter)(unsigned char data, unsigned char str,
				     struct serio *serio);

void i8042_lock_chip(void)
{}
EXPORT_SYMBOL();

void i8042_unlock_chip(void)
{}
EXPORT_SYMBOL();

int i8042_install_filter(bool (*filter)(unsigned char data, unsigned char str,
					struct serio *serio))
{}
EXPORT_SYMBOL();

int i8042_remove_filter(bool (*filter)(unsigned char data, unsigned char str,
				       struct serio *port))
{}
EXPORT_SYMBOL();

/*
 * The i8042_wait_read() and i8042_wait_write functions wait for the i8042 to
 * be ready for reading values from it / writing values to it.
 * Called always with i8042_lock held.
 */

static int i8042_wait_read(void)
{}

static int i8042_wait_write(void)
{}

/*
 * i8042_flush() flushes all data that may be in the keyboard and mouse buffers
 * of the i8042 down the toilet.
 */

static int i8042_flush(void)
{}

/*
 * i8042_command() executes a command on the i8042. It also sends the input
 * parameter(s) of the commands to it, and receives the output value(s). The
 * parameters are to be stored in the param array, and the output is placed
 * into the same array. The number of the parameters and output values is
 * encoded in bits 8-11 of the command number.
 */

static int __i8042_command(unsigned char *param, int command)
{}

int i8042_command(unsigned char *param, int command)
{}
EXPORT_SYMBOL();

/*
 * i8042_kbd_write() sends a byte out through the keyboard interface.
 */

static int i8042_kbd_write(struct serio *port, unsigned char c)
{}

/*
 * i8042_aux_write() sends a byte out through the aux interface.
 */

static int i8042_aux_write(struct serio *serio, unsigned char c)
{}


/*
 * i8042_port_close attempts to clear AUX or KBD port state by disabling
 * and then re-enabling it.
 */

static void i8042_port_close(struct serio *serio)
{}

/*
 * i8042_start() is called by serio core when port is about to finish
 * registering. It will mark port as existing so i8042_interrupt can
 * start sending data through it.
 */
static int i8042_start(struct serio *serio)
{}

/*
 * i8042_stop() marks serio port as non-existing so i8042_interrupt
 * will not try to send data to the port that is about to go away.
 * The function is called by serio core as part of unregister procedure.
 */
static void i8042_stop(struct serio *serio)
{}

/*
 * i8042_filter() filters out unwanted bytes from the input data stream.
 * It is called from i8042_interrupt and thus is running with interrupts
 * off and i8042_lock held.
 */
static bool i8042_filter(unsigned char data, unsigned char str,
			 struct serio *serio)
{}

/*
 * i8042_interrupt() is the most important function in this driver -
 * it handles the interrupts from the i8042, and sends incoming bytes
 * to the upper layers.
 */

static irqreturn_t i8042_interrupt(int irq, void *dev_id)
{}

/*
 * i8042_enable_kbd_port enables keyboard port on chip
 */

static int i8042_enable_kbd_port(void)
{}

/*
 * i8042_enable_aux_port enables AUX (mouse) port on chip
 */

static int i8042_enable_aux_port(void)
{}

/*
 * i8042_enable_mux_ports enables 4 individual AUX ports after
 * the controller has been switched into Multiplexed mode
 */

static int i8042_enable_mux_ports(void)
{}

/*
 * i8042_set_mux_mode checks whether the controller has an
 * active multiplexor and puts the chip into Multiplexed (true)
 * or Legacy (false) mode.
 */

static int i8042_set_mux_mode(bool multiplex, unsigned char *mux_version)
{}

/*
 * i8042_check_mux() checks whether the controller supports the PS/2 Active
 * Multiplexing specification by Synaptics, Phoenix, Insyde and
 * LCS/Telegraphics.
 */

static int i8042_check_mux(void)
{}

/*
 * The following is used to test AUX IRQ delivery.
 */
static struct completion i8042_aux_irq_delivered;
static bool i8042_irq_being_tested;

static irqreturn_t i8042_aux_test_irq(int irq, void *dev_id)
{}

/*
 * i8042_toggle_aux - enables or disables AUX port on i8042 via command and
 * verifies success by readinng CTR. Used when testing for presence of AUX
 * port.
 */
static int i8042_toggle_aux(bool on)
{}

/*
 * i8042_check_aux() applies as much paranoia as it can at detecting
 * the presence of an AUX interface.
 */

static int i8042_check_aux(void)
{}

static int i8042_controller_check(void)
{}

static int i8042_controller_selftest(void)
{}

/*
 * i8042_controller_init initializes the i8042 controller, and,
 * most importantly, sets it into non-xlated mode if that's
 * desired.
 */

static int i8042_controller_init(void)
{}


/*
 * Reset the controller and reset CRT to the original value set by BIOS.
 */

static void i8042_controller_reset(bool s2r_wants_reset)
{}


/*
 * i8042_panic_blink() will turn the keyboard LEDs on or off and is called
 * when kernel panics. Flashing LEDs is useful for users running X who may
 * not see the console and will help distinguishing panics from "real"
 * lockups.
 *
 * Note that DELAY has a limit of 10ms so we will not get stuck here
 * waiting for KBC to free up even if KBD interrupt is off
 */

#define DELAY

static long i8042_panic_blink(int state)
{}

#undef DELAY

#ifdef CONFIG_X86
static void i8042_dritek_enable(void)
{}
#endif

#ifdef CONFIG_PM

/*
 * Here we try to reset everything back to a state we had
 * before suspending.
 */

static int i8042_controller_resume(bool s2r_wants_reset)
{}

/*
 * Here we try to restore the original BIOS settings to avoid
 * upsetting it.
 */

static int i8042_pm_suspend(struct device *dev)
{}

static int i8042_pm_resume_noirq(struct device *dev)
{}

static int i8042_pm_resume(struct device *dev)
{}

static int i8042_pm_thaw(struct device *dev)
{}

static int i8042_pm_reset(struct device *dev)
{}

static int i8042_pm_restore(struct device *dev)
{}

static const struct dev_pm_ops i8042_pm_ops =;

#endif /* CONFIG_PM */

/*
 * We need to reset the 8042 back to original mode on system shutdown,
 * because otherwise BIOSes will be confused.
 */

static void i8042_shutdown(struct platform_device *dev)
{}

static int i8042_create_kbd_port(void)
{}

static int i8042_create_aux_port(int idx)
{}

static void i8042_free_kbd_port(void)
{}

static void i8042_free_aux_ports(void)
{}

static void i8042_register_ports(void)
{}

static void i8042_unregister_ports(void)
{}

static void i8042_free_irqs(void)
{}

static int i8042_setup_aux(void)
{}

static int i8042_setup_kbd(void)
{}

static int i8042_kbd_bind_notifier(struct notifier_block *nb,
				   unsigned long action, void *data)
{}

static int i8042_probe(struct platform_device *dev)
{}

static void i8042_remove(struct platform_device *dev)
{}

static struct platform_driver i8042_driver =;

static struct notifier_block i8042_kbd_bind_notifier_block =;

static int __init i8042_init(void)
{}

static void __exit i8042_exit(void)
{}

module_init();
module_exit(i8042_exit);