Lines Matching +full:nr +full:- +full:gpios
1 // SPDX-License-Identifier: GPL-2.0+
3 * Intel ICH6-10, Series 5 and 6, Atom C2000 (Avoton/Rangeley) GPIO driver
21 * Each chunk of 32 GPIOs is manipulated via its own USE_SELx, IO_SELx, and
36 {0x00, 0x30, 0x40}, /* USE_SEL[1-3] offsets */
37 {0x04, 0x34, 0x44}, /* IO_SEL[1-3] offsets */
38 {0x0c, 0x38, 0x48}, /* LVL[1-3] offsets */
56 #define ICHX_WRITE(val, reg, base_res) outl(val, (reg) + (base_res)->start)
57 #define ICHX_READ(reg, base_res) inl((reg) + (base_res)->start)
93 struct ichx_desc *desc; /* Pointer to chipset-specific description */
99 static int modparam_gpiobase = -1; /* dynamic */
101 MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, which is the default.");
103 static int ichx_write_bit(int reg, unsigned int nr, int val, int verify) in ichx_write_bit() argument
107 int reg_nr = nr / 32; in ichx_write_bit()
108 int bit = nr & 0x1f; in ichx_write_bit()
112 if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache) in ichx_write_bit()
115 data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], in ichx_write_bit()
122 ICHX_WRITE(data, ichx_priv.desc->regs[reg][reg_nr], in ichx_write_bit()
124 if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache) in ichx_write_bit()
127 tmp = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], in ichx_write_bit()
132 return (verify && data != tmp) ? -EPERM : 0; in ichx_write_bit()
135 static int ichx_read_bit(int reg, unsigned int nr) in ichx_read_bit() argument
139 int reg_nr = nr / 32; in ichx_read_bit()
140 int bit = nr & 0x1f; in ichx_read_bit()
144 data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], in ichx_read_bit()
147 if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache) in ichx_read_bit()
155 static bool ichx_gpio_check_available(struct gpio_chip *gpio, unsigned int nr) in ichx_gpio_check_available() argument
157 return !!(ichx_priv.use_gpio & BIT(nr / 32)); in ichx_gpio_check_available()
160 static int ichx_gpio_get_direction(struct gpio_chip *gpio, unsigned int nr) in ichx_gpio_get_direction() argument
162 if (ichx_read_bit(GPIO_IO_SEL, nr)) in ichx_gpio_get_direction()
168 static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned int nr) in ichx_gpio_direction_input() argument
172 * are output-only. in ichx_gpio_direction_input()
174 return ichx_write_bit(GPIO_IO_SEL, nr, 1, 1); in ichx_gpio_direction_input()
177 static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned int nr, in ichx_gpio_direction_output() argument
180 /* Disable blink hardware which is available for GPIOs from 0 to 31. */ in ichx_gpio_direction_output()
181 if (nr < 32 && ichx_priv.desc->have_blink) in ichx_gpio_direction_output()
182 ichx_write_bit(GPO_BLINK, nr, 0, 0); in ichx_gpio_direction_output()
185 ichx_write_bit(GPIO_LVL, nr, val, 0); in ichx_gpio_direction_output()
189 * are input-only. in ichx_gpio_direction_output()
191 return ichx_write_bit(GPIO_IO_SEL, nr, 0, 1); in ichx_gpio_direction_output()
194 static int ichx_gpio_get(struct gpio_chip *chip, unsigned int nr) in ichx_gpio_get() argument
196 return ichx_read_bit(GPIO_LVL, nr); in ichx_gpio_get()
199 static int ich6_gpio_get(struct gpio_chip *chip, unsigned int nr) in ich6_gpio_get() argument
205 * GPI 0 - 15 need to be read from the power management registers on in ich6_gpio_get()
208 if (nr < 16) { in ich6_gpio_get()
210 return -ENXIO; in ich6_gpio_get()
214 /* GPI 0 - 15 are latched, write 1 to clear*/ in ich6_gpio_get()
215 ICHX_WRITE(BIT(16 + nr), 0, ichx_priv.pm_base); in ich6_gpio_get()
220 return !!((data >> 16) & BIT(nr)); in ich6_gpio_get()
222 return ichx_gpio_get(chip, nr); in ich6_gpio_get()
226 static int ichx_gpio_request(struct gpio_chip *chip, unsigned int nr) in ichx_gpio_request() argument
228 if (!ichx_gpio_check_available(chip, nr)) in ichx_gpio_request()
229 return -ENXIO; in ichx_gpio_request()
237 if (ichx_priv.desc->use_sel_ignore[nr / 32] & BIT(nr & 0x1f)) in ichx_gpio_request()
240 return ichx_read_bit(GPIO_USE_SEL, nr) ? 0 : -ENODEV; in ichx_gpio_request()
243 static int ich6_gpio_request(struct gpio_chip *chip, unsigned int nr) in ich6_gpio_request() argument
251 if (nr == 16 || nr == 17) in ich6_gpio_request()
252 nr -= 16; in ich6_gpio_request()
254 return ichx_gpio_request(chip, nr); in ich6_gpio_request()
257 static void ichx_gpio_set(struct gpio_chip *chip, unsigned int nr, int val) in ichx_gpio_set() argument
259 ichx_write_bit(GPIO_LVL, nr, val, 0); in ichx_gpio_set()
264 chip->owner = THIS_MODULE; in ichx_gpiolib_setup()
265 chip->label = DRV_NAME; in ichx_gpiolib_setup()
266 chip->parent = ichx_priv.dev; in ichx_gpiolib_setup()
268 /* Allow chip-specific overrides of request()/get() */ in ichx_gpiolib_setup()
269 chip->request = ichx_priv.desc->request ? in ichx_gpiolib_setup()
270 ichx_priv.desc->request : ichx_gpio_request; in ichx_gpiolib_setup()
271 chip->get = ichx_priv.desc->get ? in ichx_gpiolib_setup()
272 ichx_priv.desc->get : ichx_gpio_get; in ichx_gpiolib_setup()
274 chip->set = ichx_gpio_set; in ichx_gpiolib_setup()
275 chip->get_direction = ichx_gpio_get_direction; in ichx_gpiolib_setup()
276 chip->direction_input = ichx_gpio_direction_input; in ichx_gpiolib_setup()
277 chip->direction_output = ichx_gpio_direction_output; in ichx_gpiolib_setup()
278 chip->base = modparam_gpiobase; in ichx_gpiolib_setup()
279 chip->ngpio = ichx_priv.desc->ngpio; in ichx_gpiolib_setup()
280 chip->can_sleep = false; in ichx_gpiolib_setup()
281 chip->dbg_show = NULL; in ichx_gpiolib_setup()
284 /* ICH6-based, 631xesb-based */
286 /* Bridges using the ICH6 controller need fixups for GPIO 0 - 17 */
290 /* GPIO 0-15 are read in the GPE0_STS PM register */
308 /* The 3100 needs fixups for GPIO 0 - 17 */
312 /* GPIO 0-15 are read in the GPE0_STS PM register */
320 /* ICH7 and ICH8-based */
328 /* ICH9-based */
336 /* ICH10-based - Consumer/corporate versions have different amount of GPIO */
359 /* Avoton has only 59 GPIOs, but we assume the first set of register
360 * (Core) has 32 instead of 31 to keep gpio-ich compliance
373 if (!res_base || !res_base->start || !res_base->end) in ichx_gpio_request_regions()
374 return -ENODEV; in ichx_gpio_request_regions()
376 for (i = 0; i < ARRAY_SIZE(ichx_priv.desc->regs[0]); i++) { in ichx_gpio_request_regions()
380 res_base->start + ichx_priv.desc->regs[0][i], in ichx_gpio_request_regions()
381 ichx_priv.desc->reglen[i], name)) in ichx_gpio_request_regions()
382 return -EBUSY; in ichx_gpio_request_regions()
389 struct device *dev = &pdev->dev; in ichx_gpio_probe()
395 return -ENODEV; in ichx_gpio_probe()
397 switch (ich_info->gpio_version) { in ichx_gpio_probe()
423 return -ENODEV; in ichx_gpio_probe()
430 err = ichx_gpio_request_regions(dev, res_base, pdev->name, in ichx_gpio_probe()
431 ich_info->use_gpio); in ichx_gpio_probe()
436 ichx_priv.use_gpio = ich_info->use_gpio; in ichx_gpio_probe()
441 * 0 - 15 on some chipsets. in ichx_gpio_probe()
443 if (!ichx_priv.desc->uses_gpe0) in ichx_gpio_probe()
448 dev_warn(dev, "ACPI BAR is unavailable, GPI 0 - 15 unavailable\n"); in ichx_gpio_probe()
452 if (!devm_request_region(dev, res_pm->start, resource_size(res_pm), in ichx_gpio_probe()
453 pdev->name)) { in ichx_gpio_probe()
454 dev_warn(dev, "ACPI BAR is busy, GPI 0 - 15 unavailable\n"); in ichx_gpio_probe()
464 dev_err(dev, "Failed to register GPIOs\n"); in ichx_gpio_probe()
469 ichx_priv.chip.base + ichx_priv.chip.ngpio - 1); in ichx_gpio_probe()
491 MODULE_AUTHOR("Peter Tyser <ptyser@xes-inc.com>");