[PATCH v7 1/2] platform/x86: dell-privacy: Add support for Dell hardware privacy
From: Perry Yuan add support for Dell privacy driver for the Dell units equipped hardware privacy design, which protect users privacy of audio and camera from hardware level. Once the audio or camera privacy mode activated, any applications will not get any audio or video stream when user pressed ctrl+F4 hotkey, audio privacy mode will be enabled, micmute led will be also changed accordingly The micmute led is fully controlled by hardware & EC(embedded controller) and camera mute hotkey is Ctrl+F9. Currently design only emits SW_CAMERA_LENS_COVER event while the camera lens shutter will be changed by EC & HW(hardware) control *The flow is like this: 1) User presses key. HW does stuff with this key (timeout timer is started) 2) WMI event is emitted from BIOS to kernel 3) WMI event is received by dell-privacy 4) KEY_MICMUTE emitted from dell-privacy 5) Userland picks up key and modifies kcontrol for SW mute 6) Codec kernel driver catches and calls ledtrig_audio_set, like this: ledtrig_audio_set(LED_AUDIO_MICMUTE, rt715->micmute_led ? LED_ON :LED_OFF); 7) If "LED" is set to on dell-privacy notifies EC, and timeout is cancelled, HW mic mute activated. If EC not notified, HW mic mute will also be activated when timeout used up, it is just later than active ack Signed-off-by: Perry Yuan --- v5 -> v6: * addressed feedback from Hans * addressed feedback from Pierre * optimize some debug format with dev_dbg() * remove platform driver,combined privacy acpi driver into single wmi driver file * optimize sysfs interface with string added to be more clearly reading * remove unused function and clear header file v4 -> v5: * addressed feedback from Randy Dunlap * addressed feedback from Pierre-Louis Bossart * rebase to latest 5.12 rc4 upstream kernel * fix some space alignment problem v3 -> v4: * fix format for Kconfig * add sysfs document * add flow comments to the privacy wmi/acpi driver * addressed feedback from Barnabás Pőcze[Thanks very much] * export privacy_valid to make the global state simpler to query * fix one issue which will block the dell-laptop driver to load when privacy driver invalid * addressed feedback from Pierre-Louis Bossart,remove the EC ID match v2 -> v3: * add sysfs attributes doc v1 -> v2: * query EC handle from EC driver directly. * fix some code style. * add KEY_END to keymap array. * clean platform device when cleanup called * use hexadecimal format for log print in dev_dbg * remove __set_bit for the report keys from probe. * fix keymap leak * add err_free_keymap in dell_privacy_wmi_probe * wmi driver will be unregistered if privacy_acpi_init() fails * add sysfs attribute files for user space query. * add leds micmute driver to privacy acpi * add more design info the commit info --- --- .../testing/sysfs-platform-dell-privacy-wmi | 55 +++ drivers/platform/x86/dell/Kconfig | 14 + drivers/platform/x86/dell/Makefile| 1 + drivers/platform/x86/dell/dell-laptop.c | 23 +- drivers/platform/x86/dell/dell-privacy-wmi.c | 394 ++ drivers/platform/x86/dell/dell-privacy-wmi.h | 23 + drivers/platform/x86/dell/dell-wmi.c | 8 +- 7 files changed, 511 insertions(+), 7 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi create mode 100644 drivers/platform/x86/dell/dell-privacy-wmi.c create mode 100644 drivers/platform/x86/dell/dell-privacy-wmi.h diff --git a/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi b/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi new file mode 100644 index ..7f9e18705861 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi @@ -0,0 +1,55 @@ +What: /sys/bus/wmi/devices/6932965F-1671-4CEB-B988-D3AB0A901919/dell_privacy_supported_type +Date: Apr 2021 +KernelVersion: 5.13 +Contact: "perry.y...@dell.com>" +Description: + Display which dell hardware level privacy devices are supported + “Dell Privacy” is a set of HW, FW, and SW features to enhance + Dell’s commitment to platform privacy for MIC, Camera, and + ePrivacy screens. + The supported hardware privacy devices are: +Attributes: + Microphone Mute: + Identifies the local microphone can be muted by hardware, no applications + is available to capture system mic sound + + Camera Shutter: + Identifies camera shutter controlled by hardware, which is a micromechanical + shutter assembly that is built onto the camera module to block capturing images + from outside the laptop + + supported: + The privacy device is supported by this system + + unsupported: +
[PATCH v7 2/2] ASoC: rt715:add micmute led state control supports
From: Perry Yuan Some new Dell system is going to support audio internal micphone privacy setting from hardware level with micmute led state changing When micmute hotkey pressed by user, soft mute will need to be enabled firstly in case of pop noise, and codec driver need to react to mic mute event to EC(embedded controller) notifying that SW mute is completed Then EC will do the hardware mute physically within the timeout reached This patch allow codec rt715 and rt715 sdca driver to change the local micmute led state. Dell privacy led trigger driver will ack EC when micmute key pressed through this micphone led control interface like hda_generic provided ACPI method defined in dell-privacy micmute led trigger will be called for notifying the EC that software mute has been completed, then hardware audio circuit solution controlled by EC will switch the audio input source off/on Signed-off-by: Perry Yuan v5 -> v6: * addresed review comments from Jaroslav * add quirks for micmute led control as short term solution to control micmute led state change * add comments for the invert checking v4 -> v5: * rebase to latest 5.12 rc4 upstream kernel v3 -> v4: * remove unused debug log * remove compile flag of DELL privacy * move the micmute_led to local from rt715_priv * when Jaroslav upstream his gerneric LED trigger driver,I will rebase this patch,please consider merge this at first https://lore.kernel.org/alsa-devel/2021021400.1131020-1-pe...@perex.cz/ v2 -> v3: * simplify the patch to reuse some val value * add more detail to the commit info v1 -> v2: * fix some format issue --- sound/soc/codecs/rt715-sdca.c | 42 ++ sound/soc/codecs/rt715.c | 43 +++ 2 files changed, 85 insertions(+) diff --git a/sound/soc/codecs/rt715-sdca.c b/sound/soc/codecs/rt715-sdca.c index 20528afbdc57..47dc31f7f3e3 100644 --- a/sound/soc/codecs/rt715-sdca.c +++ b/sound/soc/codecs/rt715-sdca.c @@ -11,12 +11,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -344,6 +346,32 @@ static int rt715_sdca_get_volsw(struct snd_kcontrol *kcontrol, return 0; } +static bool micmute_led_set; +static int dmi_matched(const struct dmi_system_id *dmi) +{ + micmute_led_set = 1; + return 1; +} + +/* Some systems will need to use this to trigger mic mute LED state changed */ +static const struct dmi_system_id micmute_led_dmi_table[] = { + { + .callback = dmi_matched, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_SKU, "0A32"), + }, + }, + { + .callback = dmi_matched, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_SKU, "0A3E"), + }, + }, + {}, +}; + static int rt715_sdca_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -358,6 +386,7 @@ static int rt715_sdca_put_volsw(struct snd_kcontrol *kcontrol, unsigned int mask = (1 << fls(max)) - 1; unsigned int invert = p->invert; int err; + bool micmute_led; for (i = 0; i < 4; i++) { if (ucontrol->value.integer.value[i] != rt715->kctl_switch_orig[i]) { @@ -394,6 +423,18 @@ static int rt715_sdca_put_volsw(struct snd_kcontrol *kcontrol, return err; } + /* Micmute LED state changed by muted/unmute switch +* to keep syncing with actual hardware mic mute led state +* invert will be checked to change the state switch +*/ + if (invert && micmute_led_set) { + if (ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1]) + micmute_led = LED_OFF; + else + micmute_led = LED_ON; + ledtrig_audio_set(LED_AUDIO_MICMUTE, micmute_led); + } + return k_changed; } @@ -1066,6 +1107,7 @@ int rt715_sdca_io_init(struct device *dev, struct sdw_slave *slave) pm_runtime_mark_last_busy(&slave->dev); pm_runtime_put_autosuspend(&slave->dev); + dmi_check_system(micmute_led_dmi_table); return 0; } diff --git a/sound/soc/codecs/rt715.c b/sound/soc/codecs/rt715.c index 34c3357e943b..59d05b28f52e 100644 --- a/sound/soc/codecs/rt715.c +++ b/sound/soc/codecs/rt715.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -70,6 +72,32 @@ static void rt715_get_gain(struct rt715_priv *rt71
[PATCH v7 0/2] hardware-privacy-implementation-for-dell-laptop
From: Perry Yuan Hi All, This patch set is a new driver for Dell mobile platform that has the hardware privacy feature including micmute,camera mute. For micmute led control, the hotkey is Fn + F4, it is a hardware based mute state, and new privacy will prevent micphone void input from hardware layer, any application cannot get voice data when micmute activated. Camera mute use a new hardware design to control the camrea shutter. When video is muted, no OS application should be functionally able to capture images of the person/environment in front of the system Older history: [1]https://patchwork.kernel.org/project/platform-driver-x86/patch/20201228132855.17544-1-perry_y...@dell.com/ [2]https://patchwork.kernel.org/project/alsa-devel/patch/20201103125859.8759-1-perry_y...@dell.com/#23733605 [3]https://www.spinics.net/lists/alsa-devel/msg120537.html [4]https://github.com/thesofproject/linux/pull/2660 [5]https://github.com/thesofproject/linux/issues/2496 Perry Yuan (2): platform/x86: dell-privacy: Add support for Dell hardware privacy ASoC: rt715:add micmute led state control supports .../testing/sysfs-platform-dell-privacy-wmi | 55 +++ drivers/platform/x86/dell/Kconfig | 14 + drivers/platform/x86/dell/Makefile| 1 + drivers/platform/x86/dell/dell-laptop.c | 23 +- drivers/platform/x86/dell/dell-privacy-wmi.c | 394 ++ drivers/platform/x86/dell/dell-privacy-wmi.h | 23 + drivers/platform/x86/dell/dell-wmi.c | 8 +- sound/soc/codecs/rt715-sdca.c | 42 ++ sound/soc/codecs/rt715.c | 43 ++ 9 files changed, 596 insertions(+), 7 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi create mode 100644 drivers/platform/x86/dell/dell-privacy-wmi.c create mode 100644 drivers/platform/x86/dell/dell-privacy-wmi.h -- 2.25.1
[PATCH v6 2/2] ASoC: rt715:add micmute led state control supports
From: Perry Yuan Some new Dell system is going to support audio internal micphone privacy setting from hardware level with micmute led state changing When micmute hotkey pressed by user, soft mute will need to be enabled firstly in case of pop noise, and codec driver need to react to mic mute event to EC(embedded controller) notifying that SW mute is completed Then EC will do the hardware mute physically within the timeout reached This patch allow codec rt715 and rt715 sdca driver to change the local micmute led state. Dell privacy led trigger driver will ack EC when micmute key pressed through this micphone led control interface like hda_generic provided ACPI method defined in dell-privacy micmute led trigger will be called for notifying the EC that software mute has been completed, then hardware audio circuit solution controlled by EC will switch the audio input source off/on Signed-off-by: Perry Yuan v5 -> v6: * addresed review comments from Jaroslav * add quirks for micmute led control as short term solution to control micmute led state change v4 -> v5: * rebase to latest 5.12 rc4 upstream kernel v3 -> v4: * remove unused debug log * remove compile flag of DELL privacy * move the micmute_led to local from rt715_priv * when Jaroslav upstream his gerneric LED trigger driver,I will rebase this patch,please consider merge this at first https://lore.kernel.org/alsa-devel/2021021400.1131020-1-pe...@perex.cz/ v2 -> v3: * simplify the patch to reuse some val value * add more detail to the commit info v1 -> v2: * fix some format issue --- sound/soc/codecs/rt715-sdca.c | 41 ++- sound/soc/codecs/rt715.c | 41 +++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/rt715-sdca.c b/sound/soc/codecs/rt715-sdca.c index 20528afbdc57..7bd7ad0ba7d7 100644 --- a/sound/soc/codecs/rt715-sdca.c +++ b/sound/soc/codecs/rt715-sdca.c @@ -11,12 +11,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -344,6 +346,34 @@ static int rt715_sdca_get_volsw(struct snd_kcontrol *kcontrol, return 0; } +static bool micmute_led_set; +static int dmi_matched(const struct dmi_system_id *dmi) +{ + micmute_led_set = 1; + return 1; +} + +/* Some systems will need to use this to trigger mic mute LED state changed */ +static const struct dmi_system_id micmute_led_dmi_table[] = { + { + .callback = dmi_matched, + .ident = "Dell Latitude 9420", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 9420"), + }, + }, + { + .callback = dmi_matched, + .ident = "Dell Latitude 9520", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 9520"), + }, + }, + {}, +}; + static int rt715_sdca_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -358,6 +388,7 @@ static int rt715_sdca_put_volsw(struct snd_kcontrol *kcontrol, unsigned int mask = (1 << fls(max)) - 1; unsigned int invert = p->invert; int err; + bool micmute_led; for (i = 0; i < 4; i++) { if (ucontrol->value.integer.value[i] != rt715->kctl_switch_orig[i]) { @@ -393,7 +424,15 @@ static int rt715_sdca_put_volsw(struct snd_kcontrol *kcontrol, if (err < 0) return err; } - + /* Micmute LED state changed by muted/unmute switch */ + dmi_check_system(micmute_led_dmi_table); + if (invert && micmute_led_set) { + if (ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1]) + micmute_led = LED_OFF; + else + micmute_led = LED_ON; + ledtrig_audio_set(LED_AUDIO_MICMUTE, micmute_led); + } return k_changed; } diff --git a/sound/soc/codecs/rt715.c b/sound/soc/codecs/rt715.c index 34c3357e943b..490cf9e63c2d 100644 --- a/sound/soc/codecs/rt715.c +++ b/sound/soc/codecs/rt715.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -70,6 +72,34 @@ static void rt715_get_gain(struct rt715_priv *rt715, unsigned int addr_h, pr_err("Failed to get L channel gain.\n"); } +static bool micmute_led_set; +static int dmi_matched(const struct dmi_system_id *dmi) +{ + micmute_led_set = 1; + return 1;
[PATCH v6 1/2] platform/x86: dell-privacy: Add support for Dell hardware privacy
From: Perry Yuan add support for Dell privacy driver for the Dell units equipped hardware privacy design, which protect users privacy of audio and camera from hardware level. Once the audio or camera privacy mode activated, any applications will not get any audio or video stream when user pressed ctrl+F4 hotkey, audio privacy mode will be enabled, micmute led will be also changed accordingly The micmute led is fully controlled by hardware & EC(embedded controller) and camera mute hotkey is Ctrl+F9. Currently design only emits SW_CAMERA_LENS_COVER event while the camera lens shutter will be changed by EC & HW(hardware) control *The flow is like this: 1) User presses key. HW does stuff with this key (timeout timer is started) 2) WMI event is emitted from BIOS to kernel 3) WMI event is received by dell-privacy 4) KEY_MICMUTE emitted from dell-privacy 5) Userland picks up key and modifies kcontrol for SW mute 6) Codec kernel driver catches and calls ledtrig_audio_set, like this: ledtrig_audio_set(LED_AUDIO_MICMUTE, rt715->micmute_led ? LED_ON :LED_OFF); 7) If "LED" is set to on dell-privacy notifies EC, and timeout is cancelled, HW mic mute activated. If EC not notified, HW mic mute will also be activated when timeout used up, it is just later than active ack Signed-off-by: Perry Yuan --- v5 -> v6: * addressed feedback from Hans * addressed feedback from Pierre * optimize some debug format with dev_dbg() * remove platform driver,combined privacy acpi driver into single wmi driver file * optimize sysfs interface with string added to be more clearly reading v4 -> v5: * addressed feedback from Randy Dunlap * addressed feedback from Pierre-Louis Bossart * rebase to latest 5.12 rc4 upstream kernel * fix some space alignment problem v3 -> v4: * fix format for Kconfig * add sysfs document * add flow comments to the privacy wmi/acpi driver * addressed feedback from Barnabás Pőcze[Thanks very much] * export privacy_valid to make the global state simpler to query * fix one issue which will block the dell-laptop driver to load when privacy driver invalid * addressed feedback from Pierre-Louis Bossart,remove the EC ID match v2 -> v3: * add sysfs attributes doc v1 -> v2: * query EC handle from EC driver directly. * fix some code style. * add KEY_END to keymap array. * clean platform device when cleanup called * use hexadecimal format for log print in dev_dbg * remove __set_bit for the report keys from probe. * fix keymap leak * add err_free_keymap in dell_privacy_wmi_probe * wmi driver will be unregistered if privacy_acpi_init() fails * add sysfs attribute files for user space query. * add leds micmute driver to privacy acpi * add more design info the commit info --- --- .../testing/sysfs-platform-dell-privacy-wmi | 55 +++ drivers/platform/x86/dell/Kconfig | 14 + drivers/platform/x86/dell/Makefile| 1 + drivers/platform/x86/dell/dell-laptop.c | 23 +- drivers/platform/x86/dell/dell-privacy-wmi.c | 441 ++ drivers/platform/x86/dell/dell-privacy-wmi.h | 32 ++ drivers/platform/x86/dell/dell-wmi.c | 13 +- 7 files changed, 572 insertions(+), 7 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi create mode 100644 drivers/platform/x86/dell/dell-privacy-wmi.c create mode 100644 drivers/platform/x86/dell/dell-privacy-wmi.h diff --git a/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi b/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi new file mode 100644 index ..a57ddc6a221e --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi @@ -0,0 +1,55 @@ +What: /sys/bus/wmi/devices/6932965F-1671-4CEB-B988-D3AB0A901919/dell_privacy_supported_type +Date: Apr 2021 +KernelVersion: 5.13 +Contact: "perry.y...@dell.com>" +Description: + Display which dell hardware level privacy devices are supported + “Dell Privacy” is a set of HW, FW, and SW features to enhance + Dell’s commitment to platform privacy for MIC, Camera, and + ePrivacy screens. + The supported hardware privacy devices are: +Attributes: + Microphone Mute: + Identifies the local microphone can be muted by hardware, no applications + is available to capture system mic sound + +Camera Shutter: + Identifies camera shutter controlled by hardware, which is a micromechanical + shutter assembly that is built onto the camera module to block capturing images + from outside the laptop + + supported: + The privacy device is supported by this system + + unsupported: + The privacy device is not supported
[PATCH v6 0/2] hardware-privacy-implementation-for-dell-laptop
From: Perry Yuan Hi All, This patch set is a new driver for Dell mobile platform that has the hardware privacy feature including micmute,camera mute. For micmute led control, the hotkey is Fn + F4, it is a hardware based mute state, and new privacy will prevent micphone void input from hardware layer, any application cannot get voice data when micmute activated. Camera mute use a new hardware design to control the camrea shutter. When video is muted, no OS application should be functionally able to capture images of the person/environment in front of the system Older history: [1]https://patchwork.kernel.org/project/platform-driver-x86/patch/20201228132855.17544-1-perry_y...@dell.com/ [2]https://patchwork.kernel.org/project/alsa-devel/patch/20201103125859.8759-1-perry_y...@dell.com/#23733605 [3]https://www.spinics.net/lists/alsa-devel/msg120537.html [4]https://github.com/thesofproject/linux/pull/2660 [5]https://github.com/thesofproject/linux/issues/2496 Perry Yuan (2): platform/x86: dell-privacy: Add support for Dell hardware privacy ASoC: rt715:add micmute led state control supports .../testing/sysfs-platform-dell-privacy-wmi | 55 +++ drivers/platform/x86/dell/Kconfig | 14 + drivers/platform/x86/dell/Makefile| 1 + drivers/platform/x86/dell/dell-laptop.c | 23 +- drivers/platform/x86/dell/dell-privacy-wmi.c | 441 ++ drivers/platform/x86/dell/dell-privacy-wmi.h | 32 ++ drivers/platform/x86/dell/dell-wmi.c | 13 +- sound/soc/codecs/rt715-sdca.c | 41 +- sound/soc/codecs/rt715.c | 41 ++ 9 files changed, 653 insertions(+), 8 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi create mode 100644 drivers/platform/x86/dell/dell-privacy-wmi.c create mode 100644 drivers/platform/x86/dell/dell-privacy-wmi.h -- 2.25.1
Re: [PATCH v5 1/2] platform/x86: dell-privacy: Add support for Dell hardware privacy
Hi Hans. Thanks for your suggestion helping to improve the patch. On 3/24/21 7:39 AM, Hans de Goede wrote: Hi, On 3/24/21 12:19 PM, Hans de Goede wrote: Hi, On 3/22/21 10:38 AM, Perry Yuan wrote: From: Perry Yuan add support for Dell privacy driver for the Dell units equipped hardware privacy design, which protect users privacy of audio and camera from hardware level. Once the audio or camera privacy mode activated, any applications will not get any audio or video stream when user pressed ctrl+F4 hotkey, audio privacy mode will be enabled, micmute led will be also changed accordingly The micmute led is fully controlled by hardware & EC(embedded controller) and camera mute hotkey is Ctrl+F9. Currently design only emmits SW_CAMERA_LENS_COVER event while the camera lens shutter will be changed by EC & hw(hadware) control *The flow is like this: 1) User presses key. HW does stuff with this key (timeout timer is started) 2) WMI event is emitted from BIOS to kernel 3) WMI event is received by dell-privacy 4) KEY_MICMUTE emitted from dell-privacy 5) Userland picks up key and modifies kcontrol for SW mute 6) Codec kernel driver catches and calls ledtrig_audio_set, like this: ledtrig_audio_set(LED_AUDIO_MICMUTE, rt715->micmute_led ? LED_ON :LED_OFF); 7) If "LED" is set to on dell-privacy notifies EC, and timeout is cancelled, HW mic mute activated. Signed-off-by: Perry Yuan One last remark, I think that the dell_privacy_present() function which I suggested in my review should be renamed to: dell_privacy_has_micmute() and then its return should check the micmute feature bit in priv->features_present and this new function should then be used in dell-laptop.c to determine it dell-laptop.c should register its own mic-mute led_classdev. This way if a theoretical future laptop shows up where the micmute feature is not implemented by the privacy interface dell-laptop.c will still register the non-privacy mic-mute led_classdev. Regards, Hans Yes, I rename the micmute checking function to dell_privacy_has_micmute. and i rewrite it to simplify the micmute checking process. I am doing some testing and drive other feedback to be finished. Will post V6 soon for your confirm. Perry. --- v4 -> v5: * addressed feedback from Randy Dunlap * addressed feedback from Pierre-Louis Bossart * rebase to latest 5.12 rc4 upstream kernel * fix some space alignment problem v3 -> v4: * fix format for Kconfig * add sysfs document * add flow comments to the privacy wmi/acpi driver * addressed feedback from Barnabás Pőcze[Thanks very much] * export privacy_valid to make the global state simpler to query * fix one issue which will block the dell-laptop driver to load when privacy driver invalid * addressed feedback from Pierre-Louis Bossart,remove the EC ID match v2 -> v3: * add sysfs attributes doc v1 -> v2: * query EC handle from EC driver directly. * fix some code style. * add KEY_END to keymap array. * clean platform device when cleanup called * use hexadecimal format for log print in dev_dbg * remove __set_bit for the report keys from probe. * fix keymap leak * add err_free_keymap in dell_privacy_wmi_probe * wmi driver will be unregistered if privacy_acpi_init() fails * add sysfs attribute files for user space query. * add leds micmute driver to privacy acpi * add more design info the commit info --- --- .../testing/sysfs-platform-dell-privacy-wmi | 32 ++ drivers/platform/x86/dell/Kconfig | 16 + drivers/platform/x86/dell/Makefile| 3 + drivers/platform/x86/dell/dell-laptop.c | 23 +- drivers/platform/x86/dell/dell-privacy-acpi.c | 164 + drivers/platform/x86/dell/dell-privacy-wmi.c | 340 ++ drivers/platform/x86/dell/dell-privacy-wmi.h | 35 ++ drivers/platform/x86/dell/dell-wmi.c | 27 +- 8 files changed, 627 insertions(+), 13 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi create mode 100644 drivers/platform/x86/dell/dell-privacy-acpi.c create mode 100644 drivers/platform/x86/dell/dell-privacy-wmi.c create mode 100644 drivers/platform/x86/dell/dell-privacy-wmi.h diff --git a/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi b/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi new file mode 100644 index ..20c15a51ec38 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi @@ -0,0 +1,32 @@ +What: /sys/bus/wmi/devices/6932965F-1671-4CEB-B988-D3AB0A901919/devices_supported +Date: Feb 2021 +KernelVersion: 5.12 +Contact: "perry.y...@dell.com>" +Description: + Display which dell hardware level privacy devices are supported + “Dell Privacy” is a set of HW, FW, and SW features to enhance + Dell’s commitment to platform privacy for MIC, Camera, and + ePrivacy screen
Re: [PATCH v5 1/2] platform/x86: dell-privacy: Add support for Dell hardware privacy
Hi Pierre Thanks for your review . I changed the patch and explain the review comments as below (Maybe the mail format has problem, sent from one new system thunderbird :) On 3/23/21 2:57 PM, Pierre-Louis Bossart wrote: Minor comments below. On 3/22/21 4:38 AM, Perry Yuan wrote: From: Perry Yuan add support for Dell privacy driver for the Dell units equipped hardware privacy design, which protect users privacy of audio and camera from hardware level. Once the audio or camera privacy mode activated, any applications will not get any audio or video stream when user pressed ctrl+F4 hotkey, audio privacy mode will be enabled, micmute led will be also changed accordingly The micmute led is fully controlled by hardware & EC(embedded controller) and camera mute hotkey is Ctrl+F9. Currently design only emmits typo: emits fixed SW_CAMERA_LENS_COVER event while the camera lens shutter will be changed by EC & hw(hadware) control typo: hardware fixed *The flow is like this: 1) User presses key. HW does stuff with this key (timeout timer is started) 2) WMI event is emitted from BIOS to kernel 3) WMI event is received by dell-privacy 4) KEY_MICMUTE emitted from dell-privacy 5) Userland picks up key and modifies kcontrol for SW mute 6) Codec kernel driver catches and calls ledtrig_audio_set, like this: ledtrig_audio_set(LED_AUDIO_MICMUTE, rt715->micmute_led ? LED_ON :LED_OFF); 7) If "LED" is set to on dell-privacy notifies EC, and timeout is cancelled, HW mic mute activated. what happens if there is timeout? You have an explicit description of the timer handling in the success case, but not what happens on a timeout... add more explicit description for timeout triggered case 7) If "LED" is set to on dell-privacy notifies EC, and timeout is cancelled. HW mic mute activated. If EC not notified,HW mic mute will also be activated when timeout used up, it is just later than active ack diff --git a/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi b/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi new file mode 100644 index ..20c15a51ec38 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi @@ -0,0 +1,32 @@ +What: /sys/bus/wmi/devices/6932965F-1671-4CEB-B988-D3AB0A901919/devices_supported +Date: Feb 2021 +KernelVersion: 5.12 5.13 now? changed to 5.13 +static int dell_privacy_micmute_led_set(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct privacy_acpi_priv *priv = privacy_acpi; + acpi_status status; + acpi_handle handle; + static char *acpi_method = (char *)"ECAK"; + + handle = ec_get_handle(); + if (!handle) + return -EIO; + if (!acpi_has_method(handle, acpi_method)) + return -EIO; + status = acpi_evaluate_object(handle, acpi_method, NULL, NULL); + if (ACPI_FAILURE(status)) { + dev_err(priv->dev, "Error setting privacy EC ack value: %s\n", + acpi_format_exception(status)); + return -EIO; + } + pr_debug("set dell privacy micmute ec ack event done\n"); can we use dev_dbg() here? Same for all occurrences of pr_debug and pr_err below, it's cleaner and easier to filter. I changed some pr_xx to dev_xxx , but below code will be more complex to use dev_xxx to print the log , because it need to get the priv->dev, but it is not registered at this time , I would prefer to keep use the pr_debug here. and some other cases where "priv->dev" cannot be used. static int __init init_dell_privacy(void) { int ret; ret = wmi_has_guid(DELL_PRIVACY_GUID); if (!ret) { privacy_valid = -ENODEV; pr_debug("Unable to detect available Dell privacy devices: %d\n", ret); return privacy_valid; } + return 0; +} + +static int dell_privacy_acpi_remove(struct platform_device *pdev) +{ + struct privacy_acpi_priv *priv = dev_get_drvdata(privacy_acpi->dev); + + led_classdev_unregister(&priv->cdev); + + return 0; +} +/* + * Pressing the mute key activates a time delayed circuit to physically cut + * off the mute. The LED is in the same circuit, so it reflects the true + * state of the HW mute. The reason for the EC "ack" is so that software + * can first invoke a SW mute before the HW circuit is cut off. Without SW + * cutting this off first does not affect the time delayed muting or status + * of the LED but there is a possibility of a "popping" noise. + * + * If the EC receives the SW ack, the circuit will be activated before the + * delay completed. + * + * Exposing as an LED device allows the codec drivers notification path to + * EC ACK to work + */ +static int dell_privacy_leds_setup(struct device *dev) +{ + struct privacy_acpi_priv *priv = dev_get_dr
[PATCH v5 2/2] ASoC: rt715:add micmute led state control supports
From: Perry Yuan Some new Dell system is going to support audio internal micphone privacy setting from hardware level with micmute led state changing When micmute hotkey pressed by user, soft mute will need to be enabled firstly in case of pop noise, and codec driver need to react to mic mute event to EC(embedded controller) notifying that SW mute is completed Then EC will do the hardware mute physically within the timeout reached This patch allow codec rt715 and rt715 sdca driver to change the local micmute led state. Dell privacy led trigger driver will ack EC when micmute key pressed through this micphone led control interface like hda_generic provided ACPI method defined in dell-privacy micmute led trigger will be called for notifying the EC that software mute has been completed, then hardware audio circuit solution controlled by EC will switch the audio input source off/on Signed-off-by: Perry Yuan v4 -> v5: * rebase to latest 5.12 rc4 upstream kernel v3 -> v4: * remove unused debug log * remove compile flag of DELL privacy * move the micmute_led to local from rt715_priv * when Jaroslav upstream his gerneric LED trigger driver,I will rebase this patch,please consider merge this at first https://lore.kernel.org/alsa-devel/2021021400.1131020-1-pe...@perex.cz/ v2 -> v3: * simplify the patch to reuse some val value * add more detail to the commit info v1 -> v2: * fix some format issue --- sound/soc/codecs/rt715-sdca.c | 11 +++ sound/soc/codecs/rt715.c | 12 2 files changed, 23 insertions(+) diff --git a/sound/soc/codecs/rt715-sdca.c b/sound/soc/codecs/rt715-sdca.c index 20528afbdc57..70e1181f1dee 100644 --- a/sound/soc/codecs/rt715-sdca.c +++ b/sound/soc/codecs/rt715-sdca.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -358,6 +359,7 @@ static int rt715_sdca_put_volsw(struct snd_kcontrol *kcontrol, unsigned int mask = (1 << fls(max)) - 1; unsigned int invert = p->invert; int err; + bool micmute_led; for (i = 0; i < 4; i++) { if (ucontrol->value.integer.value[i] != rt715->kctl_switch_orig[i]) { @@ -393,6 +395,15 @@ static int rt715_sdca_put_volsw(struct snd_kcontrol *kcontrol, if (err < 0) return err; } + /* Micmute LED state changed by muted/unmute switch */ + if (invert) { + if (ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1]) { + micmute_led = LED_OFF; + } else { + micmute_led = LED_ON; + } + ledtrig_audio_set(LED_AUDIO_MICMUTE, micmute_led); + } return k_changed; } diff --git a/sound/soc/codecs/rt715.c b/sound/soc/codecs/rt715.c index 34c3357e943b..13686c5239b3 100644 --- a/sound/soc/codecs/rt715.c +++ b/sound/soc/codecs/rt715.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -88,6 +89,7 @@ static int rt715_set_amp_gain_put(struct snd_kcontrol *kcontrol, RT715_SET_GAIN_MIX_ADC2_L}; unsigned int addr_h, addr_l, val_h, val_ll, val_lr; unsigned int read_ll, read_rl, i, j, loop_cnt; + bool micmute_led; if (strstr(ucontrol->id.name, "Main Capture Switch") || strstr(ucontrol->id.name, "Main Capture Volume")) @@ -95,6 +97,16 @@ static int rt715_set_amp_gain_put(struct snd_kcontrol *kcontrol, else loop_cnt = 1; + /* Micmute LED state changed by muted/unmute switch */ + if (mc->invert) { + if (ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1]) { + micmute_led = LED_OFF; + } else { + micmute_led = LED_ON; + } + ledtrig_audio_set(LED_AUDIO_MICMUTE, micmute_led); + } + for (j = 0; j < loop_cnt; j++) { /* Can't use update bit function, so read the original value first */ if (loop_cnt == 1) { -- 2.25.1
[PATCH v5 1/2] platform/x86: dell-privacy: Add support for Dell hardware privacy
From: Perry Yuan add support for Dell privacy driver for the Dell units equipped hardware privacy design, which protect users privacy of audio and camera from hardware level. Once the audio or camera privacy mode activated, any applications will not get any audio or video stream when user pressed ctrl+F4 hotkey, audio privacy mode will be enabled, micmute led will be also changed accordingly The micmute led is fully controlled by hardware & EC(embedded controller) and camera mute hotkey is Ctrl+F9. Currently design only emmits SW_CAMERA_LENS_COVER event while the camera lens shutter will be changed by EC & hw(hadware) control *The flow is like this: 1) User presses key. HW does stuff with this key (timeout timer is started) 2) WMI event is emitted from BIOS to kernel 3) WMI event is received by dell-privacy 4) KEY_MICMUTE emitted from dell-privacy 5) Userland picks up key and modifies kcontrol for SW mute 6) Codec kernel driver catches and calls ledtrig_audio_set, like this: ledtrig_audio_set(LED_AUDIO_MICMUTE, rt715->micmute_led ? LED_ON :LED_OFF); 7) If "LED" is set to on dell-privacy notifies EC, and timeout is cancelled, HW mic mute activated. Signed-off-by: Perry Yuan --- v4 -> v5: * addressed feedback from Randy Dunlap * addressed feedback from Pierre-Louis Bossart * rebase to latest 5.12 rc4 upstream kernel * fix some space alignment problem v3 -> v4: * fix format for Kconfig * add sysfs document * add flow comments to the privacy wmi/acpi driver * addressed feedback from Barnabás Pőcze[Thanks very much] * export privacy_valid to make the global state simpler to query * fix one issue which will block the dell-laptop driver to load when privacy driver invalid * addressed feedback from Pierre-Louis Bossart,remove the EC ID match v2 -> v3: * add sysfs attributes doc v1 -> v2: * query EC handle from EC driver directly. * fix some code style. * add KEY_END to keymap array. * clean platform device when cleanup called * use hexadecimal format for log print in dev_dbg * remove __set_bit for the report keys from probe. * fix keymap leak * add err_free_keymap in dell_privacy_wmi_probe * wmi driver will be unregistered if privacy_acpi_init() fails * add sysfs attribute files for user space query. * add leds micmute driver to privacy acpi * add more design info the commit info --- --- .../testing/sysfs-platform-dell-privacy-wmi | 32 ++ drivers/platform/x86/dell/Kconfig | 16 + drivers/platform/x86/dell/Makefile| 3 + drivers/platform/x86/dell/dell-laptop.c | 23 +- drivers/platform/x86/dell/dell-privacy-acpi.c | 164 + drivers/platform/x86/dell/dell-privacy-wmi.c | 340 ++ drivers/platform/x86/dell/dell-privacy-wmi.h | 35 ++ drivers/platform/x86/dell/dell-wmi.c | 27 +- 8 files changed, 627 insertions(+), 13 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi create mode 100644 drivers/platform/x86/dell/dell-privacy-acpi.c create mode 100644 drivers/platform/x86/dell/dell-privacy-wmi.c create mode 100644 drivers/platform/x86/dell/dell-privacy-wmi.h diff --git a/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi b/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi new file mode 100644 index ..20c15a51ec38 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi @@ -0,0 +1,32 @@ +What: /sys/bus/wmi/devices/6932965F-1671-4CEB-B988-D3AB0A901919/devices_supported +Date: Feb 2021 +KernelVersion: 5.12 +Contact: "perry.y...@dell.com>" +Description: + Display which dell hardware level privacy devices are supported + “Dell Privacy” is a set of HW, FW, and SW features to enhance + Dell’s commitment to platform privacy for MIC, Camera, and + ePrivacy screens. + The supported hardware privacy devices are: + - 0 = Not Supported + - 1 = Supported + - Bit0 -> Microphone + - Bit1 -> Camera + - Bit2 -> ePrivacy Screen + +What: /sys/bus/wmi/devices/6932965F-1671-4CEB-B988-D3AB0A901919/current_state +Date: Feb 2021 +KernelVersion: 5.12 +Contact: "perry.y...@dell.com>" +Description: + Allow user space to check current dell privacy device state. + Describes the Device State class exposed by BIOS which can be + consumed by various applications interested in knowing the Privacy + feature capabilities + There are three Bits for available states: + - 0 = Enabled + - 1 = Disabled + - Bit0 -> Microphone + - Bit1 -> Camera + - Bit2 -> ePrivacyScreen + diff --git a/drivers/platform/x86/dell/Kconfig b/drivers/platform/x86/dell/Kc
[PATCH v5 0/2] hardware-privacy-implementation-for-dell-laptop
From: Perry Yuan Hi All, This patch set is a new driver for Dell mobile platform that has the hardware privacy feature including micmute,camera mute. For micmute led control, the hotkey is Fn + F4, it is a hardware based mute state, and new privacy will prevent micphone void input from hardware layer, any application cannot get voice data when micmute activated. Camera mute use a new hardware design to control the camrea shutter. When video is muted, no OS application should be functionally able to capture images of the person/environment in front of the system Older history: [1]https://patchwork.kernel.org/project/platform-driver-x86/patch/20201228132855.17544-1-perry_y...@dell.com/ [2]https://patchwork.kernel.org/project/alsa-devel/patch/20201103125859.8759-1-perry_y...@dell.com/#23733605 [3]https://www.spinics.net/lists/alsa-devel/msg120537.html [4]https://github.com/thesofproject/linux/pull/2660 [5]https://github.com/thesofproject/linux/issues/2496 Perry Yuan (2): platform/x86: dell-privacy: Add support for Dell hardware privacy ASoC: rt715:add micmute led state control supports .../testing/sysfs-platform-dell-privacy-wmi | 32 ++ drivers/platform/x86/dell/Kconfig | 16 + drivers/platform/x86/dell/Makefile| 3 + drivers/platform/x86/dell/dell-laptop.c | 23 +- drivers/platform/x86/dell/dell-privacy-acpi.c | 164 + drivers/platform/x86/dell/dell-privacy-wmi.c | 340 ++ drivers/platform/x86/dell/dell-privacy-wmi.h | 35 ++ drivers/platform/x86/dell/dell-wmi.c | 27 +- sound/soc/codecs/rt715-sdca.c | 11 + sound/soc/codecs/rt715.c | 12 + 10 files changed, 650 insertions(+), 13 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi create mode 100644 drivers/platform/x86/dell/dell-privacy-acpi.c create mode 100644 drivers/platform/x86/dell/dell-privacy-wmi.c create mode 100644 drivers/platform/x86/dell/dell-privacy-wmi.h -- 2.25.1
Re: [PATCH v4 1/2] platform/x86: dell-privacy: Add support for Dell hardware privacy
Hi Pierre: Thanks for your review! On 2021/3/8 23:59, Pierre-Louis Bossart wrote: module_param(force_rfkill, bool, 0444); MODULE_PARM_DESC(force_rfkill, "enable rfkill on non whitelisted models"); + spurious line change I just want to make them separate with more space . If it cause concern, I will remote the line in V5. it's fine to improve spaces/alignment, just do it in a separate patch. static const struct dmi_system_id dell_device_table[] __initconst = { { .ident = "Dell laptop", @@ -2205,11 +2209,17 @@ static int __init dell_init(void) dell_laptop_register_notifier(&dell_laptop_notifier); if (dell_smbios_find_token(GLOBAL_MIC_MUTE_DISABLE) && - dell_smbios_find_token(GLOBAL_MIC_MUTE_ENABLE)) { - micmute_led_cdev.brightness = ledtrig_audio_get(LED_AUDIO_MICMUTE); - ret = led_classdev_register(&platform_device->dev, &micmute_led_cdev); - if (ret < 0) - goto fail_led; + dell_smbios_find_token(GLOBAL_MIC_MUTE_ENABLE)) { not sure why you changed the alignment? The previous alignment is a little not correct. So I adjust it If it cause concern, will restore it to original shape. same here, use a different patch. As you suggested,I should add the alignment change in another patch. But if i keep the old alignment, the code will be very odd. Seems like that I have to change the below code to new alignment in this patch. if (dell_smbios_find_token(GLOBAL_MIC_MUTE_DISABLE) && dell_smbios_find_token(GLOBAL_MIC_MUTE_ENABLE)) { <<--- changed back if (!privacy_valid) has_privacy = true; else has_privacy = false; if (!has_privacy) { micmute_led_cdev.brightness <<--- new alignment ... } ... }
[PATCH v4 2/2] ASoC: rt715:add micmute led state control supports
From: Perry Yuan Some new Dell system is going to support audio internal micphone privacy setting from hardware level with micmute led state changing When micmute hotkey pressed by user, soft mute will need to be enabled firstly in case of pop noise, and codec driver need to react to mic mute event to EC(embedded controller) notifying that SW mute is completed Then EC will do the hardware mute physically within the timeout reached This patch allow codec rt715 and rt715 sdca driver to change the local micmute led state. Dell privacy led trigger driver will ack EC when micmute key pressed through this micphone led control interface like hda_generic provided ACPI method defined in dell-privacy micmute led trigger will be called for notifying the EC that software mute has been completed, then hardware audio circuit solution controlled by EC will switch the audio input source off/on Signed-off-by: Perry Yuan v3 -> v4: * remove unused debug log * remove compile flag of DELL privacy * move the micmute_led to local from rt715_priv * when Jaroslav upstream his gerneric LED trigger driver,I will rebase this patch,please consider merge this at first https://lore.kernel.org/alsa-devel/2021021400.1131020-1-pe...@perex.cz/ v2 -> v3: * simplify the patch to reuse some val value * add more detail to the commit info v1 -> v2: * fix some format issue --- sound/soc/codecs/rt715-sdca.c | 12 sound/soc/codecs/rt715.c | 12 2 files changed, 24 insertions(+) diff --git a/sound/soc/codecs/rt715-sdca.c b/sound/soc/codecs/rt715-sdca.c index b43ac8559e45..816348ae11a1 100644 --- a/sound/soc/codecs/rt715-sdca.c +++ b/sound/soc/codecs/rt715-sdca.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -269,6 +270,7 @@ static int rt715_sdca_put_volsw(struct snd_kcontrol *kcontrol, unsigned int reg = mc->reg; unsigned int max = mc->max; int err; + bool micmute_led; val = ucontrol->value.integer.value[0]; if (invert) @@ -287,6 +289,16 @@ static int rt715_sdca_put_volsw(struct snd_kcontrol *kcontrol, return err; } + /* Micmute LED state changed by muted/unmute switch */ + if (mc->invert) { + if (ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1]) { + micmute_led = LED_OFF; + } else { + micmute_led = LED_ON; + } + ledtrig_audio_set(LED_AUDIO_MICMUTE, micmute_led); + } + return 0; } diff --git a/sound/soc/codecs/rt715.c b/sound/soc/codecs/rt715.c index cdcba70146da..db2c0d2ff9d2 100644 --- a/sound/soc/codecs/rt715.c +++ b/sound/soc/codecs/rt715.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -88,6 +89,7 @@ static int rt715_set_amp_gain_put(struct snd_kcontrol *kcontrol, RT715_SET_GAIN_MIX_ADC2_L}; unsigned int addr_h, addr_l, val_h, val_ll, val_lr; unsigned int read_ll, read_rl, i, j, loop_cnt; + bool micmute_led; if (strstr(ucontrol->id.name, "Main Capture Switch") || strstr(ucontrol->id.name, "Main Capture Volume")) @@ -95,6 +97,16 @@ static int rt715_set_amp_gain_put(struct snd_kcontrol *kcontrol, else loop_cnt = 1; + /* Micmute LED state changed by muted/unmute switch */ + if (mc->invert) { + if (ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1]) { + micmute_led = LED_OFF; + } else { + micmute_led = LED_ON; + } + ledtrig_audio_set(LED_AUDIO_MICMUTE, micmute_led); + } + for (j = 0; j < loop_cnt; j++) { /* Can't use update bit function, so read the original value first */ if (loop_cnt == 1) { -- 2.25.1
[PATCH v4 1/2] platform/x86: dell-privacy: Add support for Dell hardware privacy
From: Perry Yuan add support for Dell privacy driver for the Dell units equipped hardware privacy design, which protect users privacy of audio and camera from hardware level. Once the audio or camera privacy mode activated, any applications will not get any audio or video stream when user pressed ctrl+F4 hotkey, audio privacy mode will be enabled, micmute led will be also changed accordingly The micmute led is fully controlled by hardware & EC(embedded controller) and camera mute hotkey is Ctrl+F9. Currently design only emmits SW_CAMERA_LENS_COVER event while the camera lens shutter will be changed by EC & hw(hadware) control *The flow is like this: 1) User presses key. HW does stuff with this key (timeout timer is started) 2) WMI event is emitted from BIOS to kernel 3) WMI event is received by dell-privacy 4) KEY_MICMUTE emitted from dell-privacy 5) Userland picks up key and modifies kcontrol for SW mute 6) Codec kernel driver catches and calls ledtrig_audio_set, like this: ledtrig_audio_set(LED_AUDIO_MICMUTE, rt715->micmute_led ? LED_ON :LED_OFF); 7) If "LED" is set to on dell-privacy notifies EC, and timeout is cancelled, HW mic mute activated. Signed-off-by: Perry Yuan --- v3 -> v4: * fix format for Kconfig * add sysfs document * add flow comments to the privacy wmi/acpi driver * addressed feedback from Barnabás Pőcze[Thanks very much] * export privacy_valid to make the global state simpler to query * fix one issue which will block the dell-laptop driver to load when privacy driver invalid * addressed feedback from Pierre-Louis Bossart,remove the EC ID match v2 -> v3: * add sysfs attributes doc v1 -> v2: * query EC handle from EC driver directly. * fix some code style. * add KEY_END to keymap array. * clean platform device when cleanup called * use hexadecimal format for log print in dev_dbg * remove __set_bit for the report keys from probe. * fix keymap leak * add err_free_keymap in dell_privacy_wmi_probe * wmi driver will be unregistered if privacy_acpi_init() fails * add sysfs attribute files for user space query. * add leds micmute driver to privacy acpi * add more design info the commit info --- --- .../testing/sysfs-platform-dell-privacy-wmi | 32 ++ drivers/platform/x86/Kconfig | 17 + drivers/platform/x86/Makefile | 4 +- drivers/platform/x86/dell-laptop.c| 26 +- drivers/platform/x86/dell-privacy-acpi.c | 164 + drivers/platform/x86/dell-privacy-wmi.c | 340 ++ drivers/platform/x86/dell-privacy-wmi.h | 35 ++ drivers/platform/x86/dell-wmi.c | 29 +- 8 files changed, 631 insertions(+), 16 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi create mode 100644 drivers/platform/x86/dell-privacy-acpi.c create mode 100644 drivers/platform/x86/dell-privacy-wmi.c create mode 100644 drivers/platform/x86/dell-privacy-wmi.h diff --git a/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi b/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi new file mode 100644 index ..20c15a51ec38 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi @@ -0,0 +1,32 @@ +What: /sys/bus/wmi/devices/6932965F-1671-4CEB-B988-D3AB0A901919/devices_supported +Date: Feb 2021 +KernelVersion: 5.12 +Contact: "perry.y...@dell.com>" +Description: + Display which dell hardware level privacy devices are supported + “Dell Privacy” is a set of HW, FW, and SW features to enhance + Dell’s commitment to platform privacy for MIC, Camera, and + ePrivacy screens. + The supported hardware privacy devices are: + - 0 = Not Supported + - 1 = Supported + - Bit0 -> Microphone + - Bit1 -> Camera + - Bit2 -> ePrivacy Screen + +What: /sys/bus/wmi/devices/6932965F-1671-4CEB-B988-D3AB0A901919/current_state +Date: Feb 2021 +KernelVersion: 5.12 +Contact: "perry.y...@dell.com>" +Description: + Allow user space to check current dell privacy device state. + Describes the Device State class exposed by BIOS which can be + consumed by various applications interested in knowing the Privacy + feature capabilities + There are three Bits for available states: + - 0 = Enabled + - 1 = Disabled + - Bit0 -> Microphone + - Bit1 -> Camera + - Bit2 -> ePrivacyScreen + diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 91e6176cdfbd..e20f79389a39 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -491,6 +491,23 @@ config DELL_WMI_LED This adds support for the Latitude
[PATCH v4 0/2] Dell-hardware-privacy-implementation-for-dell-laptop
From: Perry Yuan Hi All, This patch set is a new driver for dell mobile platform ,which has the hardware privacy feature. For micmute led control, the hotkey is Fn + F4, it is a hardware based mute state, and new privacy will prevent micphone void input from hardware layer, any application cannot get voice data when micmute activated. Camera mute use a new hardware design to control the camrea shutter. When video is muted, no OS application should be functionally able to capture images of the person/environment in front of the system Older history: [1]https://patchwork.kernel.org/project/platform-driver-x86/patch/20201228132855.17544-1-perry_y...@dell.com/ [2]https://patchwork.kernel.org/project/alsa-devel/patch/20201103125859.8759-1-perry_y...@dell.com/#23733605 [3]https://www.spinics.net/lists/alsa-devel/msg120537.html [4]https://github.com/thesofproject/linux/pull/2660 Perry Yuan (2): platform/x86: dell-privacy: Add support for Dell hardware privacy ASoC: rt715:add micmute led state control supports .../testing/sysfs-platform-dell-privacy-wmi | 32 ++ drivers/platform/x86/Kconfig | 17 + drivers/platform/x86/Makefile | 4 +- drivers/platform/x86/dell-laptop.c| 26 +- drivers/platform/x86/dell-privacy-acpi.c | 164 + drivers/platform/x86/dell-privacy-wmi.c | 340 ++ drivers/platform/x86/dell-privacy-wmi.h | 35 ++ drivers/platform/x86/dell-wmi.c | 29 +- sound/soc/codecs/rt715-sdca.c | 12 + sound/soc/codecs/rt715.c | 12 + 10 files changed, 655 insertions(+), 16 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi create mode 100644 drivers/platform/x86/dell-privacy-acpi.c create mode 100644 drivers/platform/x86/dell-privacy-wmi.c create mode 100644 drivers/platform/x86/dell-privacy-wmi.h -- 2.25.1
Re: [PATCH v3 1/3] platform/x86: dell-privacy: Add support for Dell hardware privacy
Hi Pierre: On 2021/2/16 22:56, Pierre-Louis Bossart wrote: +static const struct acpi_device_id privacy_acpi_device_ids[] = { + {"PNP0C09", 0}, + { }, +}; +MODULE_DEVICE_TABLE(acpi, privacy_acpi_device_ids); + +static struct platform_driver dell_privacy_platform_drv = { + .driver = { + .name = PRIVACY_PLATFORM_NAME, + .acpi_match_table = ACPI_PTR(privacy_acpi_device_ids), + }, no .probe? Originally i added the probe here, but it cause the driver .probe called twice. after i use platform_driver_probe to register the driver loading process, the duplicated probe issue resolved. I + .remove = dell_privacy_acpi_remove, +}; + +int __init dell_privacy_acpi_init(void) +{ + int err; + struct platform_device *pdev; + int privacy_capable = wmi_has_guid(DELL_PRIVACY_GUID); + + if (!wmi_has_guid(DELL_PRIVACY_GUID)) + return -ENODEV; + + privacy_acpi = kzalloc(sizeof(*privacy_acpi), GFP_KERNEL); + if (!privacy_acpi) + return -ENOMEM; + + pdev = platform_device_register_simple( + PRIVACY_PLATFORM_NAME, PLATFORM_DEVID_NONE, NULL, 0); + if (IS_ERR(pdev)) { + err = PTR_ERR(pdev); + goto pdev_err; + } + err = platform_driver_probe(&dell_privacy_platform_drv, + dell_privacy_acpi_probe); + if (err) + goto pdrv_err; why is the probe done here? Put differently, what prevents you from using a 'normal' platform driver, and do the leds_setup in the .probe()? At first ,I used the normal platform driver framework, however tt cause the driver .probe called twice. after i use platform_driver_probe to register the driver loading process, the duplicated probe issue resolved. This sounds very odd... this looks like a conflict with the ACPI subsystem finding a device and probing the driver that's associated with the PNP0C09 HID, and then this module __init creating a device manually which leads to a second probe Neither the platform_device_register_simple() nor platform_driver_probe() seem necessary?Because this privacy acpi driver file has dependency on the ec handle, so i want to determine if the driver can be loaded basing on the EC ID PNP0C09 matching. So far,It works well for me to register the privacy driver with the register sequence. Dose it hurt to keep current registering process with platform_driver_probe used? Perry
Re: [PATCH v2 1/2] platform/x86: dell-privacy: Add support for Dell hardware privacy
Hi Hans: On 2021/1/13 2:37, Hans de Goede wrote: Hi, I know there already is a v3 out and I will try to get around to reviewing that soon, still 1 remark about the discussion surrounding v2: On 1/11/21 2:42 PM, Perry Yuan wrote: *The flow is like this: 1) User presses key. HW does stuff with this key (timeout is started) 2) Event is emitted from FW 3) Event received by dell-privacy 4) KEY_MICMUTE emitted from dell-privacy 5) Userland picks up key and modifies kcontrol for SW mute 6) Codec kernel driver catches and calls ledtrig_audio_set, like this: ledtrig_audio_set(LED_AUDIO_MICMUTE, rt715->micmute_led ? LED_ON :LED_OFF); 7) If "LED" is set to on dell-privacy notifies ec, and timeout is cancelled,HW mic mute activated. Please proofread the commit message again, and pay attention to capitalization and spacing. I want to reformat it and move the commit info to cover letter. Please also put a copy of this as a comment in either the wmi or the acpi driver (with a comment pointing to the comment in the other) this is important info to have for someone reading the code and trying to understand how this all fits together. Regards, Hans Hans. I have added the comments to the dell-privacy driver file in V4 --- drivers/platform/x86/dell-privacy-wmi.c EXPORT_SYMBOL_GPL(dell_privacy_valid); /* * The flow of privacy event: * 1) User presses key. HW does stuff with this key (timeout is started) * 2) WMI event is emitted from BIOS * 3) WMI event is received by dell-privacy * 4) KEY_MICMUTE emitted from dell-privacy * 5) Userland picks up key and modifies kcontrol for SW mute * 6) Codec kernel driver catches and calls ledtrig_audio_set defined by *dell-privacy-acpi driver. *codec driver will call like this to switch micmute led state. * ledtrig_audio_set(LED_AUDIO_MICMUTE, micmute_led ? LED_ON :LED_OFF); * 7) If "LED" is set to on dell-privacy notifies EC,and timeout is cancelled, * HW mic mute activated. */ void dell_privacy_process_event(int type, int code, int status) { struct privacy_wmi_data *priv; const struct key_entry *key; mutex_lock(&list_mutex); --- drivers/platform/x86/dell-privacy-acpi.c /* * Pressing the mute key activates a time delayed circuit to physically cut * off the mute. The LED is in the same circuit, so it reflects the true * state of the HW mute. The reason for the EC "ack" is so that software * can first invoke a SW mute before the HW circuit is cut off. Without SW * cutting this off first does not affect the time delayed muting or status * of the LED but there is a possibility of a "popping" noise. * * If the EC receives the SW ack, the circuit will be activated before the * delay completed. * * Exposing as an LED device allows the codec drivers notification path to * EC ACK to work */ static int dell_privacy_leds_setup(struct device *dev) { struct privacy_acpi_priv *priv = dev_get_drvdata(dev); int ret = 0; .
Re: [PATCH v3 1/3] platform/x86: dell-privacy: Add support for Dell hardware privacy
Hi Pierre: thanks for the review effort. On 2021/1/13 3:00, Pierre-Louis Bossart wrote: On 1/12/21 11:17 AM, Perry Yuan wrote: From: Perry Yuan add support for dell privacy driver for the dell units equipped hardware privacy design, which protect users privacy of audio and camera from hardware level. once the audio or camera privacy mode enabled, any applications will not get any audio or video stream when user pressed ctrl+F4 hotkey, audio privacy mode will be enabled,Micmute led will be also changed accordingly The micmute led is fully controlled by hardware & EC(embedded controller) and camera mute hotkey is ctrl+f9. currently design only emmit SW_CAMERA_LENS_COVER event while the camera lens shutter will be changed by EC & hw(hadware) control It wouldn't hurt to use capital letters and punctuation, it helps with readility.. I will try to improve the description in V4 [...] diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index 70edc5bb3a14..2fea1f34fcf9 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -30,6 +30,7 @@ #include #include "dell-rbtn.h" #include "dell-smbios.h" +#include "dell-privacy-wmi.h" struct quirk_entry { bool touchpad_led; @@ -90,6 +91,7 @@ static struct rfkill *wifi_rfkill; static struct rfkill *bluetooth_rfkill; static struct rfkill *wwan_rfkill; static bool force_rfkill; +static bool privacy_valid; why is this variable needed? Was the intent to have a kernel parameter here? The var is used to mark if the Dell privacy wmi driver was loaded successfully for now,if privacy loaded,the micmute_led_cdev.brightness will not be registered by dell-laptop, it will be in dell-privacy-acpi file using dell_privacy_leds_setup to register the led class. module_param(force_rfkill, bool, 0444); MODULE_PARM_DESC(force_rfkill, "enable rfkill on non whitelisted models"); @@ -2205,11 +2207,18 @@ static int __init dell_init(void) dell_laptop_register_notifier(&dell_laptop_notifier); if (dell_smbios_find_token(GLOBAL_MIC_MUTE_DISABLE) && - dell_smbios_find_token(GLOBAL_MIC_MUTE_ENABLE)) { - micmute_led_cdev.brightness = ledtrig_audio_get(LED_AUDIO_MICMUTE); - ret = led_classdev_register(&platform_device->dev, &micmute_led_cdev); - if (ret < 0) - goto fail_led; + dell_smbios_find_token(GLOBAL_MIC_MUTE_ENABLE)) { +#if IS_ENABLED(CONFIG_DELL_PRIVACY) + ret = dell_privacy_valid(); + if (!ret) + privacy_valid = true; +#endif + if (!privacy_valid) { if it was intended to be used as a kernel parameter it's not done the right way: the value set by the user would be ignored... The privacy_valid value will be retrieved from dell-privacy-wmi showing if the privacy driver loaded. + micmute_led_cdev.brightness = ledtrig_audio_get(LED_AUDIO_MICMUTE); + ret = led_classdev_register(&platform_device->dev, &micmute_led_cdev); + if (ret < 0) + goto fail_led; + } } if (acpi_video_get_backlight_type() != acpi_backlight_vendor) @@ -2257,7 +2266,8 @@ static int __init dell_init(void) fail_get_brightness: backlight_device_unregister(dell_backlight_device); fail_backlight: - led_classdev_unregister(&micmute_led_cdev); + if (!privacy_valid) + led_classdev_unregister(&micmute_led_cdev); fail_led: dell_cleanup_rfkill(); fail_rfkill: @@ -2278,7 +2288,8 @@ static void __exit dell_exit(void) touchpad_led_exit(); kbd_led_exit(); backlight_device_unregister(dell_backlight_device); - led_classdev_unregister(&micmute_led_cdev); + if (!privacy_valid) + led_classdev_unregister(&micmute_led_cdev); dell_cleanup_rfkill(); if (platform_device) { platform_device_unregister(platform_device); diff --git a/drivers/platform/x86/dell-privacy-acpi.c b/drivers/platform/x86/dell-privacy-acpi.c new file mode 100644 index ..df6a86e1345c --- /dev/null +++ b/drivers/platform/x86/dell-privacy-acpi.c @@ -0,0 +1,167 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Dell privacy notification driver + * + * Copyright (C) 2021 Dell Inc. All Rights Reserved. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dell-privacy-wmi.h" + +#define PRIVACY_PLATFORM_NAME "dell-privacy-acpi" +#define DELL_PRIVACY_GUID "6932965F-1671-4CEB-B988-D3AB0A901919" + +struct privacy_acpi_priv { + struct device *dev; + struct platform_device *platform_device; + struct led_classdev cdev; +}; +static struct privacy_acpi_priv *privacy_acpi;
Re: [PATCH v3 2/3] x86/platform/dell-privacy-wmi: add document for dell privacy driver
Hi Mario: Thanks for the review. On 2021/1/13 1:54, Limonciello, Mario wrote: -Original Message- From: Yuan, Perry Sent: Tuesday, January 12, 2021 11:18 To: oder_ch...@realtek.com; pe...@perex.cz; ti...@suse.com; hdego...@redhat.com; mgr...@linux.intel.com Cc: lgirdw...@gmail.com; broo...@kernel.org; alsa-de...@alsa-project.org; linux-kernel@vger.kernel.org; platform-driver-...@vger.kernel.org; Yuan, Perry; Limonciello, Mario Subject: [PATCH v3 2/3] x86/platform/dell-privacy-wmi: add document for dell privacy driver From: Perry Yuan Describe the Dell Privacy feature capabilities and devices state class exposed by BIOS Signed-off-by: Perry Yuan --- .../testing/sysfs-platform-dell-privacy-wmi | 31 +++ 1 file changed, 31 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi I don't see a reason that the documentation needs to come in it's own commit. In v4, I would think this can collapse as part of: "Add support for Dell hardware privacy" Merged this commit PR to privacy PR in V4. diff --git a/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi b/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi new file mode 100644 index ..3dbc2d25b60e --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi @@ -0,0 +1,31 @@ +What: /sys/bus/wmi/devices/6932965F-1671-4CEB-B988- D3AB0A901919/devices_supported +Date: Jan 2021 +KernelVersion: 5.11 I think this is 5.12 material now. Need to update this to approximate 5.12 date. Updated KernelVersion and Date in V4. +Contact: "perry_y...@dell.com>" I think Dell addresses publicly use a period rather than an underscore, no? So shouldn't this be perry.y...@dell.com? (Although I acknowledge it's an alias, I don't trust that I/T wouldn't remove that some day). +Description: + Display which dell hardware level privacy devices are supported + “Dell Privacy” is a set of HW, FW, and SW features to enhance + Dell’s commitment to platform privacy for MIC, Camera, and + ePrivacy screens. + The supported privacy haredware privacy devices are: You have a typo here. Fixed. +* 0x0 - None, +* 0x1 - Microphone, +* 0x2 - Camera, +* 0x4 - ePrivacy Screen So this is an bitmap encoded in the integer? I think that needs to be mentioned in the documentation. will be updated in V4 like this: ePrivacy screens. The supported hardware privacy devices are: - 0 = Not Supported - 1 = Supported - Bit0 -> Microphone - Bit1 -> Camera - Bit2 -> ePrivacy Screen + +What: /sys/bus/wmi/devices/6932965F-1671-4CEB-B988- D3AB0A901919/current_state +Date: Jan 2021 +KernelVersion: 5.11 +Contact: "perry_y...@dell.com>" +Description: + Allow user space to check current dell privacy device state. + Describes the Device State class exposed by BIOS which can be + consumed by various applications interested in knowing the Privacy + feature capabilities + There are three Bits for available states: + * 0 -> Off + * 1 -> On + * Bit0 -> Microphone + * Bit1 -> Camera + * Bit2 -> ePrivacyScreen + -- 2.25.1
Re: [PATCH v3 1/3] platform/x86: dell-privacy: Add support for Dell hardware privacy
Hi Randy. On 2021/1/13 1:39, Randy Dunlap wrote: On 1/12/21 9:17 AM, Perry Yuan wrote: +config DELL_PRIVACY + tristate "Dell Hardware Privacy Support" + depends on ACPI + depends on ACPI_WMI + depends on INPUT + depends on DELL_LAPTOP + depends on LEDS_TRIGGER_AUDIO + select DELL_WMI + help + This driver provides support for the "Dell Hardware Privacy" feature + of Dell laptops. + Support for a micmute and camera mute privacy will be provided as + hardware button Ctrl+F4 and Ctrl+F9 hotkey End above with a period '.' please. + + To compile this driver as a module, choose M here: the module will + be called dell_privacy. Please follow coding-style for Kconfig files: from Documentation/process/coding-style.rst, section 10): For all of the Kconfig* configuration files throughout the source tree, the indentation is somewhat different. Lines under a ``config`` definition are indented with one tab, while help text is indented an additional two spaces. thanks. Thank you for the review. Format checked again and will be updated in V4.
Re: [PATCH v3 3/3] ASoC: rt715:add micmute led state control supports
Hi Mark: Thanks for your review. On 2021/1/13 1:54, Mark Brown wrote: On Wed, Jan 13, 2021 at 01:18:14AM +0800, Perry Yuan wrote: Some new Dell system is going to support audio internal micphone privacy setting from hardware level with micmute led state changing When micmute hotkey pressed by user, soft mute will need to be enabled firstly in case of pop noise, and codec driver need to react to mic mute event to EC(embedded controller) notifying that SW mute is completed Then EC will do the hardware mute physically within the timeout reached This patch allow codec rt715 driver to ack EC when micmute key pressed through this micphone led control interface like hda_generic provided ACPI method defined in dell-privacy micmute led trigger will be called for notifying the EC that software mute has been completed It feels like there's an abstraction problem here with this being hard coded in a specific CODEC driver. #include @@ -244,6 +245,7 @@ static int rt715_sdca_get_volsw(struct snd_kcontrol *kcontrol, unsigned int max = mc->max; int val; + pr_err("++rt715_sdca_get_volsw++\n"); val = snd_soc_component_read(component, mc->reg); if (val < 0) return -EINVAL; This shouldn't be in the patch. Removed in V4, I forget to clear this debug code @@ -287,6 +291,18 @@ static int rt715_sdca_put_volsw(struct snd_kcontrol *kcontrol, return err; } +#if IS_ENABLED(CONFIG_DELL_PRIVACY) + /* dell privacy LED trigger state changed by muted/unmute switch */ + if (mc->invert) { + if (ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1]) { + rt715->micmute_led = LED_OFF; + } else { + rt715->micmute_led = LED_ON; + } + ledtrig_audio_set(LED_AUDIO_MICMUTE, rt715->micmute_led); + } +#endif + This doesn't look good. There's nothing Dell specific here, and nothing about this is conditional on any sort of runtime detection of Dell systems, it's not obvious why this is conditional on DELL_PRIVACY or why we only report the state if the control is inverted. I will remove the CONFIG_DELL_PRIVACY from V4 patch and allow it to run if CONFIG_DELL_PRIVACY is not set, the result will be a no-op. I'm also not convinced that it's a good idea to set the mute LED if only one channel in a stereo microphone is muted, that seems likely to lead to surprising behaviour for users. https://github.com/thesofproject/linux/pull/2660#discussion_r555480210 There is a discussion for the channel mute changing behavior. If the anyone of value[0] or value[1] is 1, it means mic is NOT muted The muted state will be LED_ON state need to set. TBH I don't understand why this isn't being done in generic code. + bool micmute_led; What is this for, it never seems to be read except for in the function where it's set? I have moved this part code to the local definition of rt715_set_amp_gain_put and removed from rt715_priv. new code will be like this in V4. @@ -88,6 +89,7 @@ static int rt715_set_amp_gain_put(struct snd_kcontrol *kcontrol, RT715_SET_GAIN_MIX_ADC2_L}; unsigned int addr_h, addr_l, val_h, val_ll, val_lr; unsigned int read_ll, read_rl, i, j, loop_cnt; + bool micmute_led;
Re: [PATCH v3 3/3] ASoC: rt715:add micmute led state control supports
Hi Mark: Thanks for your review. On 2021/1/13 1:54, Mark Brown wrote: On Wed, Jan 13, 2021 at 01:18:14AM +0800, Perry Yuan wrote: Some new Dell system is going to support audio internal micphone privacy setting from hardware level with micmute led state changing When micmute hotkey pressed by user, soft mute will need to be enabled firstly in case of pop noise, and codec driver need to react to mic mute event to EC(embedded controller) notifying that SW mute is completed Then EC will do the hardware mute physically within the timeout reached This patch allow codec rt715 driver to ack EC when micmute key pressed through this micphone led control interface like hda_generic provided ACPI method defined in dell-privacy micmute led trigger will be called for notifying the EC that software mute has been completed It feels like there's an abstraction problem here with this being hard coded in a specific CODEC driver. #include @@ -244,6 +245,7 @@ static int rt715_sdca_get_volsw(struct snd_kcontrol *kcontrol, unsigned int max = mc->max; int val; + pr_err("++rt715_sdca_get_volsw++\n"); val = snd_soc_component_read(component, mc->reg); if (val < 0) return -EINVAL; This shouldn't be in the patch. Removed in V4, I forget to clear this debug code @@ -287,6 +291,18 @@ static int rt715_sdca_put_volsw(struct snd_kcontrol *kcontrol, return err; } +#if IS_ENABLED(CONFIG_DELL_PRIVACY) + /* dell privacy LED trigger state changed by muted/unmute switch */ + if (mc->invert) { + if (ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1]) { + rt715->micmute_led = LED_OFF; + } else { + rt715->micmute_led = LED_ON; + } + ledtrig_audio_set(LED_AUDIO_MICMUTE, rt715->micmute_led); + } +#endif + This doesn't look good. There's nothing Dell specific here, and nothing about this is conditional on any sort of runtime detection of Dell systems, it's not obvious why this is conditional on DELL_PRIVACY or why we only report the state if the control is inverted. I will remove the CONFIG_DELL_PRIVACY from V4 patch and allow it to run if CONFIG_DELL_PRIVACY is not set, the result will be a no-op. I'm also not convinced that it's a good idea to set the mute LED if only one channel in a stereo microphone is muted, that seems likely to lead to surprising behaviour for users. https://github.com/thesofproject/linux/pull/2660#discussion_r555480210 There is a discussion for the channel mute changing behavior. If the anyone of value[0] or value[1] is 1, it means mic is NOT muted The muted state will be LED_ON state need to set. TBH I don't understand why this isn't being done in generic code. + bool micmute_led; What is this for, it never seems to be read except for in the function where it's set? I have moved this part code to the local definition of rt715_set_amp_gain_put and removed from rt715_priv. new code will be like this in V4. @@ -88,6 +89,7 @@ static int rt715_set_amp_gain_put(struct snd_kcontrol *kcontrol, RT715_SET_GAIN_MIX_ADC2_L}; unsigned int addr_h, addr_l, val_h, val_ll, val_lr; unsigned int read_ll, read_rl, i, j, loop_cnt; + bool micmute_led;
Re: [PATCH] platform/x86: dell-wmi-sysman: fix a NULL pointer dereference
On 2021/2/1 4:59, Hans de Goede wrote: Hi, On 1/31/21 3:04 PM, Limonciello, Mario wrote: -Original Message- From: Hans de Goede Sent: Saturday, January 30, 2021 15:44 To: Limonciello, Mario; Mark Gross Cc: LKML; platform-driver-...@vger.kernel.org Subject: Re: [PATCH] platform/x86: dell-wmi-sysman: fix a NULL pointer dereference [EXTERNAL EMAIL] Hi, On 1/29/21 6:26 PM, Mario Limonciello wrote: An upcoming Dell platform is causing a NULL pointer dereference in dell-wmi-sysman initialization. Validate that the input from BIOS matches correct ACPI types and abort module initialization if it fails. This leads to a memory leak that needs to be cleaned up properly. Signed-off-by: Mario Limonciello --- drivers/platform/x86/dell-wmi-sysman/sysman.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/dell-wmi-sysman/sysman.c b/drivers/platform/x86/dell-wmi-sysman/sysman.c index dc6dd531c996..38b497991071 100644 --- a/drivers/platform/x86/dell-wmi-sysman/sysman.c +++ b/drivers/platform/x86/dell-wmi-sysman/sysman.c @@ -419,13 +419,19 @@ static int init_bios_attributes(int attr_type, const char *guid) return retval; /* need to use specific instance_id and guid combination to get right data */ obj = get_wmiobj_pointer(instance_id, guid); - if (!obj) + if (!obj || obj->type != ACPI_TYPE_PACKAGE) { + release_attributes_data(); All calls of init_bios_attributes() have the following error handling: ret = init_bios_attributes(INT, DELL_WMI_BIOS_INTEGER_ATTRIBUTE_GUID); if (ret) { pr_debug("failed to populate integer type attributes\n"); goto fail_create_group; } ... fail_create_group: release_attributes_data(); So that added release_attributes_data() call is not necessary. If you can respin this patch Monday with the release_attributes_data(); addition dropped, then I will try to get this to Linus in time for 5.11 . Or I can fix this up locally if you agree with dropping the unnecessary release_attributes_data() call. Yes, please go ahead and drop the unnecessary call locally. Ok, I've merged this into my review-hans branch and I will push this out to for-next as soon as a local build has finished. I'll also include this in my last fixes pull-req for Linus later this week. While working on this I did notice that the function in question still has a bunch of further issues. But since this patch fixes a crash and has been tested I've decided to move forward with it as is (with the duplicate release_attributes_data() call dropped). The further issues can be fixed with follow-up patches. So the other issues which I noticed are: 1. Calling release_attributes_data() in the error-path here: obj = get_wmiobj_pointer(instance_id, guid); if (!obj || obj->type != ACPI_TYPE_PACKAGE) { return -ENODEV; } Is not necessary as discussed, but the added obj->type != ACPI_TYPE_PACKAGE which I assume triggers to fix the reported crash, means that obj is not NULL in which case we should free it. So this should become: obj = get_wmiobj_pointer(instance_id, guid); if (!obj || obj->type != ACPI_TYPE_PACKAGE) { kfree(obj); return -ENODEV; } Note that the kfree() will be a no-op when obj == NULL. This means that with just the current fix merged there is a small memleak on machines where we hit the error-path. I've decided that we can live with that, since the alternative is the crash or me pushing something untested. 2. There is a while below this if, which gets a new obj pointer: obj = get_wmiobj_pointer(instance_id, guid); if (!obj || obj->type != ACPI_TYPE_PACKAGE) { kfree(obj); return -ENODEV; } elements = obj->package.elements; mutex_lock(&wmi_priv.mutex); while (elements) { ... nextobj: kfree(obj); instance_id++; obj = get_wmiobj_pointer(instance_id, guid); elements = obj ? obj->package.elements : NULL; } This is missing a check for the obj->type for the new obj when going into a second (or higher) iteration of the loop. This check can be added by moving the original check to inside the loop like this: obj = get_wmiobj_pointer(instance_id, guid); mutex_lock(&wmi_priv.mutex); while (obj) { if (obj->type != ACPI_TYPE_PACKAGE) { err = ENODEV; goto err_attr_init; } elements = obj->package.elements; ... nextobj: kfree(obj); instance_id++; obj = get_wmiobj_pointer(instance_id, guid); } 3. Functions like populate_enum_data() (and the others) index the el
Re: [PATCH v3 2/3] x86/platform/dell-privacy-wmi: add document for dell privacy driver
Hi Mario, Thanks for your review. On 2021/1/13 1:54, Limonciello, Mario wrote: -Original Message- From: Yuan, Perry Sent: Tuesday, January 12, 2021 11:18 To: oder_ch...@realtek.com; pe...@perex.cz; ti...@suse.com; hdego...@redhat.com; mgr...@linux.intel.com Cc: lgirdw...@gmail.com; broo...@kernel.org; alsa-de...@alsa-project.org; linux-kernel@vger.kernel.org; platform-driver-...@vger.kernel.org; Yuan, Perry; Limonciello, Mario Subject: [PATCH v3 2/3] x86/platform/dell-privacy-wmi: add document for dell privacy driver From: Perry Yuan Describe the Dell Privacy feature capabilities and devices state class exposed by BIOS Signed-off-by: Perry Yuan --- .../testing/sysfs-platform-dell-privacy-wmi | 31 +++ 1 file changed, 31 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi I don't see a reason that the documentation needs to come in it's own commit. In v4, I would think this can collapse as part of: "Add support for Dell hardware privacy" Agreed. will merge this patch content to "Add support for Dell hardware privacy" diff --git a/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi b/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi new file mode 100644 index ..3dbc2d25b60e --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi @@ -0,0 +1,31 @@ +What: /sys/bus/wmi/devices/6932965F-1671-4CEB-B988- D3AB0A901919/devices_supported +Date: Jan 2021 +KernelVersion: 5.11 I think this is 5.12 material now. Need to update this to approximate 5.12 date. +Contact: "perry_y...@dell.com>" I think Dell addresses publicly use a period rather than an underscore, no? So shouldn't this be perry.y...@dell.com? (Although I acknowledge it's an alias, I don't trust that I/T wouldn't remove that some day). changed using period for the mail address. +Description: + Display which dell hardware level privacy devices are supported + “Dell Privacy” is a set of HW, FW, and SW features to enhance + Dell’s commitment to platform privacy for MIC, Camera, and + ePrivacy screens. + The supported privacy haredware privacy devices are: You have a typo here. will fix this in V4. +* 0x0 - None, +* 0x1 - Microphone, +* 0x2 - Camera, +* 0x4 - ePrivacy Screen So this is an bitmap encoded in the integer? I think that needs to be mentioned in the documentation. Indeed it is a bitmap , will change this part as below in V4. What: /sys/bus/wmi/devices/6932965F-1671-4CEB-B988-D3AB0A901919/devices_supported Date: Jan 2021 -KernelVersion: 5.11 -Contact: "perry_y...@dell.com>" +KernelVersion: 5.12 +Contact: "perry.y...@dell.com>" Description: Display which dell hardware level privacy devices are supported “Dell Privacy” is a set of HW, FW, and SW features to enhance Dell’s commitment to platform privacy for MIC, Camera, and ePrivacy screens. - The supported privacy haredware privacy devices are: -* 0x0 - None, -* 0x1 - Microphone, -* 0x2 - Camera, -* 0x4 - ePrivacy Screen + The supported hardware privacy devices are: + - 0 = Not Supported + - 1 = Supported + - Bit0 -> Microphone + - Bit1 -> Camera + - Bit2 -> ePrivacy Screen + +What: /sys/bus/wmi/devices/6932965F-1671-4CEB-B988- D3AB0A901919/current_state +Date: Jan 2021 +KernelVersion: 5.11 +Contact: "perry_y...@dell.com>" +Description: + Allow user space to check current dell privacy device state. + Describes the Device State class exposed by BIOS which can be + consumed by various applications interested in knowing the Privacy + feature capabilities + There are three Bits for available states: + * 0 -> Off + * 1 -> On + * Bit0 -> Microphone + * Bit1 -> Camera + * Bit2 -> ePrivacyScreen + -- 2.25.1
Re: [PATCH v3 3/3] ASoC: rt715:add micmute led state control supports
On 2021/1/13 1:50, Limonciello, Mario wrote: -Original Message- From: Yuan, Perry Sent: Tuesday, January 12, 2021 11:18 To: oder_ch...@realtek.com; pe...@perex.cz; ti...@suse.com; hdego...@redhat.com; mgr...@linux.intel.com Cc: lgirdw...@gmail.com; broo...@kernel.org; alsa-de...@alsa-project.org; linux-kernel@vger.kernel.org; platform-driver-...@vger.kernel.org; Yuan, Perry; Limonciello, Mario Subject: [PATCH v3 3/3] ASoC: rt715:add micmute led state control supports From: Perry Yuan Some new Dell system is going to support audio internal micphone privacy setting from hardware level with micmute led state changing When micmute hotkey pressed by user, soft mute will need to be enabled firstly in case of pop noise, and codec driver need to react to mic mute event to EC(embedded controller) notifying that SW mute is completed Then EC will do the hardware mute physically within the timeout reached This patch allow codec rt715 driver to ack EC when micmute key pressed through this micphone led control interface like hda_generic provided ACPI method defined in dell-privacy micmute led trigger will be called for notifying the EC that software mute has been completed Signed-off-by: Perry Yuan v2 -> v3 * simplify the patch to reuse some val value * add more detail to the commit info v1 -> v2: * fix some format issue --- sound/soc/codecs/rt715-sdca.c | 16 sound/soc/codecs/rt715-sdca.h | 1 + sound/soc/codecs/rt715.c | 14 ++ sound/soc/codecs/rt715.h | 1 + 4 files changed, 32 insertions(+) diff --git a/sound/soc/codecs/rt715-sdca.c b/sound/soc/codecs/rt715-sdca.c index b43ac8559e45..861a0d2a8957 100644 --- a/sound/soc/codecs/rt715-sdca.c +++ b/sound/soc/codecs/rt715-sdca.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -244,6 +245,7 @@ static int rt715_sdca_get_volsw(struct snd_kcontrol *kcontrol, unsigned int max = mc->max; int val; + pr_err("++rt715_sdca_get_volsw++\n"); val = snd_soc_component_read(component, mc->reg); if (val < 0) return -EINVAL; @@ -261,6 +263,7 @@ static int rt715_sdca_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; unsigned int val, val2, loop_cnt = 2, i; @@ -268,6 +271,7 @@ static int rt715_sdca_put_volsw(struct snd_kcontrol *kcontrol, unsigned int reg2 = mc->rreg; unsigned int reg = mc->reg; unsigned int max = mc->max; + unsigned int val0, val1; int err; val = ucontrol->value.integer.value[0]; @@ -287,6 +291,18 @@ static int rt715_sdca_put_volsw(struct snd_kcontrol *kcontrol, return err; } +#if IS_ENABLED(CONFIG_DELL_PRIVACY) + /* dell privacy LED trigger state changed by muted/unmute switch */ + if (mc->invert) { + if (ucontrol->value.integer.value[0] || ucontrol- value.integer.value[1]) { + rt715->micmute_led = LED_OFF; + } else { + rt715->micmute_led = LED_ON; + } + ledtrig_audio_set(LED_AUDIO_MICMUTE, rt715->micmute_led); + } +#endif + return 0; } diff --git a/sound/soc/codecs/rt715-sdca.h b/sound/soc/codecs/rt715-sdca.h index 840c237895dd..f8988ab88f80 100644 --- a/sound/soc/codecs/rt715-sdca.h +++ b/sound/soc/codecs/rt715-sdca.h @@ -31,6 +31,7 @@ struct rt715_sdca_priv { int l_is_unmute; int r_is_unmute; int hw_sdw_ver; + bool micmute_led; }; struct rt715_sdw_stream_data { diff --git a/sound/soc/codecs/rt715.c b/sound/soc/codecs/rt715.c index cdcba70146da..b4e480744c94 100644 --- a/sound/soc/codecs/rt715.c +++ b/sound/soc/codecs/rt715.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -88,6 +89,7 @@ static int rt715_set_amp_gain_put(struct snd_kcontrol *kcontrol, RT715_SET_GAIN_MIX_ADC2_L}; unsigned int addr_h, addr_l, val_h, val_ll, val_lr; unsigned int read_ll, read_rl, i, j, loop_cnt; + unsigned int val0, val1; if (strstr(ucontrol->id.name, "Main Capture Switch") || strstr(ucontrol->id.name, "Main Capture Volume")) @@ -95,6 +97,18 @@ static int rt715_set_amp_gain_put(struct snd_kcontrol *kcontrol, else loop_cnt = 1; +#if IS_ENABLED(CONFIG_DELL_PRIVACY) + /* Micmute LED state changed by muted/unmute switch */ + if (mc->invert) { + if (ucontrol->value.integer.value[0] || uco
Re: [PATCH v3 3/3] ASoC: rt715:add micmute led state control supports
Hi Mark, Thanks for your review feedback. On 2021/1/13 1:54, Mark Brown wrote: On Wed, Jan 13, 2021 at 01:18:14AM +0800, Perry Yuan wrote: Some new Dell system is going to support audio internal micphone privacy setting from hardware level with micmute led state changing When micmute hotkey pressed by user, soft mute will need to be enabled firstly in case of pop noise, and codec driver need to react to mic mute event to EC(embedded controller) notifying that SW mute is completed Then EC will do the hardware mute physically within the timeout reached This patch allow codec rt715 driver to ack EC when micmute key pressed through this micphone led control interface like hda_generic provided ACPI method defined in dell-privacy micmute led trigger will be called for notifying the EC that software mute has been completed It feels like there's an abstraction problem here with this being hard coded in a specific CODEC driver. I will remove the CONFIG_DELL_PRIVACY ,because other vendors and other platforms maybe need to set their Mic mute led state when they enable soundwire and sof driver for audio function. We can avoid hardcode in codec driver, indeed it is need for this new soundwire & sof architecture of alsa. #include @@ -244,6 +245,7 @@ static int rt715_sdca_get_volsw(struct snd_kcontrol *kcontrol, unsigned int max = mc->max; int val; + pr_err("++rt715_sdca_get_volsw++\n"); val = snd_soc_component_read(component, mc->reg); if (val < 0) return -EINVAL; This shouldn't be in the patch. It is my mistake to leave the debug line here. will be removed in next V4 . @@ -287,6 +291,18 @@ static int rt715_sdca_put_volsw(struct snd_kcontrol *kcontrol, return err; } +#if IS_ENABLED(CONFIG_DELL_PRIVACY) + /* dell privacy LED trigger state changed by muted/unmute switch */ + if (mc->invert) { + if (ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1]) { + rt715->micmute_led = LED_OFF; + } else { + rt715->micmute_led = LED_ON; + } + ledtrig_audio_set(LED_AUDIO_MICMUTE, rt715->micmute_led); + } +#endif + This doesn't look good. There's nothing Dell specific here, and nothing about this is conditional on any sort of runtime detection of Dell systems, it's not obvious why this is conditional on DELL_PRIVACY or why we only report the state if the control is inverted. I will remove the CONFIG_DELL_PRIVACY for the mic mute led operation is not only needed for dell platforms but also other Vendors all need to set micmute led necessaryily. I'm also not convinced that it's a good idea to set the mute LED if only one channel in a stereo microphone is muted, that seems likely to lead to surprising behaviour for users. At first, i just want to handle val0 == 1 && val1 == 1 and val0 == 0 && val1 == 0 only. Intel suggested i need to cover all about other cases, the mute led should be off if any channel of mic is on. So i change the led state when any one channel is muted or unmuted. TBH I don't understand why this isn't being done in generic code. + bool micmute_led; What is this for, it never seems to be read except for in the function where it's set? Do you mean i can use a local micmute_led var in the function?
Re: [PATCH v3 1/3] platform/x86: dell-privacy: Add support for Dell hardware privacy
On 2021/1/13 1:39, Randy Dunlap wrote: On 1/12/21 9:17 AM, Perry Yuan wrote: +config DELL_PRIVACY + tristate "Dell Hardware Privacy Support" + depends on ACPI + depends on ACPI_WMI + depends on INPUT + depends on DELL_LAPTOP + depends on LEDS_TRIGGER_AUDIO + select DELL_WMI + help + This driver provides support for the "Dell Hardware Privacy" feature + of Dell laptops. + Support for a micmute and camera mute privacy will be provided as + hardware button Ctrl+F4 and Ctrl+F9 hotkey End above with a period '.' please. + + To compile this driver as a module, choose M here: the module will + be called dell_privacy. Please follow coding-style for Kconfig files: from Documentation/process/coding-style.rst, section 10): For all of the Kconfig* configuration files throughout the source tree, the indentation is somewhat different. Lines under a ``config`` definition are indented with one tab, while help text is indented an additional two spaces. thanks. Thanks for your review feedback. I will fix this in V4 patch.
Re: [PATCH v2 1/2] platform/x86: dell-privacy: Add support for Dell hardware privacy
On 2021/1/13 2:37, Hans de Goede wrote: Hi, I know there already is a v3 out and I will try to get around to reviewing that soon, still 1 remark about the discussion surrounding v2: On 1/11/21 2:42 PM, Perry Yuan wrote: *The flow is like this: 1) User presses key. HW does stuff with this key (timeout is started) 2) Event is emitted from FW 3) Event received by dell-privacy 4) KEY_MICMUTE emitted from dell-privacy 5) Userland picks up key and modifies kcontrol for SW mute 6) Codec kernel driver catches and calls ledtrig_audio_set, like this: ledtrig_audio_set(LED_AUDIO_MICMUTE, rt715->micmute_led ? LED_ON :LED_OFF); 7) If "LED" is set to on dell-privacy notifies ec, and timeout is cancelled,HW mic mute activated. Please proofread the commit message again, and pay attention to capitalization and spacing. I want to reformat it and move the commit info to cover letter. Please also put a copy of this as a comment in either the wmi or the acpi driver (with a comment pointing to the comment in the other) this is important info to have for someone reading the code and trying to understand how this all fits together. Regards, Hans Hi Hans: Agreed. I will add this to the driver comments and explain how the acpi/wmi driver associated.
Re: [PATCH v2 1/2] platform/x86: dell-privacy: Add support for Dell hardware privacy
Hi Barnabás, On 2021/1/12 0:07, Barnabás Pőcze wrote: Hi 2021. január 11., hétfő 14:42 keltezéssel, Perry Yuan írta: [...] +#define PRIVACY_PLATFORM_NAME "dell-privacy-acpi" +#define DELL_PRIVACY_GUID "6932965F-1671-4CEB-B988-D3AB0A901919" + +struct privacy_acpi_priv { + struct device *dev; + struct platform_device *platform_device; + struct led_classdev cdev; +}; +static struct privacy_acpi_priv *privacy_acpi; Any reason it needs to be dynamically allocated? I need to set one static struct to let some function to get the priv pointer. It is more simple if i add some function and get the priv easily. If you have better suggestion, i would be glad to optimize it. for example. static int dell_privacy_micmute_led_set(struct led_classdev *led_cdev, enum led_brightness brightness) { struct privacy_acpi_priv *priv = privacy_acpi; .. } My comment was referring to the fact that you could've used ``` static struct privacy_acpi_priv privacy_acpi; ``` to achieve the same result without the dynamic memory allocation. + +static int dell_privacy_micmute_led_set(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct privacy_acpi_priv *priv = privacy_acpi; + acpi_status status; + acpi_handle handle; + char *acpi_method; + + handle = ec_get_handle(); + if (!handle) + return -EIO; + if (acpi_has_method(handle, "ECAK")) + acpi_method = "ECAK"; + else + return -ENODEV; I find this if-else a bit cumbersome. Any reason why if (!acpi_has_method(handle, "ECAK")) return ...; would not work? I believe you could also easily do away with the `acpi_method` variable. Just want to make sure the BIOS has the correct method to call. normally it will not be failed, just keep it safe to call BIOS, not to cause any panic. I changed it as below . handle = ec_get_handle(); if (!handle) return -EIO; acpi_method = "ECAK"; You could keep the method name in a static variable: ``` static char *acpi_method = (char *)"ECAK"; // this is inside the function handle = ...; if (!handle) return ... if (!acpi_has_method(handle, acpi_method)) return ... ... acpi_evaluate_object(handle, acpi_method, ... ``` Another thing is that I believe you could do these checks only once, before registering the LED device. + + status = acpi_evaluate_object(handle, acpi_method, NULL, NULL); + if (ACPI_FAILURE(status)) { + dev_err(priv->dev, "Error setting privacy EC ack value: %s\n", + acpi_format_exception(status)); + return -EIO; + } + return 0; +} + [...] +static const struct acpi_device_id privacy_acpi_device_ids[] = { + {"PNP0C09", 0}, + { }, +}; +MODULE_DEVICE_TABLE(acpi, privacy_acpi_device_ids); + +static struct platform_driver dell_privacy_platform_drv = { + .driver = { + .name = PRIVACY_PLATFORM_NAME, + .acpi_match_table = ACPI_PTR(privacy_acpi_device_ids), + }, + .remove = dell_privacy_acpi_remove, +}; I think using a platform driver here just complicates things for no reason. Furthermore, I'm not sure if there's actually any need for the ACPI match table. there will be some more privacy devices need to add some acpi interface function here. including elctronic privacy screen and privacy camera. the platform driver can provide more flexible framework to extend. I see. I'm wondering if the ACPI match table is needed at the moment. If I'm not mistaken the platform driver already binds the platform device the module creates. And there is no real need to bind to the ACPI EC devices. [...] diff --git a/drivers/platform/x86/dell-privacy-wmi.c b/drivers/platform/x86/dell-privacy-wmi.c new file mode 100644 index ..80637c7f617c --- /dev/null +++ b/drivers/platform/x86/dell-privacy-wmi.c [...] +int dell_privacy_valid(void) +{ + int ret; + + ret = wmi_has_guid(DELL_PRIVACY_GUID); + if (!ret) + return -ENODEV; + ret = privacy_valid; + return ret; I find this function really confusing, and too verbose for what it does. 1. when the DELL_PRIVACY_GUID not found, it will return ENODEV showing no privacy devices. 2. when DELL_PRIVACY_GUID found,and wmi privacy driver is registered, it will return "0" 3.when DELL_PRIVACY_GUID found,and wmi privacy driver is NOT registered yet, it will return "EPROBE_DEFE" the EPROBE_DEFER is defined in "include/linux/errno.h" #define EPROBE_DEFER517 /* Driver requests probe retry */ when caller get this returned , it will defer the caller 1s ~ 7s to prob
[PATCH v3 3/3] ASoC: rt715:add micmute led state control supports
From: Perry Yuan Some new Dell system is going to support audio internal micphone privacy setting from hardware level with micmute led state changing When micmute hotkey pressed by user, soft mute will need to be enabled firstly in case of pop noise, and codec driver need to react to mic mute event to EC(embedded controller) notifying that SW mute is completed Then EC will do the hardware mute physically within the timeout reached This patch allow codec rt715 driver to ack EC when micmute key pressed through this micphone led control interface like hda_generic provided ACPI method defined in dell-privacy micmute led trigger will be called for notifying the EC that software mute has been completed Signed-off-by: Perry Yuan v2 -> v3 * simplify the patch to reuse some val value * add more detail to the commit info v1 -> v2: * fix some format issue --- sound/soc/codecs/rt715-sdca.c | 16 sound/soc/codecs/rt715-sdca.h | 1 + sound/soc/codecs/rt715.c | 14 ++ sound/soc/codecs/rt715.h | 1 + 4 files changed, 32 insertions(+) diff --git a/sound/soc/codecs/rt715-sdca.c b/sound/soc/codecs/rt715-sdca.c index b43ac8559e45..861a0d2a8957 100644 --- a/sound/soc/codecs/rt715-sdca.c +++ b/sound/soc/codecs/rt715-sdca.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -244,6 +245,7 @@ static int rt715_sdca_get_volsw(struct snd_kcontrol *kcontrol, unsigned int max = mc->max; int val; + pr_err("++rt715_sdca_get_volsw++\n"); val = snd_soc_component_read(component, mc->reg); if (val < 0) return -EINVAL; @@ -261,6 +263,7 @@ static int rt715_sdca_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; unsigned int val, val2, loop_cnt = 2, i; @@ -268,6 +271,7 @@ static int rt715_sdca_put_volsw(struct snd_kcontrol *kcontrol, unsigned int reg2 = mc->rreg; unsigned int reg = mc->reg; unsigned int max = mc->max; + unsigned int val0, val1; int err; val = ucontrol->value.integer.value[0]; @@ -287,6 +291,18 @@ static int rt715_sdca_put_volsw(struct snd_kcontrol *kcontrol, return err; } +#if IS_ENABLED(CONFIG_DELL_PRIVACY) + /* dell privacy LED trigger state changed by muted/unmute switch */ + if (mc->invert) { + if (ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1]) { + rt715->micmute_led = LED_OFF; + } else { + rt715->micmute_led = LED_ON; + } + ledtrig_audio_set(LED_AUDIO_MICMUTE, rt715->micmute_led); + } +#endif + return 0; } diff --git a/sound/soc/codecs/rt715-sdca.h b/sound/soc/codecs/rt715-sdca.h index 840c237895dd..f8988ab88f80 100644 --- a/sound/soc/codecs/rt715-sdca.h +++ b/sound/soc/codecs/rt715-sdca.h @@ -31,6 +31,7 @@ struct rt715_sdca_priv { int l_is_unmute; int r_is_unmute; int hw_sdw_ver; + bool micmute_led; }; struct rt715_sdw_stream_data { diff --git a/sound/soc/codecs/rt715.c b/sound/soc/codecs/rt715.c index cdcba70146da..b4e480744c94 100644 --- a/sound/soc/codecs/rt715.c +++ b/sound/soc/codecs/rt715.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -88,6 +89,7 @@ static int rt715_set_amp_gain_put(struct snd_kcontrol *kcontrol, RT715_SET_GAIN_MIX_ADC2_L}; unsigned int addr_h, addr_l, val_h, val_ll, val_lr; unsigned int read_ll, read_rl, i, j, loop_cnt; + unsigned int val0, val1; if (strstr(ucontrol->id.name, "Main Capture Switch") || strstr(ucontrol->id.name, "Main Capture Volume")) @@ -95,6 +97,18 @@ static int rt715_set_amp_gain_put(struct snd_kcontrol *kcontrol, else loop_cnt = 1; +#if IS_ENABLED(CONFIG_DELL_PRIVACY) + /* Micmute LED state changed by muted/unmute switch */ + if (mc->invert) { + if (ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1]) { + rt715->micmute_led = LED_OFF; + } else { + rt715->micmute_led = LED_ON; + } + ledtrig_audio_set(LED_AUDIO_MICMUTE, rt715->micmute_led); + } +#endif + for (j = 0; j < loop_cnt; j++) { /* Can't use update bit function, so read the original value first */ if (loop_cnt == 1) { diff --git a/sound/soc/codecs/r
[PATCH v3 2/3] x86/platform/dell-privacy-wmi: add document for dell privacy driver
From: Perry Yuan Describe the Dell Privacy feature capabilities and devices state class exposed by BIOS Signed-off-by: Perry Yuan --- .../testing/sysfs-platform-dell-privacy-wmi | 31 +++ 1 file changed, 31 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi diff --git a/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi b/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi new file mode 100644 index ..3dbc2d25b60e --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi @@ -0,0 +1,31 @@ +What: /sys/bus/wmi/devices/6932965F-1671-4CEB-B988-D3AB0A901919/devices_supported +Date: Jan 2021 +KernelVersion: 5.11 +Contact: "perry_y...@dell.com>" +Description: + Display which dell hardware level privacy devices are supported + “Dell Privacy” is a set of HW, FW, and SW features to enhance + Dell’s commitment to platform privacy for MIC, Camera, and + ePrivacy screens. + The supported privacy haredware privacy devices are: +* 0x0 - None, +* 0x1 - Microphone, +* 0x2 - Camera, +* 0x4 - ePrivacy Screen + +What: /sys/bus/wmi/devices/6932965F-1671-4CEB-B988-D3AB0A901919/current_state +Date: Jan 2021 +KernelVersion: 5.11 +Contact: "perry_y...@dell.com>" +Description: + Allow user space to check current dell privacy device state. + Describes the Device State class exposed by BIOS which can be + consumed by various applications interested in knowing the Privacy + feature capabilities + There are three Bits for available states: + * 0 -> Off + * 1 -> On + * Bit0 -> Microphone + * Bit1 -> Camera + * Bit2 -> ePrivacyScreen + -- 2.25.1
[PATCH v3 1/3] platform/x86: dell-privacy: Add support for Dell hardware privacy
From: Perry Yuan add support for dell privacy driver for the dell units equipped hardware privacy design, which protect users privacy of audio and camera from hardware level. once the audio or camera privacy mode enabled, any applications will not get any audio or video stream when user pressed ctrl+F4 hotkey, audio privacy mode will be enabled,Micmute led will be also changed accordingly The micmute led is fully controlled by hardware & EC(embedded controller) and camera mute hotkey is ctrl+f9. currently design only emmit SW_CAMERA_LENS_COVER event while the camera lens shutter will be changed by EC & hw(hadware) control *The flow is like this: 1) User presses key. HW does stuff with this key (timeout is started) 2) WMI event is emitted from BIOS 3) WMI event is received by dell-privacy 4) KEY_MICMUTE emitted from dell-privacy 5) Userland picks up key and modifies kcontrol for SW mute 6) Codec kernel driver catches and calls ledtrig_audio_set, like this: ledtrig_audio_set(LED_AUDIO_MICMUTE, rt715->micmute_led ? LED_ON :LED_OFF); 7) If "LED" is set to on dell-privacy notifies EC, and timeout is cancelled, HW mic mute activated. Signed-off-by: Perry Yuan --- v3 -> v4: * changed as Barnabás`s review comments v2 -> v3: * add sysfs attributes doc v1 -> v2: * query EC handle from EC driver directly * fix some code style * add KEY_END to keymap array * clean platform device when cleanup called * use hexadecimal format for log print in dev_dbg * remove __set_bit for the report keys from probe. * fix keymap leak * add err_free_keymap in dell_privacy_wmi_probe * wmi driver will be unregistered if privacy_acpi_init() fails * add sysfs attribute files for user space query. * add leds micmute driver to privacy acpi * add more design info the commit info --- --- drivers/platform/x86/Kconfig | 17 ++ drivers/platform/x86/Makefile| 4 +- drivers/platform/x86/dell-laptop.c | 25 +- drivers/platform/x86/dell-privacy-acpi.c | 167 drivers/platform/x86/dell-privacy-wmi.c | 320 +++ drivers/platform/x86/dell-privacy-wmi.h | 33 +++ drivers/platform/x86/dell-wmi.c | 37 ++- 7 files changed, 587 insertions(+), 16 deletions(-) create mode 100644 drivers/platform/x86/dell-privacy-acpi.c create mode 100644 drivers/platform/x86/dell-privacy-wmi.c create mode 100644 drivers/platform/x86/dell-privacy-wmi.h diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 91e6176cdfbd..9d5cc2454b3e 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -491,6 +491,23 @@ config DELL_WMI_LED This adds support for the Latitude 2100 and similar notebooks that have an external LED. +config DELL_PRIVACY + tristate "Dell Hardware Privacy Support" + depends on ACPI + depends on ACPI_WMI + depends on INPUT + depends on DELL_LAPTOP + depends on LEDS_TRIGGER_AUDIO + select DELL_WMI + help + This driver provides support for the "Dell Hardware Privacy" feature + of Dell laptops. + Support for a micmute and camera mute privacy will be provided as + hardware button Ctrl+F4 and Ctrl+F9 hotkey + + To compile this driver as a module, choose M here: the module will + be called dell_privacy. + config AMILO_RFKILL tristate "Fujitsu-Siemens Amilo rfkill support" depends on RFKILL diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 581475f59819..18c430456de7 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -51,7 +51,9 @@ obj-$(CONFIG_DELL_WMI_DESCRIPTOR) += dell-wmi-descriptor.o obj-$(CONFIG_DELL_WMI_AIO) += dell-wmi-aio.o obj-$(CONFIG_DELL_WMI_LED) += dell-wmi-led.o obj-$(CONFIG_DELL_WMI_SYSMAN) += dell-wmi-sysman/ - +obj-$(CONFIG_DELL_PRIVACY) += dell-privacy.o +dell-privacy-objs := dell-privacy-wmi.o \ + dell-privacy-acpi.o # Fujitsu obj-$(CONFIG_AMILO_RFKILL) += amilo-rfkill.o obj-$(CONFIG_FUJITSU_LAPTOP) += fujitsu-laptop.o diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index 70edc5bb3a14..2fea1f34fcf9 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -30,6 +30,7 @@ #include #include "dell-rbtn.h" #include "dell-smbios.h" +#include "dell-privacy-wmi.h" struct quirk_entry { bool touchpad_led; @@ -90,6 +91,7 @@ static struct rfkill *wifi_rfkill; static struct rfkill *bluetooth_rfkill; static struct rfkill *wwan_rfkill; static bool force_rfkill; +static bool privacy_valid; module_param(force_rfkill, bool, 0444); MODULE_PARM_DESC(force_rfkill, "enable rfkill on non whitelisted models&quo
[PATCH v3 0/3] Dell hardware privacy implementation for dell laptop
From: Perry Yuan Hi All, This patch set is a new driver for dell mobile platform ,which has the hardware privacy feature. For micmute led control, the hotkey is Fn + F4, it is a hardware based mute state, and new privacy will prevent micphone void input from hardware layer, any application cannot get voice data when micmute activated. Camera mute use a new hardware design to control the camrea shutter. When video is muted, no OS application should be functionally able to capture images of the person/environment in front of the system Older history: [1]https://patchwork.kernel.org/project/platform-driver-x86/patch/20201228132855.17544-1-perry_y...@dell.com/ [2]https://patchwork.kernel.org/project/alsa-devel/patch/20201103125859.8759-1-perry_y...@dell.com/#23733605 [3]https://www.spinics.net/lists/alsa-devel/msg120537.html [4]https://github.com/thesofproject/linux/pull/2660 Perry Yuan (3): platform/x86: dell-privacy: Add support for Dell hardware privacy x86/platform/dell-privacy-wmi: add document for dell privacy driver ASoC: rt715:add micmute led state control supports .../testing/sysfs-platform-dell-privacy-wmi | 31 ++ drivers/platform/x86/Kconfig | 17 + drivers/platform/x86/Makefile | 4 +- drivers/platform/x86/dell-laptop.c| 25 +- drivers/platform/x86/dell-privacy-acpi.c | 167 + drivers/platform/x86/dell-privacy-wmi.c | 320 ++ drivers/platform/x86/dell-privacy-wmi.h | 33 ++ drivers/platform/x86/dell-wmi.c | 37 +- sound/soc/codecs/rt715-sdca.c | 16 + sound/soc/codecs/rt715-sdca.h | 1 + sound/soc/codecs/rt715.c | 14 + sound/soc/codecs/rt715.h | 1 + 12 files changed, 650 insertions(+), 16 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-platform-dell-privacy-wmi create mode 100644 drivers/platform/x86/dell-privacy-acpi.c create mode 100644 drivers/platform/x86/dell-privacy-wmi.c create mode 100644 drivers/platform/x86/dell-privacy-wmi.h -- 2.25.1
[PATCH v2 1/2] platform/x86: dell-privacy: Add support for Dell hardware privacy
From: Perry Yuan add support for dell privacy driver for the dell units equipped hardware privacy design, which protect users privacy of audio and camera from hardware level. once the audio or camera privacy mode enabled, any applications will not get any audio or video stream. when user pressed ctrl+F4 hotkey, audio privacy mode will be enabled,Micmute led will be also changed accordingly. The micmute led is fully controlled by hardware & EC. and camera mute hotkey is ctrl+F9.currently design only emmit SW_CAMERA_LENS_COVER event while the camera LENS shutter will be changed by EC & HW control. *The flow is like this: 1) User presses key. HW does stuff with this key (timeout is started) 2) Event is emitted from FW 3) Event received by dell-privacy 4) KEY_MICMUTE emitted from dell-privacy 5) Userland picks up key and modifies kcontrol for SW mute 6) Codec kernel driver catches and calls ledtrig_audio_set, like this: ledtrig_audio_set(LED_AUDIO_MICMUTE, rt715->micmute_led ? LED_ON :LED_OFF); 7) If "LED" is set to on dell-privacy notifies ec, and timeout is cancelled,HW mic mute activated. Signed-off-by: Perry Yuan Signed-off-by: Limonciello Mario --- v1 -> v2: * query EC handle from EC driver directly. * fix some code style. * add KEY_END to keymap array. * clean platform device when cleanup called * use hexadecimal format for log print in dev_dbg * remove __set_bit for the report keys from probe. * fix keymap leak * add err_free_keymap in dell_privacy_wmi_probe * wmi driver will be unregistered if privacy_acpi_init() fails * add sysfs attribute files for user space query. * add leds micmute driver to privacy acpi * add more design info the commit info --- --- drivers/platform/x86/Kconfig | 17 ++ drivers/platform/x86/Makefile| 4 +- drivers/platform/x86/dell-laptop.c | 29 ++- drivers/platform/x86/dell-privacy-acpi.c | 165 drivers/platform/x86/dell-privacy-wmi.c | 309 +++ drivers/platform/x86/dell-privacy-wmi.h | 33 +++ drivers/platform/x86/dell-wmi.c | 26 +- 7 files changed, 567 insertions(+), 16 deletions(-) create mode 100644 drivers/platform/x86/dell-privacy-acpi.c create mode 100644 drivers/platform/x86/dell-privacy-wmi.c create mode 100644 drivers/platform/x86/dell-privacy-wmi.h diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 91e6176cdfbd..9d5cc2454b3e 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -491,6 +491,23 @@ config DELL_WMI_LED This adds support for the Latitude 2100 and similar notebooks that have an external LED. +config DELL_PRIVACY + tristate "Dell Hardware Privacy Support" + depends on ACPI + depends on ACPI_WMI + depends on INPUT + depends on DELL_LAPTOP + depends on LEDS_TRIGGER_AUDIO + select DELL_WMI + help + This driver provides support for the "Dell Hardware Privacy" feature + of Dell laptops. + Support for a micmute and camera mute privacy will be provided as + hardware button Ctrl+F4 and Ctrl+F9 hotkey + + To compile this driver as a module, choose M here: the module will + be called dell_privacy. + config AMILO_RFKILL tristate "Fujitsu-Siemens Amilo rfkill support" depends on RFKILL diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 581475f59819..18c430456de7 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -51,7 +51,9 @@ obj-$(CONFIG_DELL_WMI_DESCRIPTOR) += dell-wmi-descriptor.o obj-$(CONFIG_DELL_WMI_AIO) += dell-wmi-aio.o obj-$(CONFIG_DELL_WMI_LED) += dell-wmi-led.o obj-$(CONFIG_DELL_WMI_SYSMAN) += dell-wmi-sysman/ - +obj-$(CONFIG_DELL_PRIVACY) += dell-privacy.o +dell-privacy-objs := dell-privacy-wmi.o \ + dell-privacy-acpi.o # Fujitsu obj-$(CONFIG_AMILO_RFKILL) += amilo-rfkill.o obj-$(CONFIG_FUJITSU_LAPTOP) += fujitsu-laptop.o diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index 70edc5bb3a14..ea0c8a8099ff 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -30,6 +30,7 @@ #include #include "dell-rbtn.h" #include "dell-smbios.h" +#include "dell-privacy-wmi.h" struct quirk_entry { bool touchpad_led; @@ -90,6 +91,7 @@ static struct rfkill *wifi_rfkill; static struct rfkill *bluetooth_rfkill; static struct rfkill *wwan_rfkill; static bool force_rfkill; +static bool privacy_valid; module_param(force_rfkill, bool, 0444); MODULE_PARM_DESC(force_rfkill, "enable rfkill on non whitelisted models"); @@ -1587,10 +1589,10 @@ static ssize_t kbd_led_timeout_store(struct device *dev,
[PATCH v2 2/2] ASoC: rt715:add Mic Mute LED control support
From: Perry Yuan Some new Dell system is going to support audio internal micphone privacy setting from hardware level with micmute led state changing When micmute hotkey pressed by user, soft mute will need to be enabled firstly in case of pop noise, and codec driver need to react to mic mute event to EC notifying that SW mute is completed. Then EC will do the HW mute physically. This patch allow codec rt715 driver to ack EC when micmute key pressed through this micphone led control interface like hda_generic provided. Signed-off-by: Perry Yuan Signed-off-by: Limonciello Mario --- sound/soc/codecs/rt715-sdca.c | 19 ++- sound/soc/codecs/rt715-sdca.h | 1 + sound/soc/codecs/rt715.c | 19 ++- sound/soc/codecs/rt715.h | 1 + 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt715-sdca.c b/sound/soc/codecs/rt715-sdca.c index b43ac8559e45..e168ef6efcf5 100644 --- a/sound/soc/codecs/rt715-sdca.c +++ b/sound/soc/codecs/rt715-sdca.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -268,6 +269,7 @@ static int rt715_sdca_put_volsw(struct snd_kcontrol *kcontrol, unsigned int reg2 = mc->rreg; unsigned int reg = mc->reg; unsigned int max = mc->max; + unsigned int val0, val1; int err; val = ucontrol->value.integer.value[0]; @@ -286,7 +288,22 @@ static int rt715_sdca_put_volsw(struct snd_kcontrol *kcontrol, if (err < 0) return err; } - +#if IS_ENABLED(CONFIG_DELL_PRIVACY) + /* Privacy LED Trigger State Changed by muted/unmute switch */ + if (mc->invert) { + val0 = ucontrol->value.integer.value[0]; + val1 = ucontrol->value.integer.value[1]; + if (val0 == 1 && val1 == 1) { + rt715->micmute_led = LED_OFF; + ledtrig_audio_set(LED_AUDIO_MICMUTE, + rt715->micmute_led ? LED_ON : LED_OFF); + } else if (val0 == 0 && val1 == 0) { + rt715->micmute_led = LED_ON; + ledtrig_audio_set(LED_AUDIO_MICMUTE, + rt715->micmute_led ? LED_ON : LED_OFF); + } + } +#endif return 0; } diff --git a/sound/soc/codecs/rt715-sdca.h b/sound/soc/codecs/rt715-sdca.h index 840c237895dd..2ab8724ae50b 100644 --- a/sound/soc/codecs/rt715-sdca.h +++ b/sound/soc/codecs/rt715-sdca.h @@ -31,6 +31,7 @@ struct rt715_sdca_priv { int l_is_unmute; int r_is_unmute; int hw_sdw_ver; + int micmute_led; }; struct rt715_sdw_stream_data { diff --git a/sound/soc/codecs/rt715.c b/sound/soc/codecs/rt715.c index cdcba70146da..faa4dee6b39a 100644 --- a/sound/soc/codecs/rt715.c +++ b/sound/soc/codecs/rt715.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -88,13 +89,29 @@ static int rt715_set_amp_gain_put(struct snd_kcontrol *kcontrol, RT715_SET_GAIN_MIX_ADC2_L}; unsigned int addr_h, addr_l, val_h, val_ll, val_lr; unsigned int read_ll, read_rl, i, j, loop_cnt; + unsigned int val0, val1; if (strstr(ucontrol->id.name, "Main Capture Switch") || strstr(ucontrol->id.name, "Main Capture Volume")) loop_cnt = 4; else loop_cnt = 1; - +#if IS_ENABLED(CONFIG_DELL_PRIVACY) + /* Privacy micmute led trigger for muted/unmute switch */ + if (mc->invert) { + val0 = ucontrol->value.integer.value[0]; + val1 = ucontrol->value.integer.value[1]; + if (val0 == 1 && val1 == 1) { + rt715->micmute_led = LED_OFF; + ledtrig_audio_set(LED_AUDIO_MICMUTE, + rt715->micmute_led ? LED_ON : LED_OFF); + } else if (val0 == 0 && val1 == 0) { + rt715->micmute_led = LED_ON; + ledtrig_audio_set(LED_AUDIO_MICMUTE, + rt715->micmute_led ? LED_ON : LED_OFF); + } + } +#endif for (j = 0; j < loop_cnt; j++) { /* Can't use update bit function, so read the original value first */ if (loop_cnt == 1) { diff --git a/sound/soc/codecs/rt715.h b/sound/soc/codecs/rt715.h index 009a8266f606..2d3b5b299514 100644 --- a/sound/soc/codecs/rt715.h +++ b/sound/soc/codecs/rt715.h @@ -22,6 +22,7 @@ struct rt715_priv { struct sdw_bus_params params; bool hw_init; bool first_hw_init; + int micmute_led; }; struct sdw_stream_data { -- 2.25.1
[PATCH v2 1/2] platform/x86: dell-privacy: Add support for Dell hardware privacy
From: Perry Yuan add support for dell privacy driver for the dell units equipped hardware privacy design, which protect users privacy of audio and camera from hardware level. once the audio or camera privacy mode enabled, any applications will not get any audio or video stream. when user pressed ctrl+F4 hotkey, audio privacy mode will be enabled,Micmute led will be also changed accordingly. The micmute led is fully controlled by hardware & EC. and camera mute hotkey is ctrl+F9.currently design only emmit SW_CAMERA_LENS_COVER event while the camera LENS shutter will be changed by EC & HW control. *The flow is like this: 1) User presses key. HW does stuff with this key (timeout is started) 2) Event is emitted from FW 3) Event received by dell-privacy 4) KEY_MICMUTE emitted from dell-privacy 5) Userland picks up key and modifies kcontrol for SW mute 6) Codec kernel driver catches and calls ledtrig_audio_set, like this: ledtrig_audio_set(LED_AUDIO_MICMUTE, rt715->micmute_led ? LED_ON :LED_OFF); 7) If "LED" is set to on dell-privacy notifies ec, and timeout is cancelled,HW mic mute activated. Signed-off-by: Perry Yuan Signed-off-by: Limonciello Mario --- v1 -> v2: * query EC handle from EC driver directly. * fix some code style. * add KEY_END to keymap array. * clean platform device when cleanup called * use hexadecimal format for log print in dev_dbg * remove __set_bit for the report keys from probe. * fix keymap leak * add err_free_keymap in dell_privacy_wmi_probe * wmi driver will be unregistered if privacy_acpi_init() fails * add sysfs attribute files for user space query. * add leds micmute driver to privacy acpi * add more design info the commit info --- --- drivers/platform/x86/Kconfig | 17 ++ drivers/platform/x86/Makefile| 4 +- drivers/platform/x86/dell-laptop.c | 29 ++- drivers/platform/x86/dell-privacy-acpi.c | 165 drivers/platform/x86/dell-privacy-wmi.c | 309 +++ drivers/platform/x86/dell-privacy-wmi.h | 33 +++ drivers/platform/x86/dell-wmi.c | 26 +- 7 files changed, 567 insertions(+), 16 deletions(-) create mode 100644 drivers/platform/x86/dell-privacy-acpi.c create mode 100644 drivers/platform/x86/dell-privacy-wmi.c create mode 100644 drivers/platform/x86/dell-privacy-wmi.h diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 91e6176cdfbd..9d5cc2454b3e 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -491,6 +491,23 @@ config DELL_WMI_LED This adds support for the Latitude 2100 and similar notebooks that have an external LED. +config DELL_PRIVACY + tristate "Dell Hardware Privacy Support" + depends on ACPI + depends on ACPI_WMI + depends on INPUT + depends on DELL_LAPTOP + depends on LEDS_TRIGGER_AUDIO + select DELL_WMI + help + This driver provides support for the "Dell Hardware Privacy" feature + of Dell laptops. + Support for a micmute and camera mute privacy will be provided as + hardware button Ctrl+F4 and Ctrl+F9 hotkey + + To compile this driver as a module, choose M here: the module will + be called dell_privacy. + config AMILO_RFKILL tristate "Fujitsu-Siemens Amilo rfkill support" depends on RFKILL diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 581475f59819..18c430456de7 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -51,7 +51,9 @@ obj-$(CONFIG_DELL_WMI_DESCRIPTOR) += dell-wmi-descriptor.o obj-$(CONFIG_DELL_WMI_AIO) += dell-wmi-aio.o obj-$(CONFIG_DELL_WMI_LED) += dell-wmi-led.o obj-$(CONFIG_DELL_WMI_SYSMAN) += dell-wmi-sysman/ - +obj-$(CONFIG_DELL_PRIVACY) += dell-privacy.o +dell-privacy-objs := dell-privacy-wmi.o \ + dell-privacy-acpi.o # Fujitsu obj-$(CONFIG_AMILO_RFKILL) += amilo-rfkill.o obj-$(CONFIG_FUJITSU_LAPTOP) += fujitsu-laptop.o diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index 70edc5bb3a14..ea0c8a8099ff 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -30,6 +30,7 @@ #include #include "dell-rbtn.h" #include "dell-smbios.h" +#include "dell-privacy-wmi.h" struct quirk_entry { bool touchpad_led; @@ -90,6 +91,7 @@ static struct rfkill *wifi_rfkill; static struct rfkill *bluetooth_rfkill; static struct rfkill *wwan_rfkill; static bool force_rfkill; +static bool privacy_valid; module_param(force_rfkill, bool, 0444); MODULE_PARM_DESC(force_rfkill, "enable rfkill on non whitelisted models"); @@ -1587,10 +1589,10 @@ static ssize_t kbd_led_timeout_store(struct device *dev,
[PATCH] ASoC: rt715:add Mic Mute LED control support
From: perry_yuan Some new Dell system is going to support audio internal micphone privacy setting from hardware level with micmute led state changing This patch allow to change micmute led state through this micphone led control interface like hda_generic provided. Signed-off-by: Perry Yuan Signed-off-by: Limonciello Mario --- sound/soc/codecs/rt715.c | 43 sound/soc/codecs/rt715.h | 1 + 2 files changed, 44 insertions(+) diff --git a/sound/soc/codecs/rt715.c b/sound/soc/codecs/rt715.c index 099c8bd20006..2df2895d0092 100644 --- a/sound/soc/codecs/rt715.c +++ b/sound/soc/codecs/rt715.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -213,6 +214,45 @@ static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0); .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \ xmax, xinvert) } +static const char *rt715_micmute_led_mode[] = { + "Off", "On" +}; + +static const struct soc_enum rt715_micmute_led_mode_enum = + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rt715_micmute_led_mode), + rt715_micmute_led_mode); + +static int rt715_mic_mute_led_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ +struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); +struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component); +int led_mode = rt715->micmute_led; + +ucontrol->value.integer.value[0] = led_mode; +#if IS_ENABLED(CONFIG_LEDS_TRIGGER_AUDIO) +ledtrig_audio_set(LED_AUDIO_MICMUTE, +rt715->micmute_led ? LED_ON : LED_OFF); +#endif +return 0; +} + +static int rt715_micmute_led_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ +struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); +struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component); +int led_mode = ucontrol->value.integer.value[0]; + +rt715->micmute_led = led_mode; +#if IS_ENABLED(CONFIG_LEDS_TRIGGER_AUDIO) +ledtrig_audio_set(LED_AUDIO_MICMUTE, + rt715->micmute_led ? LED_ON : LED_OFF); +#endif + return 0; +} + + static const struct snd_kcontrol_new rt715_snd_controls[] = { /* Capture switch */ SOC_DOUBLE_R_EXT("ADC 07 Capture Switch", RT715_SET_GAIN_MIC_ADC_H, @@ -277,6 +317,9 @@ static const struct snd_kcontrol_new rt715_snd_controls[] = { RT715_SET_GAIN_LINE2_L, RT715_DIR_IN_SFT, 3, 0, rt715_set_amp_gain_get, rt715_set_amp_gain_put, mic_vol_tlv), +/*Micmute Led Control*/ +SOC_ENUM_EXT("Micmute Led Mode", rt715_micmute_led_mode_enum, +rt715_mic_mute_led_mode_get, rt715_micmute_led_mode_put), }; static int rt715_mux_get(struct snd_kcontrol *kcontrol, diff --git a/sound/soc/codecs/rt715.h b/sound/soc/codecs/rt715.h index df0f24f9bc0c..32917b7846b4 100644 --- a/sound/soc/codecs/rt715.h +++ b/sound/soc/codecs/rt715.h @@ -22,6 +22,7 @@ struct rt715_priv { struct sdw_bus_params params; bool hw_init; bool first_hw_init; +int micmute_led; }; struct sdw_stream_data { -- 2.25.1
[PATCH] platform/x86: dell-privacy: Add support for new privacy driver
From: perry_yuan add support for dell privacy driver for the dell units equipped hardware privacy design, which protect users privacy of audio and camera from hardware level. once the audio or camera privacy mode enabled, any applications will not get any audio or video stream. when user pressed ctrl+F4 hotkey, audio privacy mode will be enabled and camera mute hotkey is ctrl+F9. Signed-off-by: Perry Yuan Signed-off-by: Limonciello Mario --- drivers/platform/x86/Kconfig | 12 ++ drivers/platform/x86/Makefile| 4 +- drivers/platform/x86/dell-laptop.c | 41 ++-- drivers/platform/x86/dell-privacy-acpi.c | 139 drivers/platform/x86/dell-privacy-wmi.c | 259 +++ drivers/platform/x86/dell-privacy-wmi.h | 23 ++ drivers/platform/x86/dell-wmi.c | 90 7 files changed, 513 insertions(+), 55 deletions(-) create mode 100644 drivers/platform/x86/dell-privacy-acpi.c create mode 100644 drivers/platform/x86/dell-privacy-wmi.c create mode 100644 drivers/platform/x86/dell-privacy-wmi.h diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 40219bba6801..0cb6bf5a9565 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -454,6 +454,18 @@ config DELL_WMI_LED This adds support for the Latitude 2100 and similar notebooks that have an external LED. +config DELL_PRIVACY +tristate "Dell Hardware Privacy Support" +depends on ACPI +depends on ACPI_WMI +depends on INPUT +depends on DELL_LAPTOP +select DELL_WMI +help + This driver provides a driver to support messaging related to the + privacy button presses on applicable Dell laptops from 2021 and + newer. + config AMILO_RFKILL tristate "Fujitsu-Siemens Amilo rfkill support" depends on RFKILL diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 5f823f7eff45..111f7215db2f 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -47,7 +47,9 @@ obj-$(CONFIG_DELL_WMI)+= dell-wmi.o obj-$(CONFIG_DELL_WMI_DESCRIPTOR) += dell-wmi-descriptor.o obj-$(CONFIG_DELL_WMI_AIO) += dell-wmi-aio.o obj-$(CONFIG_DELL_WMI_LED) += dell-wmi-led.o - +obj-$(CONFIG_DELL_PRIVACY) += dell-privacy.o +dell-privacy-objs := dell-privacy-wmi.o \ + dell-privacy-acpi.o # Fujitsu obj-$(CONFIG_AMILO_RFKILL) += amilo-rfkill.o obj-$(CONFIG_FUJITSU_LAPTOP) += fujitsu-laptop.o diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index 5e9c2296931c..12b91de09356 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -30,6 +30,7 @@ #include #include "dell-rbtn.h" #include "dell-smbios.h" +#include "dell-privacy-wmi.h" struct quirk_entry { bool touchpad_led; @@ -90,6 +91,7 @@ static struct rfkill *wifi_rfkill; static struct rfkill *bluetooth_rfkill; static struct rfkill *wwan_rfkill; static bool force_rfkill; +static bool privacy_valid; module_param(force_rfkill, bool, 0444); MODULE_PARM_DESC(force_rfkill, "enable rfkill on non whitelisted models"); @@ -2202,20 +2204,25 @@ static int __init dell_init(void) debugfs_create_file("rfkill", 0444, dell_laptop_dir, NULL, &dell_debugfs_fops); - dell_laptop_register_notifier(&dell_laptop_notifier); - - if (dell_smbios_find_token(GLOBAL_MIC_MUTE_DISABLE) && - dell_smbios_find_token(GLOBAL_MIC_MUTE_ENABLE)) { - micmute_led_cdev.brightness = ledtrig_audio_get(LED_AUDIO_MICMUTE); - ret = led_classdev_register(&platform_device->dev, &micmute_led_cdev); - if (ret < 0) - goto fail_led; - } - - if (acpi_video_get_backlight_type() != acpi_backlight_vendor) - return 0; - - token = dell_smbios_find_token(BRIGHTNESS_TOKEN); +dell_laptop_register_notifier(&dell_laptop_notifier); + +if (dell_smbios_find_token(GLOBAL_MIC_MUTE_DISABLE) && +dell_smbios_find_token(GLOBAL_MIC_MUTE_ENABLE)) { +#if IS_ENABLED(CONFIG_DELL_PRIVACY) +privacy_valid = dell_privacy_valid() == -ENODEV; +#endif +if (!privacy_valid) { +micmute_led_cdev.brightness = ledtrig_audio_get(LED_AUDIO_MICMUTE); +ret = led_classdev_register(&platform_device->dev, &micmute_led_cdev); +if (ret < 0) +goto fail_led; +} +} + +if (acpi_video_get_backlight_type() != acpi_backlight_vendor) +return 0; + +token = dell_smbios_find_token(BRIGHTNESS_TOKEN); if (token) {
[PATCH] platform/x86:dell-laptop:Add battery charging thresholds and charging mode switch.
From: perry_yuan The patch control battery charging thresholds when system is under custom charging mode through smbios API and driver`s sys attributes.It also set the percentage bounds for custom charge. Start value must lie in the range [50, 95],End value must lie in the range [55, 100],END must be at least (START + 5). The patch also add the battery charging modes switch support.User can switch the battery charging mode through the new sysfs entry. Primary battery charging modes valid choices are: ['primarily_ac', 'adaptive', 'custom', 'standard', 'express'] Signed-off-by: Perry Yuan Signed-off-by: Limonciello Mario --- Documentation/ABI/testing/sysfs-class-power | 23 ++ drivers/platform/x86/dell-laptop.c | 344 drivers/platform/x86/dell-smbios.h | 26 ++ 3 files changed, 393 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-class-power b/Documentation/ABI/testing/sysfs-class-power index bf3b48f022dc..a8adc3b0ca4b 100644 --- a/Documentation/ABI/testing/sysfs-class-power +++ b/Documentation/ABI/testing/sysfs-class-power @@ -334,6 +334,29 @@ Description: Access: Read Valid values: Represented in microvolts +What: /sys/class/power_supply//charge_control_charging_mode +Date: March 2020 +Contact: linux...@vger.kernel.org +Description: + Represents the type of charging modes currently being applied to the + battery."Express", "Primarily_ac", "Adaptive", "Custom" and + "Standard" all mean different charging speeds. + + 1: "Adaptive" means that the charger uses some + algorithm to adjust the charge rate dynamically, without + any user configuration required. + 2: "Custom" means that the charger uses the charge_control_* + properties to start and stop charging + based on user input. + 3: "Express" means the charger use fast charging technology + 4: "Primarily_ac" means that users who primarily operate the system + while plugged into an external power source. + 5: "Standard" fully charges the battery at a moderate rate. + + Access: Read, Write + Valid values: "Express", "Primarily_ac", "Standard", + "Adaptive", "Custom" + = USB Properties = What: /sys/class/power_supply//current_avg diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index 74e988f839e8..8e45ce92a2d9 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include "dell-rbtn.h" #include "dell-smbios.h" @@ -90,6 +92,14 @@ static struct rfkill *wifi_rfkill; static struct rfkill *bluetooth_rfkill; static struct rfkill *wwan_rfkill; static bool force_rfkill; +static enum battery_charging_mode bat_chg_current = BAT_NONE_MODE; +static const char * const battery_state[BAT_MAX_MODE] = { + [BAT_PRIMARILY_AC_MODE] = "primarily_ac", + [BAT_ADAPTIVE_MODE] = "adaptive", + [BAT_CUSTOM_MODE] = "custom", + [BAT_STANDARD_MODE] = "standard", + [BAT_EXPRESS_MODE] = "express", +}; module_param(force_rfkill, bool, 0444); MODULE_PARM_DESC(force_rfkill, "enable rfkill on non whitelisted models"); @@ -2161,6 +2171,338 @@ static struct led_classdev micmute_led_cdev = { .default_trigger = "audio-micmute", }; +static int dell_battery_get(int *start, int *end) +{ + struct calling_interface_buffer buffer; + struct calling_interface_token *token; + int ret; + + if (start) { + token = dell_smbios_find_token(BATTERY_CUSTOM_CHARGE_START); + if (!token) + return -ENODEV; + dell_fill_request(&buffer, token->location, 0, 0, 0); + ret = dell_send_request(&buffer, + CLASS_TOKEN_READ, SELECT_TOKEN_STD); + *start = buffer.output[1]; + } + + if (end) { + token = dell_smbios_find_token(BATTERY_CUSTOM_CHARGE_END); + if (!token) + return -ENODEV; + dell_fill_request(&buffer, token->location, 0, 0, 0); + ret = dell_send_request(&buffer, + CLASS_TOKEN_READ, SELECT_TOKEN_STD); + if (ret) + return -EIO; + *end = buffer.output[1]; + } + + return 0; +} + +static int dell_battery_set(in
Re: r8152: Add support for MAC address pass through on RTL8153-BND
On 12/11/18 10:16 PM, Mario Limonciello wrote: All previous docks and dongles that have supported this feature use the RTL8153-AD chip. RTL8153-BND is a new chip that will be used in upcoming Dell type-C docks. It should be added to the whitelist of devices to activate MAC address pass through. Per confirming with Realtek all devices containing RTL8153-BND should activate MAC pass through and there won't use pass through bit on efuse like in RTL8153-AD. Signed-off-by: Mario Limonciello --- drivers/net/usb/r8152.c | 33 ++--- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index f1b5201..60dd1ec 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -129,6 +129,7 @@ #define USB_UPS_CTRL 0xd800 #define USB_POWER_CUT 0xd80a #define USB_MISC_00xd81a +#define USB_MISC_1 0xd81f #define USB_AFE_CTRL2 0xd824 #define USB_UPS_CFG 0xd842 #define USB_UPS_FLAGS 0xd848 @@ -555,6 +556,7 @@ enum spd_duplex { /* MAC PASSTHRU */ #define AD_MASK 0xfee0 +#define BND_MASK 0x0004 #define EFUSE 0xcfdb #define PASS_THRU_MASK0x1 @@ -1150,7 +1152,7 @@ static int rtl8152_set_mac_address(struct net_device *netdev, void *p) return ret; } -/* Devices containing RTL8153-AD can support a persistent +/* Devices containing proper chips can support a persistent * host system provided MAC address. * Examples of this are Dell TB15 and Dell WD15 docks */ @@ -1165,13 +1167,23 @@ static int vendor_mac_passthru_addr_read(struct r8152 *tp, struct sockaddr *sa) /* test for -AD variant of RTL8153 */ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); - if ((ocp_data & AD_MASK) != 0x1000) - return -ENODEV; - - /* test for MAC address pass-through bit */ - ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, EFUSE); - if ((ocp_data & PASS_THRU_MASK) != 1) - return -ENODEV; + if ((ocp_data & AD_MASK) == 0x1000) { + /* test for MAC address pass-through bit */ + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, EFUSE); + if ((ocp_data & PASS_THRU_MASK) != 1) { + netif_dbg(tp, probe, tp->netdev, + "No efuse for RTL8153-AD MAC pass through\n"); + return -ENODEV; + } + } else { + /* test for RTL8153-BND */ + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_1); + if ((ocp_data & BND_MASK) == 0) { + netif_dbg(tp, probe, tp->netdev, + "Invalid variant for MAC pass through\n"); + return -ENODEV; + } + } /* returns _AUXMAC_#AABBCCDDEEFF# */ status = acpi_evaluate_object(NULL, "\\_SB.AMAC", NULL, &buffer); @@ -1217,9 +1229,8 @@ static int set_ethernet_addr(struct r8152 *tp) if (tp->version == RTL_VER_01) { ret = pla_ocp_read(tp, PLA_IDR, 8, sa.sa_data); } else { - /* if this is not an RTL8153-AD, no eFuse mac pass thru set, -* or system doesn't provide valid _SB.AMAC this will be -* be expected to non-zero + /* if device doesn't support MAC pass through this will +* be expected to be non-zero */ ret = vendor_mac_passthru_addr_read(tp, &sa); if (ret < 0) Tested-by : Perry Yuan