cregit-Linux how code gets into the kernel

Release 4.7 drivers/platform/x86/topstar-laptop.c

/*
 * ACPI driver for Topstar notebooks (hotkeys support only)
 *
 * Copyright (c) 2009 Herton Ronaldo Krzesinski <herton@mandriva.com.br>
 *
 * Implementation inspired by existing x86 platform drivers, in special
 * asus/eepc/fujitsu-laptop, thanks to their authors
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */


#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/input.h>
#include <linux/input/sparse-keymap.h>


#define ACPI_TOPSTAR_CLASS "topstar"


struct topstar_hkey {
	
struct input_dev *inputdev;
};


static const struct key_entry topstar_keymap[] = {
	{ KE_KEY, 0x80, { KEY_BRIGHTNESSUP } },
	{ KE_KEY, 0x81, { KEY_BRIGHTNESSDOWN } },
	{ KE_KEY, 0x83, { KEY_VOLUMEUP } },
	{ KE_KEY, 0x84, { KEY_VOLUMEDOWN } },
	{ KE_KEY, 0x85, { KEY_MUTE } },
	{ KE_KEY, 0x86, { KEY_SWITCHVIDEOMODE } },
	{ KE_KEY, 0x87, { KEY_F13 } }, /* touchpad enable/disable key */
	{ KE_KEY, 0x88, { KEY_WLAN } },
	{ KE_KEY, 0x8a, { KEY_WWW } },
	{ KE_KEY, 0x8b, { KEY_MAIL } },
	{ KE_KEY, 0x8c, { KEY_MEDIA } },

	/* Known non hotkey events don't handled or that we don't care yet */
	{ KE_IGNORE, 0x82, }, /* backlight event */
	{ KE_IGNORE, 0x8e, },
	{ KE_IGNORE, 0x8f, },
	{ KE_IGNORE, 0x90, },

	/*
         * 'G key' generate two event codes, convert to only
         * one event/key code for now, consider replacing by
         * a switch (3G switch - SW_3G?)
         */
	{ KE_KEY, 0x96, { KEY_F14 } },
	{ KE_KEY, 0x97, { KEY_F14 } },

	{ KE_END, 0 }
};


static void acpi_topstar_notify(struct acpi_device *device, u32 event) { static bool dup_evnt[2]; bool *dup; struct topstar_hkey *hkey = acpi_driver_data(device); /* 0x83 and 0x84 key events comes duplicated... */ if (event == 0x83 || event == 0x84) { dup = &dup_evnt[event - 0x83]; if (*dup) { *dup = false; return; } *dup = true; } if (!sparse_keymap_report_event(hkey->inputdev, event, 1, true)) pr_info("unknown event = 0x%02x\n", event); }

Contributors

PersonTokensPropCommitsCommitProp
herton ronaldo krzesinskiherton ronaldo krzesinski9595.96%150.00%
dmitry torokhovdmitry torokhov44.04%150.00%
Total99100.00%2100.00%


static int acpi_topstar_fncx_switch(struct acpi_device *device, bool state) { acpi_status status; status = acpi_execute_simple_method(device->handle, "FNCX", state ? 0x86 : 0x87); if (ACPI_FAILURE(status)) { pr_err("Unable to switch FNCX notifications\n"); return -ENODEV; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
herton ronaldo krzesinskiherton ronaldo krzesinski4989.09%150.00%
rui zhangrui zhang610.91%150.00%
Total55100.00%2100.00%


static int acpi_topstar_init_hkey(struct topstar_hkey *hkey) { struct input_dev *input; int error; input = input_allocate_device(); if (!input) return -ENOMEM; input->name = "Topstar Laptop extra buttons"; input->phys = "topstar/input0"; input->id.bustype = BUS_HOST; error = sparse_keymap_setup(input, topstar_keymap, NULL); if (error) { pr_err("Unable to setup input device keymap\n"); goto err_free_dev; } error = input_register_device(input); if (error) { pr_err("Unable to register input device\n"); goto err_free_keymap; } hkey->inputdev = input; return 0; err_free_keymap: sparse_keymap_free(input); err_free_dev: input_free_device(input); return error; }

Contributors

PersonTokensPropCommitsCommitProp
herton ronaldo krzesinskiherton ronaldo krzesinski6955.20%150.00%
dmitry torokhovdmitry torokhov5644.80%150.00%
Total125100.00%2100.00%


static int acpi_topstar_add(struct acpi_device *device) { struct topstar_hkey *tps_hkey; tps_hkey = kzalloc(sizeof(struct topstar_hkey), GFP_KERNEL); if (!tps_hkey) return -ENOMEM; strcpy(acpi_device_name(device), "Topstar TPSACPI"); strcpy(acpi_device_class(device), ACPI_TOPSTAR_CLASS); if (acpi_topstar_fncx_switch(device, true)) goto add_err; if (acpi_topstar_init_hkey(tps_hkey)) goto add_err; device->driver_data = tps_hkey; return 0; add_err: kfree(tps_hkey); return -ENODEV; }

Contributors

PersonTokensPropCommitsCommitProp
herton ronaldo krzesinskiherton ronaldo krzesinski100100.00%1100.00%
Total100100.00%1100.00%


static int acpi_topstar_remove(struct acpi_device *device) { struct topstar_hkey *tps_hkey = acpi_driver_data(device); acpi_topstar_fncx_switch(device, false); sparse_keymap_free(tps_hkey->inputdev); input_unregister_device(tps_hkey->inputdev); kfree(tps_hkey); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
herton ronaldo krzesinskiherton ronaldo krzesinski4386.00%150.00%
dmitry torokhovdmitry torokhov714.00%150.00%
Total50100.00%2100.00%

static const struct acpi_device_id topstar_device_ids[] = { { "TPSACPI01", 0 }, { "", 0 }, }; MODULE_DEVICE_TABLE(acpi, topstar_device_ids); static struct acpi_driver acpi_topstar_driver = { .name = "Topstar laptop ACPI driver", .class = ACPI_TOPSTAR_CLASS, .ids = topstar_device_ids, .ops = { .add = acpi_topstar_add, .remove = acpi_topstar_remove, .notify = acpi_topstar_notify, }, }; module_acpi_driver(acpi_topstar_driver); MODULE_AUTHOR("Herton Ronaldo Krzesinski"); MODULE_DESCRIPTION("Topstar Laptop ACPI Extras driver"); MODULE_LICENSE("GPL");

Overall Contributors

PersonTokensPropCommitsCommitProp
herton ronaldo krzesinskiherton ronaldo krzesinski56476.73%116.67%
dmitry torokhovdmitry torokhov15320.82%116.67%
manuel laussmanuel lauss70.95%116.67%
rui zhangrui zhang60.82%116.67%
tejun heotejun heo30.41%116.67%
mika westerbergmika westerberg20.27%116.67%
Total735100.00%6100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}