Lines Matching +full:latched +full:- +full:gpios
1 // SPDX-License-Identifier: GPL-2.0+
3 * Intel ICH6-10, Series 5 and 6, Atom C2000 (Avoton/Rangeley) GPIO driver
19 * Each chunk of 32 GPIOs is manipulated via its own USE_SELx, IO_SELx, and
34 {0x00, 0x30, 0x40}, /* USE_SEL[1-3] offsets */
35 {0x04, 0x34, 0x44}, /* IO_SEL[1-3] offsets */
36 {0x0c, 0x38, 0x48}, /* LVL[1-3] offsets */
54 #define ICHX_WRITE(val, reg, base_res) outl(val, (reg) + (base_res)->start)
55 #define ICHX_READ(reg, base_res) inl((reg) + (base_res)->start)
91 struct ichx_desc *desc; /* Pointer to chipset-specific description */
97 static int modparam_gpiobase = -1; /* dynamic */
99 MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, which is the default.");
110 if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache) in ichx_write_bit()
113 data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], in ichx_write_bit()
120 ICHX_WRITE(data, ichx_priv.desc->regs[reg][reg_nr], in ichx_write_bit()
122 if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache) in ichx_write_bit()
125 tmp = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], in ichx_write_bit()
130 return (verify && data != tmp) ? -EPERM : 0; in ichx_write_bit()
142 data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr], in ichx_read_bit()
145 if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache) in ichx_read_bit()
170 * are output-only. in ichx_gpio_direction_input()
178 /* Disable blink hardware which is available for GPIOs from 0 to 31. */ in ichx_gpio_direction_output()
179 if (nr < 32 && ichx_priv.desc->have_blink) in ichx_gpio_direction_output()
187 * are input-only. in ichx_gpio_direction_output()
203 * GPI 0 - 15 need to be read from the power management registers on in ich6_gpio_get()
208 return -ENXIO; in ich6_gpio_get()
212 /* GPI 0 - 15 are latched, write 1 to clear*/ in ich6_gpio_get()
227 return -ENXIO; in ichx_gpio_request()
235 if (ichx_priv.desc->use_sel_ignore[nr / 32] & BIT(nr & 0x1f)) in ichx_gpio_request()
238 return ichx_read_bit(GPIO_USE_SEL, nr) ? 0 : -ENODEV; in ichx_gpio_request()
250 nr -= 16; in ich6_gpio_request()
262 chip->owner = THIS_MODULE; in ichx_gpiolib_setup()
263 chip->label = DRV_NAME; in ichx_gpiolib_setup()
264 chip->parent = ichx_priv.dev; in ichx_gpiolib_setup()
266 /* Allow chip-specific overrides of request()/get() */ in ichx_gpiolib_setup()
267 chip->request = ichx_priv.desc->request ? in ichx_gpiolib_setup()
268 ichx_priv.desc->request : ichx_gpio_request; in ichx_gpiolib_setup()
269 chip->get = ichx_priv.desc->get ? in ichx_gpiolib_setup()
270 ichx_priv.desc->get : ichx_gpio_get; in ichx_gpiolib_setup()
272 chip->set = ichx_gpio_set; in ichx_gpiolib_setup()
273 chip->get_direction = ichx_gpio_get_direction; in ichx_gpiolib_setup()
274 chip->direction_input = ichx_gpio_direction_input; in ichx_gpiolib_setup()
275 chip->direction_output = ichx_gpio_direction_output; in ichx_gpiolib_setup()
276 chip->base = modparam_gpiobase; in ichx_gpiolib_setup()
277 chip->ngpio = ichx_priv.desc->ngpio; in ichx_gpiolib_setup()
278 chip->can_sleep = false; in ichx_gpiolib_setup()
279 chip->dbg_show = NULL; in ichx_gpiolib_setup()
282 /* ICH6-based, 631xesb-based */
284 /* Bridges using the ICH6 controller need fixups for GPIO 0 - 17 */
288 /* GPIO 0-15 are read in the GPE0_STS PM register */
306 /* The 3100 needs fixups for GPIO 0 - 17 */
310 /* GPIO 0-15 are read in the GPE0_STS PM register */
318 /* ICH7 and ICH8-based */
326 /* ICH9-based */
334 /* ICH10-based - Consumer/corporate versions have different amount of GPIO */
357 /* Avoton has only 59 GPIOs, but we assume the first set of register
358 * (Core) has 32 instead of 31 to keep gpio-ich compliance
371 if (!res_base || !res_base->start || !res_base->end) in ichx_gpio_request_regions()
372 return -ENODEV; in ichx_gpio_request_regions()
374 for (i = 0; i < ARRAY_SIZE(ichx_priv.desc->regs[0]); i++) { in ichx_gpio_request_regions()
378 res_base->start + ichx_priv.desc->regs[0][i], in ichx_gpio_request_regions()
379 ichx_priv.desc->reglen[i], name)) in ichx_gpio_request_regions()
380 return -EBUSY; in ichx_gpio_request_regions()
387 struct device *dev = &pdev->dev; in ichx_gpio_probe()
393 return -ENODEV; in ichx_gpio_probe()
395 switch (ich_info->gpio_version) { in ichx_gpio_probe()
421 return -ENODEV; in ichx_gpio_probe()
428 err = ichx_gpio_request_regions(dev, res_base, pdev->name, in ichx_gpio_probe()
429 ich_info->use_gpio); in ichx_gpio_probe()
434 ichx_priv.use_gpio = ich_info->use_gpio; in ichx_gpio_probe()
439 * 0 - 15 on some chipsets. in ichx_gpio_probe()
441 if (!ichx_priv.desc->uses_gpe0) in ichx_gpio_probe()
446 dev_warn(dev, "ACPI BAR is unavailable, GPI 0 - 15 unavailable\n"); in ichx_gpio_probe()
450 if (!devm_request_region(dev, res_pm->start, resource_size(res_pm), in ichx_gpio_probe()
451 pdev->name)) { in ichx_gpio_probe()
452 dev_warn(dev, "ACPI BAR is busy, GPI 0 - 15 unavailable\n"); in ichx_gpio_probe()
462 dev_err(dev, "Failed to register GPIOs\n"); in ichx_gpio_probe()
467 ichx_priv.chip.base + ichx_priv.chip.ngpio - 1); in ichx_gpio_probe()
481 MODULE_AUTHOR("Peter Tyser <ptyser@xes-inc.com>");