Re: [PATCH 3/4] Add 3G rfkill sysfs file

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add CC. Thomas

æ æï2010-10-31 æ 00:36 +0800ïLee, Chun-Yi æåï
> Add 3G rfkill sysfs file for provide userland to control 3G device
> on/off by using WMI method.
> 
> Signed-off-by: Lee, Chun-Yi <jlee@xxxxxxxxxx>
> ---
>  drivers/platform/x86/acer-wmi.c |   99 ++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 98 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
> index 0b870d3..9656464 100644
> --- a/drivers/platform/x86/acer-wmi.c
> +++ b/drivers/platform/x86/acer-wmi.c
> @@ -136,6 +136,24 @@ struct lm_return_value {
>  } __attribute__((packed));
>  
>  /*
> + * GUID3 Get Device Status device flags
> + */
> +#define ACER_WMID3_GDS_THREEG		(1<<6)	/* 3G */
> +
> +struct wmid3_gds_input_param {	/* Get Device Status input parameter */
> +	u8 function_num;	/* Function Number */
> +	u8 hotkey_number;	/* Hotkey Number */
> +	u16 devices;		/* Get Device */
> +} __attribute__((packed));
> +
> +struct wmid3_gds_return_value {	/* Get Device Status return value*/
> +	u8 error_code;		/* Error Code */
> +	u8 ec_return_value;	/* EC Return Value */
> +	u16 devices;		/* Current Device Status */
> +	u32 reserved;
> +} __attribute__((packed));
> +
> +/*
>   * Interface capability flags
>   */
>  #define ACER_CAP_MAILLED		(1<<0)
> @@ -192,6 +210,7 @@ struct acer_debug {
>  
>  static struct rfkill *wireless_rfkill;
>  static struct rfkill *bluetooth_rfkill;
> +static struct rfkill *threeg_rfkill;
>  
>  /* Each low-level interface must define at least some of the following */
>  struct wmi_interface {
> @@ -1000,6 +1019,54 @@ static void acer_backlight_exit(void)
>  	backlight_device_unregister(acer_backlight_device);
>  }
>  
> +static acpi_status wmid3_get_device_status(u32 *value, u16 device)
> +{
> +	struct wmid3_gds_return_value return_value;
> +	acpi_status status;
> +	union acpi_object *obj;
> +	struct wmid3_gds_input_param params = {
> +		.function_num = 0x1,
> +		.hotkey_number = 0x01,
> +		.devices = device,
> +	};
> +	struct acpi_buffer input = {
> +		sizeof(struct wmid3_gds_input_param),
> +		&params
> +	};
> +	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
> +
> +	status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output);
> +	if (ACPI_FAILURE(status))
> +		return status;
> +
> +	obj = output.pointer;
> +
> +	if (!obj)
> +		return -EINVAL;
> +	else if (obj->type != ACPI_TYPE_BUFFER) {
> +		kfree(obj);
> +		return -EINVAL;
> +	}
> +	if (obj->buffer.length != 8) {
> +		printk(ACER_WARNING "Unknown buffer length %d\n",
> +			obj->buffer.length);
> +		kfree(obj);
> +		return -EINVAL;
> +	}
> +
> +	return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer);
> +	kfree(obj);
> +
> +	if (return_value.error_code || return_value.ec_return_value)
> +		printk(ACER_WARNING "Get Device Status failed: "
> +			"0x%x - 0x%x\n", return_value.error_code,
> +			return_value.ec_return_value);
> +	else
> +		*value = !!(return_value.devices & device);
> +
> +	return status;
> +}
> +
>  /*
>   * Rfkill devices
>   */
> @@ -1020,6 +1087,13 @@ static void acer_rfkill_update(struct work_struct *ignored)
>  			rfkill_set_sw_state(bluetooth_rfkill, !state);
>  	}
>  
> +	if (has_cap(ACER_CAP_THREEG) && wmi_has_guid(WMID_GUID3)) {
> +		status = wmid3_get_device_status(&state,
> +				ACER_WMID3_GDS_THREEG);
> +		if (ACPI_SUCCESS(status))
> +			rfkill_set_sw_state(threeg_rfkill, !state);
> +	}
> +
>  	schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ));
>  }
>  
> @@ -1076,6 +1150,19 @@ static int acer_rfkill_init(struct device *dev)
>  		}
>  	}
>  
> +	if (has_cap(ACER_CAP_THREEG)) {
> +		threeg_rfkill = acer_rfkill_register(dev,
> +			RFKILL_TYPE_WWAN, "acer-threeg",
> +			ACER_CAP_THREEG);
> +		if (IS_ERR(threeg_rfkill)) {
> +			rfkill_unregister(wireless_rfkill);
> +			rfkill_destroy(wireless_rfkill);
> +			rfkill_unregister(bluetooth_rfkill);
> +			rfkill_destroy(bluetooth_rfkill);
> +			return PTR_ERR(threeg_rfkill);
> +		}
> +	}
> +
>  	schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ));
>  
>  	return 0;
> @@ -1092,6 +1179,11 @@ static void acer_rfkill_exit(void)
>  		rfkill_unregister(bluetooth_rfkill);
>  		rfkill_destroy(bluetooth_rfkill);
>  	}
> +
> +	if (has_cap(ACER_CAP_THREEG)) {
> +		rfkill_unregister(threeg_rfkill);
> +		rfkill_destroy(threeg_rfkill);
> +	}
>  	return;
>  }
>  
> @@ -1102,7 +1194,12 @@ static ssize_t show_bool_threeg(struct device *dev,
>  	struct device_attribute *attr, char *buf)
>  {
>  	u32 result; \
> -	acpi_status status = get_u32(&result, ACER_CAP_THREEG);
> +	acpi_status status;
> +	if (wmi_has_guid(WMID_GUID3))
> +		status = wmid3_get_device_status(&result,
> +				ACER_WMID3_GDS_THREEG);
> +	else
> +		status = get_u32(&result, ACER_CAP_THREEG);
>  	if (ACPI_SUCCESS(status))
>  		return sprintf(buf, "%u\n", result);
>  	return sprintf(buf, "Read error\n");

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux