⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sony-laptop.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		return 0;	ret = platform_driver_register(&sony_pf_driver);	if (ret)		goto out;	sony_pf_device = platform_device_alloc("sony-laptop", -1);	if (!sony_pf_device) {		ret = -ENOMEM;		goto out_platform_registered;	}	ret = platform_device_add(sony_pf_device);	if (ret)		goto out_platform_alloced;	return 0;      out_platform_alloced:	platform_device_put(sony_pf_device);	sony_pf_device = NULL;      out_platform_registered:	platform_driver_unregister(&sony_pf_driver);      out:	atomic_dec(&sony_pf_users);	return ret;}static void sony_pf_remove(void){	/* deregister only after the last user has gone */	if (!atomic_dec_and_test(&sony_pf_users))		return;	platform_device_del(sony_pf_device);	platform_device_put(sony_pf_device);	platform_driver_unregister(&sony_pf_driver);}/*********** SNC (SNY5001) Device ***********//* the device uses 1-based values, while the backlight subsystem uses   0-based values */#define SONY_MAX_BRIGHTNESS	8#define SNC_VALIDATE_IN		0#define SNC_VALIDATE_OUT	1static ssize_t sony_nc_sysfs_show(struct device *, struct device_attribute *,			      char *);static ssize_t sony_nc_sysfs_store(struct device *, struct device_attribute *,			       const char *, size_t);static int boolean_validate(const int, const int);static int brightness_default_validate(const int, const int);struct sony_nc_value {	char *name;		/* name of the entry */	char **acpiget;		/* names of the ACPI get function */	char **acpiset;		/* names of the ACPI set function */	int (*validate)(const int, const int);	/* input/output validation */	int value;		/* current setting */	int valid;		/* Has ever been set */	int debug;		/* active only in debug mode ? */	struct device_attribute devattr;	/* sysfs atribute */};#define SNC_HANDLE_NAMES(_name, _values...) \	static char *snc_##_name[] = { _values, NULL }#define SNC_HANDLE(_name, _getters, _setters, _validate, _debug) \	{ \		.name		= __stringify(_name), \		.acpiget	= _getters, \		.acpiset	= _setters, \		.validate	= _validate, \		.debug		= _debug, \		.devattr	= __ATTR(_name, 0, sony_nc_sysfs_show, sony_nc_sysfs_store), \	}#define SNC_HANDLE_NULL	{ .name = NULL }SNC_HANDLE_NAMES(fnkey_get, "GHKE");SNC_HANDLE_NAMES(brightness_def_get, "GPBR");SNC_HANDLE_NAMES(brightness_def_set, "SPBR");SNC_HANDLE_NAMES(cdpower_get, "GCDP");SNC_HANDLE_NAMES(cdpower_set, "SCDP", "CDPW");SNC_HANDLE_NAMES(audiopower_get, "GAZP");SNC_HANDLE_NAMES(audiopower_set, "AZPW");SNC_HANDLE_NAMES(lanpower_get, "GLNP");SNC_HANDLE_NAMES(lanpower_set, "LNPW");SNC_HANDLE_NAMES(lidstate_get, "GLID");SNC_HANDLE_NAMES(indicatorlamp_get, "GILS");SNC_HANDLE_NAMES(indicatorlamp_set, "SILS");SNC_HANDLE_NAMES(gainbass_get, "GMGB");SNC_HANDLE_NAMES(gainbass_set, "CMGB");SNC_HANDLE_NAMES(PID_get, "GPID");SNC_HANDLE_NAMES(CTR_get, "GCTR");SNC_HANDLE_NAMES(CTR_set, "SCTR");SNC_HANDLE_NAMES(PCR_get, "GPCR");SNC_HANDLE_NAMES(PCR_set, "SPCR");SNC_HANDLE_NAMES(CMI_get, "GCMI");SNC_HANDLE_NAMES(CMI_set, "SCMI");static struct sony_nc_value sony_nc_values[] = {	SNC_HANDLE(brightness_default, snc_brightness_def_get,			snc_brightness_def_set, brightness_default_validate, 0),	SNC_HANDLE(fnkey, snc_fnkey_get, NULL, NULL, 0),	SNC_HANDLE(cdpower, snc_cdpower_get, snc_cdpower_set, boolean_validate, 0),	SNC_HANDLE(audiopower, snc_audiopower_get, snc_audiopower_set,			boolean_validate, 0),	SNC_HANDLE(lanpower, snc_lanpower_get, snc_lanpower_set,			boolean_validate, 1),	SNC_HANDLE(lidstate, snc_lidstate_get, NULL,			boolean_validate, 0),	SNC_HANDLE(indicatorlamp, snc_indicatorlamp_get, snc_indicatorlamp_set,			boolean_validate, 0),	SNC_HANDLE(gainbass, snc_gainbass_get, snc_gainbass_set,			boolean_validate, 0),	/* unknown methods */	SNC_HANDLE(PID, snc_PID_get, NULL, NULL, 1),	SNC_HANDLE(CTR, snc_CTR_get, snc_CTR_set, NULL, 1),	SNC_HANDLE(PCR, snc_PCR_get, snc_PCR_set, NULL, 1),	SNC_HANDLE(CMI, snc_CMI_get, snc_CMI_set, NULL, 1),	SNC_HANDLE_NULL};static acpi_handle sony_nc_acpi_handle;static struct acpi_device *sony_nc_acpi_device = NULL;/* * acpi_evaluate_object wrappers */static int acpi_callgetfunc(acpi_handle handle, char *name, int *result){	struct acpi_buffer output;	union acpi_object out_obj;	acpi_status status;	output.length = sizeof(out_obj);	output.pointer = &out_obj;	status = acpi_evaluate_object(handle, name, NULL, &output);	if ((status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER)) {		*result = out_obj.integer.value;		return 0;	}	printk(KERN_WARNING DRV_PFX "acpi_callreadfunc failed\n");	return -1;}static int acpi_callsetfunc(acpi_handle handle, char *name, int value,			    int *result){	struct acpi_object_list params;	union acpi_object in_obj;	struct acpi_buffer output;	union acpi_object out_obj;	acpi_status status;	params.count = 1;	params.pointer = &in_obj;	in_obj.type = ACPI_TYPE_INTEGER;	in_obj.integer.value = value;	output.length = sizeof(out_obj);	output.pointer = &out_obj;	status = acpi_evaluate_object(handle, name, &params, &output);	if (status == AE_OK) {		if (result != NULL) {			if (out_obj.type != ACPI_TYPE_INTEGER) {				printk(KERN_WARNING DRV_PFX "acpi_evaluate_object bad "				       "return type\n");				return -1;			}			*result = out_obj.integer.value;		}		return 0;	}	printk(KERN_WARNING DRV_PFX "acpi_evaluate_object failed\n");	return -1;}/* * sony_nc_values input/output validate functions *//* brightness_default_validate: * * manipulate input output values to keep consistency with the * backlight framework for which brightness values are 0-based. */static int brightness_default_validate(const int direction, const int value){	switch (direction) {		case SNC_VALIDATE_OUT:			return value - 1;		case SNC_VALIDATE_IN:			if (value >= 0 && value < SONY_MAX_BRIGHTNESS)				return value + 1;	}	return -EINVAL;}/* boolean_validate: * * on input validate boolean values 0/1, on output just pass the * received value. */static int boolean_validate(const int direction, const int value){	if (direction == SNC_VALIDATE_IN) {		if (value != 0 && value != 1)			return -EINVAL;	}	return value;}/* * Sysfs show/store common to all sony_nc_values */static ssize_t sony_nc_sysfs_show(struct device *dev, struct device_attribute *attr,			      char *buffer){	int value;	struct sony_nc_value *item =	    container_of(attr, struct sony_nc_value, devattr);	if (!*item->acpiget)		return -EIO;	if (acpi_callgetfunc(sony_nc_acpi_handle, *item->acpiget, &value) < 0)		return -EIO;	if (item->validate)		value = item->validate(SNC_VALIDATE_OUT, value);	return snprintf(buffer, PAGE_SIZE, "%d\n", value);}static ssize_t sony_nc_sysfs_store(struct device *dev,			       struct device_attribute *attr,			       const char *buffer, size_t count){	int value;	struct sony_nc_value *item =	    container_of(attr, struct sony_nc_value, devattr);	if (!item->acpiset)		return -EIO;	if (count > 31)		return -EINVAL;	value = simple_strtoul(buffer, NULL, 10);	if (item->validate)		value = item->validate(SNC_VALIDATE_IN, value);	if (value < 0)		return value;	if (acpi_callsetfunc(sony_nc_acpi_handle, *item->acpiset, value, NULL) < 0)		return -EIO;	item->value = value;	item->valid = 1;	return count;}/* * Backlight device */static int sony_backlight_update_status(struct backlight_device *bd){	return acpi_callsetfunc(sony_nc_acpi_handle, "SBRT",				bd->props.brightness + 1, NULL);}static int sony_backlight_get_brightness(struct backlight_device *bd){	int value;	if (acpi_callgetfunc(sony_nc_acpi_handle, "GBRT", &value))		return 0;	/* brightness levels are 1-based, while backlight ones are 0-based */	return value - 1;}static struct backlight_device *sony_backlight_device;static struct backlight_ops sony_backlight_ops = {	.update_status = sony_backlight_update_status,	.get_brightness = sony_backlight_get_brightness,};/* * New SNC-only Vaios event mapping to driver known keys */struct sony_nc_event {	u8	data;	u8	event;};static struct sony_nc_event *sony_nc_events;/* Vaio C* --maybe also FE*, N* and AR* ?-- special init sequence * for Fn keys */static int sony_nc_C_enable(const struct dmi_system_id *id){	int result = 0;	printk(KERN_NOTICE DRV_PFX "detected %s\n", id->ident);	sony_nc_events = id->driver_data;	if (acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x4, &result) < 0			|| acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x2, &result) < 0			|| acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x10, &result) < 0			|| acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x0, &result) < 0			|| acpi_callsetfunc(sony_nc_acpi_handle, "SN03", 0x2, &result) < 0			|| acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x101, &result) < 0) {		printk(KERN_WARNING DRV_PFX "failed to initialize SNC, some "				"functionalities may be missing\n");		return 1;	}	return 0;}static struct sony_nc_event sony_C_events[] = {	{ 0x81, SONYPI_EVENT_FNKEY_F1 },	{ 0x01, SONYPI_EVENT_FNKEY_RELEASED },	{ 0x85, SONYPI_EVENT_FNKEY_F5 },	{ 0x05, SONYPI_EVENT_FNKEY_RELEASED },	{ 0x86, SONYPI_EVENT_FNKEY_F6 },	{ 0x06, SONYPI_EVENT_FNKEY_RELEASED },	{ 0x87, SONYPI_EVENT_FNKEY_F7 },	{ 0x07, SONYPI_EVENT_FNKEY_RELEASED },	{ 0x8A, SONYPI_EVENT_FNKEY_F10 },	{ 0x0A, SONYPI_EVENT_FNKEY_RELEASED },	{ 0x8C, SONYPI_EVENT_FNKEY_F12 },	{ 0x0C, SONYPI_EVENT_FNKEY_RELEASED },	{ 0, 0 },};/* SNC-only model map */static const struct dmi_system_id sony_nc_ids[] = {		{			.ident = "Sony Vaio FE Series",			.callback = sony_nc_C_enable,			.driver_data = sony_C_events,			.matches = {				DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),				DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FE"),			},		},		{			.ident = "Sony Vaio FZ Series",			.callback = sony_nc_C_enable,			.driver_data = sony_C_events,			.matches = {				DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),				DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ"),			},		},		{			.ident = "Sony Vaio C Series",			.callback = sony_nc_C_enable,			.driver_data = sony_C_events,			.matches = {				DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),				DMI_MATCH(DMI_PRODUCT_NAME, "VGN-C"),			},		},		{ }};/* * ACPI callbacks */static void sony_acpi_notify(acpi_handle handle, u32 event, void *data){	struct sony_nc_event *evmap;	u32 ev = event;	int result;	if (ev == 0x92) {		/* read the key pressed from EC.GECR		 * A call to SN07 with 0x0202 will do it as well respecting		 * the current protocol on different OSes		 *		 * Note: the path for GECR may be		 *   \_SB.PCI0.LPCB.EC (C, FE, AR, N and friends)		 *   \_SB.PCI0.PIB.EC0 (VGN-FR notifications are sent directly, no GECR)		 *		 * TODO: we may want to do the same for the older GHKE -need		 *       dmi list- so this snippet may become one more callback.		 */		if (acpi_callsetfunc(handle, "SN07", 0x0202, &result) < 0)			dprintk("sony_acpi_notify, unable to decode event 0x%.2x\n", ev);		else			ev = result & 0xFF;	}	if (sony_nc_events)		for (evmap = sony_nc_events; evmap->event; evmap++) {			if (evmap->data == ev) {				ev = evmap->event;				break;			}		}	dprintk("sony_acpi_notify, event: 0x%.2x\n", ev);	sony_laptop_report_input_event(ev);	acpi_bus_generate_proc_event(sony_nc_acpi_device, 1, ev);}static acpi_status sony_walk_callback(acpi_handle handle, u32 level,				      void *context, void **return_value){	struct acpi_namespace_node *node;	union acpi_operand_object *operand;	node = (struct acpi_namespace_node *)handle;	operand = (union acpi_operand_object *)node->object;	printk(KERN_WARNING DRV_PFX "method: name: %4.4s, args %X\n", node->name.ascii,	       (u32) operand->method.param_count);	return AE_OK;}/* * ACPI device */static int sony_nc_resume(struct acpi_device *device){	struct sony_nc_value *item;	for (item = sony_nc_values; item->name; item++) {		int ret;		if (!item->valid)			continue;		ret = acpi_callsetfunc(sony_nc_acpi_handle, *item->acpiset,				       item->value, NULL);		if (ret < 0) {			printk("%s: %d\n", __FUNCTION__, ret);			break;		}	}	/* set the last requested brightness level */	if (sony_backlight_device &&			!sony_backlight_update_status(sony_backlight_device))		printk(KERN_WARNING DRV_PFX "unable to restore brightness level");	/* re-initialize models with specific requirements */	dmi_check_system(sony_nc_ids);	return 0;}static int sony_nc_add(struct acpi_device *device){	acpi_status status;	int result = 0;	acpi_handle handle;	struct sony_nc_value *item;	printk(KERN_INFO DRV_PFX "%s v%s.\n",		SONY_NC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -