linux/drivers/platform/x86/panasonic-laptop.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 *  Panasonic HotKey and LCD brightness control driver
 *  (C) 2004 Hiroshi Miura <[email protected]>
 *  (C) 2004 NTT DATA Intellilink Co. http://www.intellilink.co.jp/
 *  (C) YOKOTA Hiroshi <yokota (at) netlab. is. tsukuba. ac. jp>
 *  (C) 2004 David Bronaugh <dbronaugh>
 *  (C) 2006-2008 Harald Welte <[email protected]>
 *
 *  derived from toshiba_acpi.c, Copyright (C) 2002-2004 John Belmonte
 *
 *---------------------------------------------------------------------------
 *
 * ChangeLog:
 *	Aug.18, 2020	Kenneth Chan <[email protected]>
 *		-v0.98	add platform devices for firmware brightness registers
 *			add support for battery charging threshold (eco mode)
 *			resolve hotkey double trigger
 *			add write support to mute
 *			fix sticky_key init bug
 *			fix naming of platform files for consistency with other
 *			modules
 *			split MODULE_AUTHOR() by one author per macro call
 *			replace ACPI prints with pr_*() macros
 *		-v0.97	add support for cdpower hardware switch
 *		-v0.96	merge Lucina's enhancement
 *			Jan.13, 2009 Martin Lucina <[email protected]>
 *				- add support for optical driver power in
 *				  Y and W series
 *
 *	Sep.23, 2008	Harald Welte <[email protected]>
 *		-v0.95	rename driver from drivers/acpi/pcc_acpi.c to
 *			drivers/misc/panasonic-laptop.c
 *
 * 	Jul.04, 2008	Harald Welte <[email protected]>
 * 		-v0.94	replace /proc interface with device attributes
 * 			support {set,get}keycode on th input device
 *
 *      Jun.27, 2008	Harald Welte <[email protected]>
 *      	-v0.92	merge with 2.6.26-rc6 input API changes
 *      		remove broken <= 2.6.15 kernel support
 *      		resolve all compiler warnings
 *      		various coding style fixes (checkpatch.pl)
 *      		add support for backlight api
 *      		major code restructuring
 *
 * 	Dac.28, 2007	Harald Welte <[email protected]>
 * 		-v0.91	merge with 2.6.24-rc6 ACPI changes
 *
 * 	Nov.04, 2006	Hiroshi Miura <[email protected]>
 * 		-v0.9	remove warning about section reference.
 * 			remove acpi_os_free
 * 			add /proc/acpi/pcc/brightness interface for HAL access
 * 			merge dbronaugh's enhancement
 * 			Aug.17, 2004 David Bronaugh (dbronaugh)
 *  				- Added screen brightness setting interface
 *				  Thanks to FreeBSD crew (acpi_panasonic.c)
 * 				  for the ideas I needed to accomplish it
 *
 *	May.29, 2006	Hiroshi Miura <[email protected]>
 *		-v0.8.4 follow to change keyinput structure
 *			thanks Fabian Yamaguchi <[email protected]>,
 *			Jacob Bower <[email protected]> and
 *			Hiroshi Yokota for providing solutions.
 *
 *	Oct.02, 2004	Hiroshi Miura <[email protected]>
 *		-v0.8.2	merge code of YOKOTA Hiroshi
 *					<[email protected]>.
 *			Add sticky key mode interface.
 *			Refactoring acpi_pcc_generate_keyinput().
 *
 *	Sep.15, 2004	Hiroshi Miura <[email protected]>
 *		-v0.8	Generate key input event on input subsystem.
 *			This is based on yet another driver written by
 *							Ryuta Nakanishi.
 *
 *	Sep.10, 2004	Hiroshi Miura <[email protected]>
 *		-v0.7	Change proc interface functions using seq_file
 *			facility as same as other ACPI drivers.
 *
 *	Aug.28, 2004	Hiroshi Miura <[email protected]>
 *		-v0.6.4 Fix a silly error with status checking
 *
 *	Aug.25, 2004	Hiroshi Miura <[email protected]>
 *		-v0.6.3 replace read_acpi_int by standard function
 *							acpi_evaluate_integer
 *			some clean up and make smart copyright notice.
 *			fix return value of pcc_acpi_get_key()
 *			fix checking return value of acpi_bus_register_driver()
 *
 *      Aug.22, 2004    David Bronaugh <[email protected]>
 *              -v0.6.2 Add check on ACPI data (num_sifr)
 *                      Coding style cleanups, better error messages/handling
 *			Fixed an off-by-one error in memory allocation
 *
 *      Aug.21, 2004    David Bronaugh <[email protected]>
 *              -v0.6.1 Fix a silly error with status checking
 *
 *      Aug.20, 2004    David Bronaugh <[email protected]>
 *              - v0.6  Correct brightness controls to reflect reality
 *                      based on information gleaned by Hiroshi Miura
 *                      and discussions with Hiroshi Miura
 *
 *	Aug.10, 2004	Hiroshi Miura <[email protected]>
 *		- v0.5  support LCD brightness control
 *			based on the disclosed information by MEI.
 *
 *	Jul.25, 2004	Hiroshi Miura <[email protected]>
 *		- v0.4  first post version
 *		        add function to retrive SIFR
 *
 *	Jul.24, 2004	Hiroshi Miura <[email protected]>
 *		- v0.3  get proper status of hotkey
 *
 *      Jul.22, 2004	Hiroshi Miura <[email protected]>
 *		- v0.2  add HotKey handler
 *
 *      Jul.17, 2004	Hiroshi Miura <[email protected]>
 *		- v0.1  start from toshiba_acpi driver written by John Belmonte
 */

#include <linux/acpi.h>
#include <linux/backlight.h>
#include <linux/bits.h>
#include <linux/ctype.h>
#include <linux/i8042.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/input/sparse-keymap.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/seq_file.h>
#include <linux/serio.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <acpi/video.h>

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

#define LOGPREFIX

/* Define ACPI PATHs */
/* Lets note hotkeys */
#define METHOD_HKEY_QUERY
#define METHOD_HKEY_SQTY
#define METHOD_HKEY_SINF
#define METHOD_HKEY_SSET
#define METHOD_ECWR
#define HKEY_NOTIFY
#define ECO_MODE_OFF
#define ECO_MODE_ON

#define ACPI_PCC_DRIVER_NAME
#define ACPI_PCC_DEVICE_NAME
#define ACPI_PCC_CLASS

#define ACPI_PCC_INPUT_PHYS

/* LCD_TYPEs: 0 = Normal, 1 = Semi-transparent
   ECO_MODEs: 0x03 = off, 0x83 = on
*/
enum SINF_BITS {};
/* R1 handles SINF_AC_CUR_BRIGHT as SINF_CUR_BRIGHT, doesn't know AC state */

static int acpi_pcc_hotkey_add(struct acpi_device *device);
static void acpi_pcc_hotkey_remove(struct acpi_device *device);
static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event);

static const struct acpi_device_id pcc_device_ids[] =;
MODULE_DEVICE_TABLE(acpi, pcc_device_ids);

#ifdef CONFIG_PM_SLEEP
static int acpi_pcc_hotkey_resume(struct device *dev);
#endif
static SIMPLE_DEV_PM_OPS(acpi_pcc_hotkey_pm, NULL, acpi_pcc_hotkey_resume);

static struct acpi_driver acpi_pcc_driver =;

static const struct key_entry panasonic_keymap[] =;

struct pcc_acpi {};

/*
 * On some Panasonic models the volume up / down / mute keys send duplicate
 * keypress events over the PS/2 kbd interface, filter these out.
 */
static bool panasonic_i8042_filter(unsigned char data, unsigned char str,
				   struct serio *port)
{}

/* method access functions */
static int acpi_pcc_write_sset(struct pcc_acpi *pcc, int func, int val)
{}

static inline int acpi_pcc_get_sqty(struct acpi_device *device)
{}

static int acpi_pcc_retrieve_biosdata(struct pcc_acpi *pcc)
{}

/* backlight API interface functions */

/* This driver currently treats AC and DC brightness identical,
 * since we don't need to invent an interface to the core ACPI
 * logic to receive events in case a power supply is plugged in
 * or removed */

static int bl_get(struct backlight_device *bd)
{}

static int bl_set_status(struct backlight_device *bd)
{}

static const struct backlight_ops pcc_backlight_ops =;


/* returns ACPI_SUCCESS if methods to control optical drive are present */

static acpi_status check_optd_present(void)
{}

/* get optical driver power state */

static int get_optd_power_state(void)
{}

/* set optical drive power state */

static int set_optd_power_state(int new_state)
{}


/* sysfs user interface functions */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

static DEVICE_ATTR_RO(numbatt);
static DEVICE_ATTR_RO(lcdtype);
static DEVICE_ATTR_RW(mute);
static DEVICE_ATTR_RW(sticky_key);
static DEVICE_ATTR_RW(eco_mode);
static DEVICE_ATTR_RW(ac_brightness);
static DEVICE_ATTR_RW(dc_brightness);
static DEVICE_ATTR_RW(current_brightness);
static DEVICE_ATTR_RW(cdpower);

static umode_t pcc_sysfs_is_visible(struct kobject *kobj, struct attribute *attr, int idx)
{}

static struct attribute *pcc_sysfs_entries[] =;

static const struct attribute_group pcc_attr_group =;


/* hotkey input device driver */

static int sleep_keydown_seen;
static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc)
{}

static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event)
{}

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

static int pcc_register_optd_notifier(struct pcc_acpi *pcc, char *node)
{}

static void pcc_unregister_optd_notifier(struct pcc_acpi *pcc, char *node)
{}

static int acpi_pcc_init_input(struct pcc_acpi *pcc)
{}

/* kernel module interface */

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

static int acpi_pcc_hotkey_add(struct acpi_device *device)
{}

static void acpi_pcc_hotkey_remove(struct acpi_device *device)
{}

module_acpi_driver();