diff options
-rw-r--r-- | board/fennel/board.c | 33 | ||||
-rw-r--r-- | board/fennel/board.h | 7 | ||||
-rw-r--r-- | board/fennel/gpio.inc | 1 | ||||
-rw-r--r-- | driver/ioexpander/it8801.c | 62 | ||||
-rw-r--r-- | driver/ioexpander/it8801.h | 4 |
5 files changed, 98 insertions, 9 deletions
diff --git a/board/fennel/board.c b/board/fennel/board.c index 335a1bb486..0499be2585 100644 --- a/board/fennel/board.c +++ b/board/fennel/board.c @@ -30,6 +30,7 @@ #include "i2c_bitbang.h" #include "it8801.h" #include "keyboard_scan.h" +#include "keyboard_backlight.h" #include "lid_switch.h" #include "power.h" #include "power_button.h" @@ -409,6 +410,38 @@ struct motion_sensor_t motion_sensors[] = { }; const unsigned int motion_sensor_count = ARRAY_SIZE(motion_sensors); +const struct it8801_pwm_t it8801_pwm_channels[] = { + [IT8801_PWM_CH_KBLIGHT] = {.index = 4}, +}; + +void board_kblight_init(void) +{ + kblight_register(&kblight_it8801); +} + +bool board_has_kb_backlight(void) +{ + /* Default enable keyboard backlight */ + return true; +} + +/* Called on AP S0iX -> S0 transition */ +static void board_chipset_resume(void) +{ + if (board_has_kb_backlight()) + ioex_set_level(IOEX_KB_BL_EN, 1); +} +DECLARE_HOOK(HOOK_CHIPSET_RESUME, board_chipset_resume, HOOK_PRIO_DEFAULT); +DECLARE_HOOK(HOOK_INIT, board_chipset_resume, HOOK_PRIO_DEFAULT); + +/* Called on AP S0 -> S0iX transition */ +static void board_chipset_suspend(void) +{ + if (board_has_kb_backlight()) + ioex_set_level(IOEX_KB_BL_EN, 0); +} +DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, board_chipset_suspend, HOOK_PRIO_DEFAULT); + #endif /* !VARIANT_KUKUI_NO_SENSORS */ /* Called on AP S5 -> S3 transition */ diff --git a/board/fennel/board.h b/board/fennel/board.h index e0f013dc0d..ab036dc476 100644 --- a/board/fennel/board.h +++ b/board/fennel/board.h @@ -61,6 +61,9 @@ #define CONFIG_ACCEL_FORCE_MODE_MASK BIT(LID_ACCEL) +#define CONFIG_IO_EXPANDER_IT8801_PWM +#define CONFIG_KEYBOARD_BACKLIGHT + #endif /* VARIANT_KUKUI_NO_SENSORS */ /* I2C ports */ @@ -123,6 +126,10 @@ enum battery_type { BATTERY_TYPE_COUNT, }; +enum pwm_channel { + IT8801_PWM_CH_KBLIGHT = 0, +}; + #include "gpio_signal.h" #include "registers.h" diff --git a/board/fennel/gpio.inc b/board/fennel/gpio.inc index 6f531634a1..7aed6abfc2 100644 --- a/board/fennel/gpio.inc +++ b/board/fennel/gpio.inc @@ -87,6 +87,7 @@ GPIO(USB_C0_DISCHARGE, PIN(B, 6), GPIO_OUT_LOW) IOEX(LED_BLUE, EXPIN(0, 1, 4), GPIO_OUT_HIGH) /* LED BLUE */ IOEX(LED_GREEN, EXPIN(0, 1, 3), GPIO_OUT_HIGH) /* LED GREEN */ IOEX(LED_ORANGE, EXPIN(0, 1, 2), GPIO_OUT_HIGH) /* LED ORANGE */ +IOEX(KB_BL_EN, EXPIN(0, 0, 7), GPIO_OUT_LOW) /* * TODO(b:138352732): On IT88801 expander, To be readded once IT8801 driver and diff --git a/driver/ioexpander/it8801.c b/driver/ioexpander/it8801.c index 2f560a4468..df6ea3e76e 100644 --- a/driver/ioexpander/it8801.c +++ b/driver/ioexpander/it8801.c @@ -14,6 +14,7 @@ #include "registers.h" #include "task.h" #include "util.h" +#include "keyboard_backlight.h" #define CPRINTS(format, args...) cprints(CC_KEYSCAN, format, ## args) @@ -430,16 +431,17 @@ DECLARE_CONSOLE_COMMAND(it8801_dump, it8801_dump, "NULL", struct it8801_pwm_gpio_map { int port; int mask; + int pushpull_en; }; const static struct it8801_pwm_gpio_map it8801_pwm_gpio_map[] = { - [1] = {.port = 1, .mask = BIT(2)}, - [2] = {.port = 1, .mask = BIT(3)}, - [3] = {.port = 1, .mask = BIT(4)}, - [4] = {.port = 1, .mask = BIT(5)}, - [7] = {.port = 2, .mask = BIT(0)}, - [8] = {.port = 2, .mask = BIT(3)}, - [9] = {.port = 2, .mask = BIT(2)}, + [1] = {.port = 1, .mask = BIT(2), .pushpull_en = BIT(0)}, + [2] = {.port = 1, .mask = BIT(3), .pushpull_en = BIT(1)}, + [3] = {.port = 1, .mask = BIT(4), .pushpull_en = BIT(2)}, + [4] = {.port = 1, .mask = BIT(5), .pushpull_en = BIT(3)}, + [7] = {.port = 2, .mask = BIT(0), .pushpull_en = BIT(4)}, + [8] = {.port = 2, .mask = BIT(3), .pushpull_en = BIT(5)}, + [9] = {.port = 2, .mask = BIT(2), .pushpull_en = BIT(6)}, }; void it8801_pwm_enable(enum pwm_channel ch, int enabled) @@ -470,9 +472,19 @@ void it8801_pwm_enable(enum pwm_channel ch, int enabled) if (enabled) val |= IT8801_PWMMCR_MCR_BLINKING; it8801_write(IT8801_REG_PWMMCR(it8801_pwm_channels[ch].index), val); + + /* + * 1: enable push pull function + */ + it8801_read(IT8801_REG_PWMODDSR, &val); + val &= ~it8801_pwm_gpio_map[index].pushpull_en; + if (enabled) + val |= it8801_pwm_gpio_map[index].pushpull_en; + it8801_write(IT8801_REG_PWMODDSR, val); + } -int it88801_pwm_get_enabled(enum pwm_channel ch) +int it8801_pwm_get_enabled(enum pwm_channel ch) { int val; @@ -507,4 +519,38 @@ int it8801_pwm_get_duty(enum pwm_channel ch) return 100 - it8801_pwm_get_raw_duty(ch) * 100 / 255; } +#if defined(SECTION_IS_RW) && defined(CONFIG_KEYBOARD_BACKLIGHT) +const enum pwm_channel it8801_kblight_pwm_ch = IT8801_PWM_CH_KBLIGHT; + +static int it8801_kblight_enable(int enable) +{ + it8801_pwm_enable(it8801_kblight_pwm_ch, enable); + return EC_SUCCESS; +} + +static int it8801_kblight_set_brightness(int percent) +{ + it8801_pwm_set_duty(it8801_kblight_pwm_ch, percent); + return EC_SUCCESS; +} + +static int it8801_kblight_get_brightness(void) +{ + return it8801_pwm_get_duty(it8801_kblight_pwm_ch); +} + +static int it8801_kblight_init(void) +{ + it8801_pwm_set_duty(it8801_kblight_pwm_ch, 0); + it8801_pwm_enable(it8801_kblight_pwm_ch, 1); + return EC_SUCCESS; +} + +const struct kblight_drv kblight_it8801 = { + .init = it8801_kblight_init, + .set = it8801_kblight_set_brightness, + .get = it8801_kblight_get_brightness, + .enable = it8801_kblight_enable, +}; +#endif #endif /* CONFIG_IO_EXPANDER_IT8801_PWM */ diff --git a/driver/ioexpander/it8801.h b/driver/ioexpander/it8801.h index 016412ca22..25a82fe617 100644 --- a/driver/ioexpander/it8801.h +++ b/driver/ioexpander/it8801.h @@ -95,15 +95,17 @@ struct it8801_pwm_t { }; extern const struct it8801_pwm_t it8801_pwm_channels[]; +extern const struct kblight_drv kblight_it8801; /* standard pwm interface as defined in pwm.h */ void it8801_pwm_enable(enum pwm_channel ch, int enabled); -int it88801_pwm_get_enabled(enum pwm_channel ch); +int it8801_pwm_get_enabled(enum pwm_channel ch); void it8801_pwm_set_raw_duty(enum pwm_channel ch, uint16_t duty); uint16_t it8801_pwm_get_raw_duty(enum pwm_channel ch); void it8801_pwm_set_duty(enum pwm_channel ch, int percent); int it8801_pwm_get_duty(enum pwm_channel ch); +#define IT8801_REG_PWMODDSR 0x5F #define IT8801_REG_PWMMCR(n) (0x60 + ((n) - 1) * 8) #define IT8801_REG_PWMDCR(n) (0x64 + ((n) - 1) * 8) #define IT8801_REG_PWMPRSL(n) (0x66 + ((n) - 1) * 8) |