diff options
author | Fabio Baltieri <fabiobaltieri@google.com> | 2022-03-04 12:35:06 +0000 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2022-03-08 18:11:50 +0000 |
commit | b588702cb78170e1beeac6bb2d7dea3457b5684f (patch) | |
tree | c79d6b7156f93c7f5ee240bc05118344415f6c4a | |
parent | 893d78155f3006694eb237be8c8ad27f795a044f (diff) | |
download | chrome-ec-b588702cb78170e1beeac6bb2d7dea3457b5684f.tar.gz |
zephyr: pwm: add generic-pwm-channel support to kblight and displight
On ARM platforms, the host uses the PWM host command to control the
display and keyboard backlight level. Unfortunately the current driver
does not use the stable PWM types (EC_PWM_TYPE_KB_LIGHT...), but instead
relies on using a known generic PWM channel number (0 or 1), which is
mapped differently on different boards.
To restore compatibility with the current driver, add a PWM channel
number property to the kblight and displight driver, and use it to
control the correct PWM from the PWM host command.
BRANCH=none
BUG=b:217741090, b:222516095
TEST=zmake testall
TEST=ectool pwmsetduty on volteer
TEST=run on lazor
Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
Reported-by: Michał Barnaś <mb@semihalf.com>
Tested-by: Michał Barnaś <mb@semihalf.com>
Change-Id: I68615eb178c7b8ea8bbbc392e4485d36b2f90ae8
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3500630
Reviewed-by: Michał Barnaś <mb@semihalf.com>
Reviewed-by: Wai-Hong Tam <waihong@google.com>
-rw-r--r-- | zephyr/dts/bindings/cros_displight/cros-ec,displight.yaml | 5 | ||||
-rw-r--r-- | zephyr/dts/bindings/keyboard/cros-ec,kblight-pwm.yaml | 5 | ||||
-rw-r--r-- | zephyr/shim/src/pwm.c | 50 |
3 files changed, 56 insertions, 4 deletions
diff --git a/zephyr/dts/bindings/cros_displight/cros-ec,displight.yaml b/zephyr/dts/bindings/cros_displight/cros-ec,displight.yaml index 6b3ab11e74..df51bf19dc 100644 --- a/zephyr/dts/bindings/cros_displight/cros-ec,displight.yaml +++ b/zephyr/dts/bindings/cros_displight/cros-ec,displight.yaml @@ -18,3 +18,8 @@ properties: type: int required: true description: PWM frequency in Hz. + + generic-pwm-channel: + type: int + required: false + description: Generic PWM channel number for legacy compatibility. diff --git a/zephyr/dts/bindings/keyboard/cros-ec,kblight-pwm.yaml b/zephyr/dts/bindings/keyboard/cros-ec,kblight-pwm.yaml index e30e9c8bd2..33607729cd 100644 --- a/zephyr/dts/bindings/keyboard/cros-ec,kblight-pwm.yaml +++ b/zephyr/dts/bindings/keyboard/cros-ec,kblight-pwm.yaml @@ -18,3 +18,8 @@ properties: type: int required: true description: PWM frequency in Hz. + + generic-pwm-channel: + type: int + required: false + description: Generic PWM channel number for legacy compatibility. diff --git a/zephyr/shim/src/pwm.c b/zephyr/shim/src/pwm.c index 53b8dfabd6..5cb4507851 100644 --- a/zephyr/shim/src/pwm.c +++ b/zephyr/shim/src/pwm.c @@ -194,20 +194,62 @@ int pwm_get_duty(enum pwm_channel ch) return DIV_ROUND_NEAREST(pwm->pulse_us * 100, pwm->period_us); } + +#define HAS_PWM_GENERIC_CHANNEL(compat) \ + DT_NODE_HAS_PROP(DT_COMPAT_GET_ANY_STATUS_OKAY(compat), \ + generic_pwm_channel) + +#define PWM_GENERIC_CHANNEL_ID(compat) \ + DT_PROP(DT_COMPAT_GET_ANY_STATUS_OKAY(compat), \ + generic_pwm_channel) + +#ifdef CONFIG_PWM_KBLIGHT +static bool pwm_is_kblight(int type, int index) +{ + if (type == EC_PWM_TYPE_KB_LIGHT) + return true; + +#if HAS_PWM_GENERIC_CHANNEL(cros_ec_kblight_pwm) + if (type == EC_PWM_TYPE_GENERIC && + index == PWM_GENERIC_CHANNEL_ID(cros_ec_kblight_pwm)) + return true; +#endif /* HAS_PWM_GENERIC_CHANNEL(cros_ec_kblight_pwm) */ + + return false; +} +#endif /* CONFIG_PWM_KBLIGHT */ + +#ifdef CONFIG_PLATFORM_EC_PWM_DISPLIGHT +static bool pwm_is_displight(int type, int index) +{ + if (type == EC_PWM_TYPE_DISPLAY_LIGHT) + return true; + +#if HAS_PWM_GENERIC_CHANNEL(cros_ec_displight) + if (type == EC_PWM_TYPE_GENERIC && + index == PWM_GENERIC_CHANNEL_ID(cros_ec_displight)) + return true; +#endif /* HAS_PWM_GENERIC_CHANNEL(cros_ec_displight) */ + + return false; +} +#endif /* CONFIG_PLATFORM_EC_PWM_DISPLIGHT */ + + static enum ec_status host_command_pwm_set_duty( struct host_cmd_handler_args *args) { __maybe_unused const struct ec_params_pwm_set_duty *p = args->params; #ifdef CONFIG_PLATFORM_EC_PWM_KBLIGHT - if (p->pwm_type == EC_PWM_TYPE_KB_LIGHT) { + if (pwm_is_kblight(p->pwm_type, p->index)) { kblight_set(PWM_RAW_TO_PERCENT(p->duty)); kblight_enable(p->duty > 0); return EC_RES_SUCCESS; } #endif #ifdef CONFIG_PLATFORM_EC_PWM_DISPLIGHT - if (p->pwm_type == EC_PWM_TYPE_DISPLAY_LIGHT) { + if (pwm_is_displight(p->pwm_type, p->index)) { displight_set(PWM_RAW_TO_PERCENT(p->duty)); return EC_RES_SUCCESS; } @@ -226,14 +268,14 @@ static enum ec_status host_command_pwm_get_duty( __maybe_unused struct ec_response_pwm_get_duty *r = args->response; #ifdef CONFIG_PLATFORM_EC_PWM_KBLIGHT - if (p->pwm_type == EC_PWM_TYPE_KB_LIGHT) { + if (pwm_is_kblight(p->pwm_type, p->index)) { r->duty = PWM_PERCENT_TO_RAW(kblight_get()); args->response_size = sizeof(*r); return EC_RES_SUCCESS; } #endif #ifdef CONFIG_PLATFORM_EC_PWM_DISPLIGHT - if (p->pwm_type == EC_PWM_TYPE_DISPLAY_LIGHT) { + if (pwm_is_displight(p->pwm_type, p->index)) { r->duty = PWM_PERCENT_TO_RAW(displight_get()); args->response_size = sizeof(*r); return EC_RES_SUCCESS; |