|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ |
| 2 | + |
| 3 | +#include <device/pnp_ops.h> |
| 4 | +#include <device/pnp.h> |
| 5 | +#include <stdint.h> |
| 6 | + |
| 7 | +#include "ite.h" |
| 8 | +#include "ite_gpio.h" |
| 9 | + |
| 10 | +/* Catch ITE SIOs that enable the driver but do not configure the number of sets */ |
| 11 | +#if CONFIG_SUPERIO_ITE_COMMON_NUM_GPIO_SETS == 0 |
| 12 | +#error "Maximum number of ITE SIO GPIO sets not provided" |
| 13 | +#endif |
| 14 | + |
| 15 | +#if CONFIG_SUPERIO_ITE_COMMON_NUM_GPIO_SETS > 10 |
| 16 | +#error "ITE SIO GPIO drivers only support up to 10 GPIO sets" |
| 17 | +#endif |
| 18 | + |
| 19 | +/* GPIO Polarity Select: 1: Inverting, 0: Non-inverting */ |
| 20 | +#define ITE_GPIO_REG_POLARITY(x) \ |
| 21 | + (((x) > 8) ? (0xd1 + ((x) - 9) * 5) \ |
| 22 | + : (0xb0 + ((x) - 1)) \ |
| 23 | + ) |
| 24 | + |
| 25 | +/* GPIO Internal Pull-up: 1: Enable, 0: Disable */ |
| 26 | +#define ITE_GPIO_REG_PULLUP(x) \ |
| 27 | + (((x) > 8) ? (0xd4 + ((x) - 9) * 5) \ |
| 28 | + : (0xb8 + ((x) - 1)) \ |
| 29 | + ) |
| 30 | + |
| 31 | +/* GPIO Function Select: 1: Simple I/O, 0: Alternate function */ |
| 32 | +#define ITE_GPIO_REG_FN_SELECT(x) \ |
| 33 | + (((x) > 8) ? (0xd3 + ((x) - 9) * 5) \ |
| 34 | + : (0xc0 + ((x) - 1)) \ |
| 35 | + ) |
| 36 | + |
| 37 | +/* GPIO Mode: 0: input mode, 1: output mode */ |
| 38 | +#define ITE_GPIO_REG_OUTPUT(x) \ |
| 39 | + (((x) > 8) ? (0xd2 + ((x) - 9) * 5) \ |
| 40 | + : (0xc8 + ((x) - 1)) \ |
| 41 | + ) |
| 42 | + |
| 43 | +/* GPIO LED pin mapping register */ |
| 44 | +#define ITE_GPIO_REG_LED_PINMAP(x) (0xf8 + ((x) & 1) * 2) |
| 45 | +#define ITE_GPIO_LED_PIN_LOC(set, pin) ((((set) & 7) << 3) | ((pin) & 7)) |
| 46 | +#define ITE_GPIO_LED_PIN_LOC_MASK 0x3f |
| 47 | +/* GPIO LED control register */ |
| 48 | +#define ITE_GPIO_REG_LED_CONTROL(x) (0xf9 + ((x) & 1) * 2) |
| 49 | +#define ITE_GPIO_LED_OUTPUT_LOW (1 << 0) |
| 50 | +#define ITE_GPIO_LED_PINMAP_CLEAR (1 << 4) |
| 51 | +#define ITE_GPIO_LED_SHORT_LOW_PULSE \ |
| 52 | + (CONFIG(SUPERIO_ITE_COMMON_GPIO_LED_FREQ_5BIT) ? (1 << 5) \ |
| 53 | + : (1 << 3) \ |
| 54 | + ) |
| 55 | +#define ITE_GPIO_LED_FREQ_SEL(x) \ |
| 56 | + (CONFIG(SUPERIO_ITE_COMMON_GPIO_LED_FREQ_5BIT) \ |
| 57 | + ? ((((x) & 0x18) << 3) | (((x) & 0x7) << 1)) \ |
| 58 | + : (((x) & 0x3) << 1) \ |
| 59 | + ) |
| 60 | +#define ITE_GPIO_LED_FREQ_SEL_MASK \ |
| 61 | + (CONFIG(SUPERIO_ITE_COMMON_GPIO_LED_FREQ_5BIT) ? 0xce : 0x06) |
| 62 | + |
| 63 | +static bool ite_has_gpio_fn_select_reg(u8 set) |
| 64 | +{ |
| 65 | + /* IT8718F has all registers for all sets. */ |
| 66 | + if (CONFIG(SUPERIO_ITE_IT8718F)) |
| 67 | + return true; |
| 68 | + |
| 69 | + /* Typically ITE GPIO sets 6 to 8 don't have enable and polarity registers. */ |
| 70 | + if (set < 6 || set > 8) |
| 71 | + return true; |
| 72 | + |
| 73 | + return false; |
| 74 | +} |
| 75 | + |
| 76 | +static bool ite_has_gpio_polarity_reg(u8 set) |
| 77 | +{ |
| 78 | + /* IT8718F has all registers for all sets. */ |
| 79 | + if (CONFIG(SUPERIO_ITE_IT8718F)) |
| 80 | + return true; |
| 81 | + |
| 82 | + /* IT8720F/IT8721F has polarity register for all GPIO sets */ |
| 83 | + if (CONFIG(SUPERIO_ITE_IT8720F) || CONFIG(SUPERIO_ITE_IT8721F)) |
| 84 | + return true; |
| 85 | + |
| 86 | + /* Typically ITE GPIO sets 6 to 8 don't have enable and polarity registers. */ |
| 87 | + if (set < 6 || set > 8) |
| 88 | + return true; |
| 89 | + |
| 90 | + return false; |
| 91 | +} |
| 92 | + |
| 93 | +static bool ite_has_gpio_pullup_reg(u8 set) |
| 94 | +{ |
| 95 | + /* IT8718F/IT8720F does not have pull-up register for set 2 */ |
| 96 | + if ((CONFIG(SUPERIO_ITE_IT8718F) || CONFIG(SUPERIO_ITE_IT8720F)) && (set == 2)) |
| 97 | + return false; |
| 98 | + |
| 99 | + /* IT8783E/F does not have pull-up register for set 6 */ |
| 100 | + if (CONFIG(SUPERIO_ITE_IT8783EF) && (set == 6)) |
| 101 | + return false; |
| 102 | + |
| 103 | + /* |
| 104 | + * ITE GPIO Sets 7 and 8 don't have a pullup register. |
| 105 | + * See IT8786/IT8625 datasheet section 8.10.10. |
| 106 | + * Also applies to IT8728F. |
| 107 | + */ |
| 108 | + if (set != 7 && set != 8) |
| 109 | + return true; |
| 110 | + |
| 111 | + return false; |
| 112 | +} |
| 113 | + |
| 114 | +/* |
| 115 | + * Configures a single GPIO given its number as gpio_num, direction ("in_out" |
| 116 | + * parameter) and properties, such as polarity and pull ("gpio_ctrl" |
| 117 | + * parameter). The "enable" parameter can configure the GPIO in Simple I/O |
| 118 | + * mode when set or Alternate function mode when clear. Some chips may also |
| 119 | + * not support configuring all properties for a particular GPIO. It is left to |
| 120 | + * the implementer to check if GPIO settings are valid for given gpio_num. |
| 121 | + */ |
| 122 | +void ite_gpio_setup(pnp_devfn_t gpiodev, u8 gpio_num, enum ite_gpio_direction in_out, |
| 123 | + enum ite_gpio_mode enable, u8 gpio_ctrl) |
| 124 | +{ |
| 125 | + u8 set = (gpio_num / 10); |
| 126 | + u8 pin = (gpio_num % 10); |
| 127 | + |
| 128 | + /* Number of configurable sets is chip dependent, 8 pins each */ |
| 129 | + if (gpio_num < 10 || set > CONFIG_SUPERIO_ITE_COMMON_NUM_GPIO_SETS || pin > 7) |
| 130 | + return; |
| 131 | + |
| 132 | + pnp_enter_conf_state(gpiodev); |
| 133 | + pnp_set_logical_device(gpiodev); |
| 134 | + |
| 135 | + if (ite_has_gpio_fn_select_reg(set)) |
| 136 | + pnp_unset_and_set_config(gpiodev, ITE_GPIO_REG_FN_SELECT(set), |
| 137 | + 1 << pin, (enable & 1) << pin); |
| 138 | + |
| 139 | + if (ite_has_gpio_polarity_reg(set)) |
| 140 | + pnp_unset_and_set_config(gpiodev, ITE_GPIO_REG_POLARITY(set), |
| 141 | + 1 << pin, |
| 142 | + (gpio_ctrl & ITE_GPIO_POL_INVERT) ? 1 << pin : 0); |
| 143 | + |
| 144 | + |
| 145 | + pnp_unset_and_set_config(gpiodev, ITE_GPIO_REG_OUTPUT(set), 1 << pin, (in_out & 1) << pin); |
| 146 | + |
| 147 | + if (ite_has_gpio_pullup_reg(set)) |
| 148 | + pnp_unset_and_set_config(gpiodev, ITE_GPIO_REG_PULLUP(set), 1 << pin, |
| 149 | + (gpio_ctrl & ITE_GPIO_PULLUP_ENABLE) ? 1 << pin : 0); |
| 150 | + |
| 151 | + pnp_exit_conf_state(gpiodev); |
| 152 | +} |
| 153 | + |
| 154 | +void ite_gpio_setup_led(pnp_devfn_t gpiodev, u8 gpio_num, |
| 155 | + enum ite_gpio_led led_no, |
| 156 | + enum ite_led_frequency freq, |
| 157 | + u8 led_ctrl) |
| 158 | +{ |
| 159 | + u8 set = (gpio_num / 10); |
| 160 | + u8 pin = (gpio_num % 10); |
| 161 | + u8 reg = 0; |
| 162 | + |
| 163 | + /* Number of configurable sets is chip dependent, 8 pins each */ |
| 164 | + if (gpio_num < 10 || set > CONFIG_SUPERIO_ITE_COMMON_NUM_GPIO_SETS || pin > 7) |
| 165 | + return; |
| 166 | + |
| 167 | + /* LED is available only for GPIO sets 1-5 */ |
| 168 | + if (set > 5) |
| 169 | + return; |
| 170 | + |
| 171 | + pnp_enter_conf_state(gpiodev); |
| 172 | + pnp_set_logical_device(gpiodev); |
| 173 | + |
| 174 | + /* Pinmap clear bit is only available when frequency is controlled with 5 bits */ |
| 175 | + if (CONFIG(SUPERIO_ITE_COMMON_GPIO_LED_FREQ_5BIT) && (led_ctrl & ITE_LED_PINMAP_CLEAR)) |
| 176 | + reg |= ITE_GPIO_LED_PINMAP_CLEAR; |
| 177 | + |
| 178 | + if (led_ctrl & ITE_LED_OUTPUT_LOW) |
| 179 | + reg |= ITE_GPIO_LED_OUTPUT_LOW; |
| 180 | + |
| 181 | + if (led_ctrl & ITE_LED_SHORT_LOW_PULSE) |
| 182 | + reg |= ITE_GPIO_LED_SHORT_LOW_PULSE; |
| 183 | + |
| 184 | + reg |= ITE_GPIO_LED_FREQ_SEL(freq); |
| 185 | + pnp_write_config(gpiodev, ITE_GPIO_REG_LED_CONTROL(led_no), reg); |
| 186 | + |
| 187 | + reg = ITE_GPIO_LED_PIN_LOC(set, pin); |
| 188 | + pnp_write_config(gpiodev, ITE_GPIO_REG_LED_PINMAP(led_no), reg); |
| 189 | + |
| 190 | + pnp_exit_conf_state(gpiodev); |
| 191 | +} |
0 commit comments