RE: [External] Re: [PATCH] [v2] platform/x86: thinkpad_acpi: set keyboard language

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

 



Hello Hans ,

>-----Original Message-----
>From: Hans de Goede <hdegoede@xxxxxxxxxx>
>Sent: Tuesday, January 26, 2021 5:34 AM
>To: Nitin Joshi <nitjoshi@xxxxxxxxx>
>Cc: bberg@xxxxxxxxxx; peter.hutterer@xxxxxxxxxx; Tomoki Maruichi
><maruichit@xxxxxxxxxx>; Mark Pearson <mpearson@xxxxxxxxxx>;
>platform-driver-x86@xxxxxxxxxxxxxxx; Nitin Joshi1 <njoshi1@xxxxxxxxxx>
>Subject: [External] Re: [PATCH] [v2] platform/x86: thinkpad_acpi: set keyboard
>language
>
>Hi,
>
>On 1/25/21 3:59 AM, Nitin Joshi wrote:
>> From: Nitin Joshi <njoshi1@xxxxxxxxxx>
>>
>> This patch is to create sysfs entry for setting keyboard language
>> using ASL method. Some thinkpads models like T580 , T590 , T15 Gen 1
>> etc. has "=", "(',")" numeric keys, which are not displaying
>> correctly, when keyboard language is other than "english".
>> This patch fixes this issue by setting keyboard language to ECFW.
>>
>> Signed-off-by: Nitin Joshi <njoshi1@xxxxxxxxxx>
>> ---
>> Changes in v2:
>>  - used sysfs_streq() API instead of strcmp
>>  - used ARRAY_SIZE() API instead of strlen
>>  - addressed typo
>
>Thank you for your patch, I've applied this patch to my review-hans
>branch:
>https://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-
>x86.git/log/?h=review-hans
>
>Nitn, I did not notice one small issue while testing this on a X1C8 I will send out
>a follow-up patch addressing that. If you can test the follow-up patch on one
>of the affected models
>(T580 , T590 , T15 Gen 1, etc.) that would be great.

Yes , sure . I will test it  . Thank you 
 
>
>Note this patch will show up in my review-hans branch once I've pushed my
>local branch there, which might take a while.
>
>Once I've run some tests on this branch the patches there will be added to the
>platform-drivers-x86/for-next branch and eventually will be included in the
>pdx86 pull-request to Linus for the next merge-window.
>
>Regards,
>
>Hans
>
Thanks & Regards,
Nitin Joshi 

>
>> ---
>>  .../admin-guide/laptops/thinkpad-acpi.rst     |  24 +++
>>  drivers/platform/x86/thinkpad_acpi.c          | 182 ++++++++++++++++++
>>  2 files changed, 206 insertions(+)
>>
>> diff --git a/Documentation/admin-guide/laptops/thinkpad-acpi.rst
>> b/Documentation/admin-guide/laptops/thinkpad-acpi.rst
>> index 5fe1ade88c17..b1188f05a99a 100644
>> --- a/Documentation/admin-guide/laptops/thinkpad-acpi.rst
>> +++ b/Documentation/admin-guide/laptops/thinkpad-acpi.rst
>> @@ -51,6 +51,7 @@ detailed description):
>>  	- UWB enable and disable
>>  	- LCD Shadow (PrivacyGuard) enable and disable
>>  	- Lap mode sensor
>> +	- Setting keyboard language
>>
>>  A compatibility table by model and feature is maintained on the web
>> site, http://ibm-acpi.sf.net/. I appreciate any success or failure @@
>> -1466,6 +1467,29 @@ Sysfs notes
>>  	rfkill controller switch "tpacpi_uwb_sw": refer to
>>  	Documentation/driver-api/rfkill.rst for details.
>>
>> +
>> +Setting keyboard language
>> +-------------------
>> +
>> +sysfs: keyboard_lang
>> +
>> +This feature is used to set keyboard language to ECFW using ASL interface.
>> +Fewer thinkpads models like T580 , T590 , T15 Gen 1 etc.. has "=",
>> +"(', ")" numeric keys, which are not displaying correctly, when
>> +keyboard language is other than "english". This is because of default
>> +keyboard language in ECFW is set as "english". Hence using this
>> +sysfs, user can set correct keyboard language to ECFW and then these key's
>will work correctly .
>> +
>> +Example of command to set keyboard language is mentioned below::
>> +
>> +        echo jp > /sys/devices/platform/thinkpad_acpi/keyboard_lang
>> +
>> +Text corresponding to keyboard layout to be set in sysfs are : jp
>> +(Japan), be(Belgian), cz(Czech), en(English), da(Danish), de(German),
>> +es(Spain) , et(Estonian),
>> +fr(French) , fr-ch (French(Switzerland)), pl(Polish), sl(Slovenian),
>> +hu (Hungarian), nl(Dutch), tr(Turkey), it(Italy), sv(Sweden),
>> +pt(portugese)
>> +
>> +
>>  Adaptive keyboard
>>  -----------------
>>
>> diff --git a/drivers/platform/x86/thinkpad_acpi.c
>> b/drivers/platform/x86/thinkpad_acpi.c
>> index e03df2881dc6..3cfc4a872c2d 100644
>> --- a/drivers/platform/x86/thinkpad_acpi.c
>> +++ b/drivers/platform/x86/thinkpad_acpi.c
>> @@ -9982,6 +9982,183 @@ static struct ibm_struct proxsensor_driver_data
>= {
>>  	.exit = proxsensor_exit,
>>  };
>>
>>
>+/***************************************************************
>*****
>> +*****
>> + * Keyboard language interface
>> + */
>> +
>> +struct keyboard_lang_data {
>> +	const char *lang_str;
>> +	int lang_code;
>> +};
>> +
>> +/*
>> + * When adding new entries to keyboard_lang_data, please check that
>> + * the select_lang[] buffer in keyboard_lang_show() is still large enough.
>> + */
>> +struct keyboard_lang_data keyboard_lang_data[] = {
>> +	{"en", 0},
>> +	{"be", 0x080c},
>> +	{"cz", 0x0405},
>> +	{"da", 0x0406},
>> +	{"de", 0x0c07},
>> +	{"es", 0x2c0a},
>> +	{"et", 0x0425},
>> +	{"fr", 0x040c},
>> +	{"fr-ch", 0x100c},
>> +	{"hu", 0x040e},
>> +	{"it", 0x0410},
>> +	{"jp", 0x0411},
>> +	{"nl", 0x0413},
>> +	{"nn", 0x0414},
>> +	{"pl", 0x0415},
>> +	{"pt", 0x0816},
>> +	{"sl", 0x041b},
>> +	{"sv", 0x081d},
>> +	{"tr", 0x041f},
>> +};
>> +
>> +static int set_keyboard_lang_command(int command) {
>> +	acpi_handle sskl_handle;
>> +	int output;
>> +
>> +	if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "SSKL",
>&sskl_handle))) {
>> +		/* Platform doesn't support SSKL */
>> +		return -ENODEV;
>> +	}
>> +
>> +	if (!acpi_evalf(sskl_handle, &output, NULL, "dd", command))
>> +		return -EIO;
>> +
>> +	return 0;
>> +}
>> +
>> +static int get_keyboard_lang(int *output) {
>> +	acpi_handle gskl_handle;
>> +	int kbd_lang;
>> +
>> +	if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "GSKL",
>&gskl_handle))) {
>> +		/* Platform doesn't support GSKL */
>> +		return -ENODEV;
>> +	}
>> +
>> +	if (!acpi_evalf(gskl_handle, &kbd_lang, NULL, "dd", 0x02000000))
>> +		return -EIO;
>> +
>> +	*output = kbd_lang;
>> +
>> +	return 0;
>> +}
>> +
>> +/* sysfs keyboard language entry */
>> +static ssize_t keyboard_lang_show(struct device *dev,
>> +				struct device_attribute *attr,
>> +				char *buf)
>> +{
>> +	int output, err, i;
>> +	char select_lang[80] = "";
>> +	char lang[8] = "";
>> +
>> +	err = get_keyboard_lang(&output);
>> +	if (err)
>> +		return err;
>> +
>> +	for (i = 0; i < ARRAY_SIZE(keyboard_lang_data); i++) {
>> +		if (i)
>> +			strcat(select_lang, " ");
>> +
>> +		if (output == keyboard_lang_data[i].lang_code) {
>> +			strcat(lang, "[");
>> +			strcat(lang, keyboard_lang_data[i].lang_str);
>> +			strcat(lang, "]");
>> +			strcat(select_lang, lang);
>> +		} else {
>> +			strcat(select_lang, keyboard_lang_data[i].lang_str);
>> +		}
>> +	}
>> +
>> +	return sysfs_emit(buf, "%s\n", select_lang); }
>> +
>> +static ssize_t keyboard_lang_store(struct device *dev,
>> +				struct device_attribute *attr,
>> +				const char *buf, size_t count)
>> +{
>> +	int err, i;
>> +	bool lang_found = false;
>> +	int lang_code = 0;
>> +
>> +	for (i = 0; i < ARRAY_SIZE(keyboard_lang_data); i++) {
>> +		if (sysfs_streq(buf, keyboard_lang_data[i].lang_str)) {
>> +			lang_code = keyboard_lang_data[i].lang_code;
>> +			lang_found = true;
>> +			break;
>> +		}
>> +	}
>> +
>> +	if (lang_found) {
>> +		lang_code = lang_code | 1 << 24;
>> +
>> +		/* Set language code */
>> +		err = set_keyboard_lang_command(lang_code);
>> +		if (err)
>> +			return err;
>> +	} else {
>> +		pr_err("Unknown Keyboard language. Ignoring\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	tpacpi_disclose_usertask(attr->attr.name,
>> +			"keyboard language is set to  %s\n", buf);
>> +
>> +	sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, "keyboard_lang");
>> +
>> +	return count;
>> +}
>> +
>> +static DEVICE_ATTR_RW(keyboard_lang);
>> +
>> +static struct attribute *kbdlang_attributes[] = {
>> +	&dev_attr_keyboard_lang.attr,
>> +	NULL
>> +};
>> +
>> +static const struct attribute_group kbdlang_attr_group = {
>> +	.attrs = kbdlang_attributes,
>> +};
>> +
>> +static int tpacpi_kbdlang_init(struct ibm_init_struct *iibm) {
>> +	int err, output;
>> +
>> +	err = get_keyboard_lang(&output);
>> +	/*
>> +	 * If support isn't available (ENODEV) then don't return an error
>> +	 * just don't create the sysfs group
>> +	 */
>> +	if (err == -ENODEV)
>> +		return 0;
>> +
>> +	if (err)
>> +		return err;
>> +
>> +	/* Platform supports this feature - create the sysfs file */
>> +	err = sysfs_create_group(&tpacpi_pdev->dev.kobj,
>> +&kbdlang_attr_group);
>> +
>> +	return err;
>> +}
>> +
>> +static void kbdlang_exit(void)
>> +{
>> +	sysfs_remove_group(&tpacpi_pdev->dev.kobj,
>&kbdlang_attr_group); }
>> +
>> +static struct ibm_struct kbdlang_driver_data = {
>> +	.name = "kbdlang",
>> +	.exit = kbdlang_exit,
>> +};
>> +
>>
>/****************************************************************
>************
>>
>*****************************************************************
>***********
>>   *
>> @@ -10474,6 +10651,11 @@ static struct ibm_init_struct ibms_init[]
>__initdata = {
>>  		.init = tpacpi_proxsensor_init,
>>  		.data = &proxsensor_driver_data,
>>  	},
>> +	{
>> +		.init = tpacpi_kbdlang_init,
>> +		.data = &kbdlang_driver_data,
>> +	},
>> +
>>  };
>>
>>  static int __init set_ibm_param(const char *val, const struct
>> kernel_param *kp)
>>





[Index of Archives]     [Linux Kernel Development]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux