cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

atlas_btns.c (3591B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  atlas_btns.c - Atlas Wallmount Touchscreen ACPI Extras
      4 *
      5 *  Copyright (C) 2006 Jaya Kumar
      6 *  Based on Toshiba ACPI by John Belmonte and ASUS ACPI
      7 *  This work was sponsored by CIS(M) Sdn Bhd.
      8 */
      9
     10#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
     11
     12#include <linux/kernel.h>
     13#include <linux/module.h>
     14#include <linux/input.h>
     15#include <linux/types.h>
     16#include <linux/acpi.h>
     17#include <linux/uaccess.h>
     18
     19#define ACPI_ATLAS_NAME		"Atlas ACPI"
     20#define ACPI_ATLAS_CLASS	"Atlas"
     21
     22static unsigned short atlas_keymap[16];
     23static struct input_dev *input_dev;
     24
     25/* button handling code */
     26static acpi_status acpi_atlas_button_setup(acpi_handle region_handle,
     27		    u32 function, void *handler_context, void **return_context)
     28{
     29	*return_context =
     30		(function != ACPI_REGION_DEACTIVATE) ? handler_context : NULL;
     31
     32	return AE_OK;
     33}
     34
     35static acpi_status acpi_atlas_button_handler(u32 function,
     36		      acpi_physical_address address,
     37		      u32 bit_width, u64 *value,
     38		      void *handler_context, void *region_context)
     39{
     40	acpi_status status;
     41
     42	if (function == ACPI_WRITE) {
     43		int code = address & 0x0f;
     44		int key_down = !(address & 0x10);
     45
     46		input_event(input_dev, EV_MSC, MSC_SCAN, code);
     47		input_report_key(input_dev, atlas_keymap[code], key_down);
     48		input_sync(input_dev);
     49
     50		status = AE_OK;
     51	} else {
     52		pr_warn("shrugged on unexpected function: function=%x,address=%lx,value=%x\n",
     53			function, (unsigned long)address, (u32)*value);
     54		status = AE_BAD_PARAMETER;
     55	}
     56
     57	return status;
     58}
     59
     60static int atlas_acpi_button_add(struct acpi_device *device)
     61{
     62	acpi_status status;
     63	int i;
     64	int err;
     65
     66	input_dev = input_allocate_device();
     67	if (!input_dev) {
     68		pr_err("unable to allocate input device\n");
     69		return -ENOMEM;
     70	}
     71
     72	input_dev->name = "Atlas ACPI button driver";
     73	input_dev->phys = "ASIM0000/atlas/input0";
     74	input_dev->id.bustype = BUS_HOST;
     75	input_dev->keycode = atlas_keymap;
     76	input_dev->keycodesize = sizeof(unsigned short);
     77	input_dev->keycodemax = ARRAY_SIZE(atlas_keymap);
     78
     79	input_set_capability(input_dev, EV_MSC, MSC_SCAN);
     80	__set_bit(EV_KEY, input_dev->evbit);
     81	for (i = 0; i < ARRAY_SIZE(atlas_keymap); i++) {
     82		if (i < 9) {
     83			atlas_keymap[i] = KEY_F1 + i;
     84			__set_bit(KEY_F1 + i, input_dev->keybit);
     85		} else
     86			atlas_keymap[i] = KEY_RESERVED;
     87	}
     88
     89	err = input_register_device(input_dev);
     90	if (err) {
     91		pr_err("couldn't register input device\n");
     92		input_free_device(input_dev);
     93		return err;
     94	}
     95
     96	/* hookup button handler */
     97	status = acpi_install_address_space_handler(device->handle,
     98				0x81, &acpi_atlas_button_handler,
     99				&acpi_atlas_button_setup, device);
    100	if (ACPI_FAILURE(status)) {
    101		pr_err("error installing addr spc handler\n");
    102		input_unregister_device(input_dev);
    103		err = -EINVAL;
    104	}
    105
    106	return err;
    107}
    108
    109static int atlas_acpi_button_remove(struct acpi_device *device)
    110{
    111	acpi_status status;
    112
    113	status = acpi_remove_address_space_handler(device->handle,
    114				0x81, &acpi_atlas_button_handler);
    115	if (ACPI_FAILURE(status))
    116		pr_err("error removing addr spc handler\n");
    117
    118	input_unregister_device(input_dev);
    119
    120	return 0;
    121}
    122
    123static const struct acpi_device_id atlas_device_ids[] = {
    124	{"ASIM0000", 0},
    125	{"", 0},
    126};
    127MODULE_DEVICE_TABLE(acpi, atlas_device_ids);
    128
    129static struct acpi_driver atlas_acpi_driver = {
    130	.name	= ACPI_ATLAS_NAME,
    131	.class	= ACPI_ATLAS_CLASS,
    132	.owner	= THIS_MODULE,
    133	.ids	= atlas_device_ids,
    134	.ops	= {
    135		.add	= atlas_acpi_button_add,
    136		.remove	= atlas_acpi_button_remove,
    137	},
    138};
    139module_acpi_driver(atlas_acpi_driver);
    140
    141MODULE_AUTHOR("Jaya Kumar");
    142MODULE_LICENSE("GPL");
    143MODULE_DESCRIPTION("Atlas button driver");
    144