Lines Matching +full:chip +full:- +full:enable +full:- +full:gpios
1 // SPDX-License-Identifier: GPL-2.0+
5 * Copyright (c) 2007-2008 MontaVista Software, Inc.
26 #include "gpiolib-of.h"
29 * This is Linux-specific flags. By default controllers' and Linux' mapping
31 * Linux-specific in their .xlate callback. Though, 1:1 mapping is recommended.
44 * of_gpio_named_count() - Count GPIOs for a device
45 * @np: device node to count GPIOs for
48 * The function returns the count of GPIOs specified for a node.
50 * Number of gpios defined in property,
51 * -EINVAL for an incorrectly formed gpios property, or
52 * -ENOENT for a missing gpios property
55 * gpios = <0
60 * The above example defines four GPIOs, two of which are not specified.
66 return of_count_phandle_with_args(np, propname, "#gpio-cells"); in of_gpio_named_count()
70 * of_gpio_spi_cs_get_count() - special GPIO counting for SPI
76 * established "cs-gpios" for chip selects but instead rely on
77 * "gpios" for the chip select lines. If we detect this, we redirect
78 * the counting of "cs-gpios" to count "gpios" transparent to the
83 struct device_node *np = dev->of_node; in of_gpio_spi_cs_get_count()
91 !of_device_is_compatible(np, "ibm,ppc4xx-spi")) in of_gpio_spi_cs_get_count()
93 return of_gpio_named_count(np, "gpios"); in of_gpio_spi_cs_get_count()
108 snprintf(propname, sizeof(propname), "%s-%s", in of_gpio_get_count()
114 ret = of_gpio_named_count(dev->of_node, propname); in of_gpio_get_count()
118 return ret ? ret : -ENOENT; in of_gpio_get_count()
121 static int of_gpiochip_match_node_and_xlate(struct gpio_chip *chip, void *data) in of_gpiochip_match_node_and_xlate() argument
125 return device_match_of_node(&chip->gpiodev->dev, gpiospec->np) && in of_gpiochip_match_node_and_xlate()
126 chip->of_xlate && in of_gpiochip_match_node_and_xlate()
127 chip->of_xlate(chip, gpiospec, NULL) >= 0; in of_gpiochip_match_node_and_xlate()
136 static struct gpio_desc *of_xlate_and_get_gpiod_flags(struct gpio_chip *chip, in of_xlate_and_get_gpiod_flags() argument
142 if (chip->of_gpio_n_cells != gpiospec->args_count) in of_xlate_and_get_gpiod_flags()
143 return ERR_PTR(-EINVAL); in of_xlate_and_get_gpiod_flags()
145 ret = chip->of_xlate(chip, gpiospec, flags); in of_xlate_and_get_gpiod_flags()
149 return gpiochip_get_desc(chip, ret); in of_xlate_and_get_gpiod_flags()
162 pr_warn("%s GPIO handle specifies active low - ignored\n", in of_gpio_quirk_polarity()
186 } gpios[] = { in of_gpio_try_fixup_polarity() local
190 * "gpios-reset" property and also specified wrong in of_gpio_try_fixup_polarity()
193 { "himax,hx8357", "gpios-reset", false }, in of_gpio_try_fixup_polarity()
194 { "himax,hx8369", "gpios-reset", false }, in of_gpio_try_fixup_polarity()
199 * active-low signal. However, most of the device trees that in of_gpio_try_fixup_polarity()
201 * reset GPIO as active-high, and were also using wrong name in of_gpio_try_fixup_polarity()
204 { "lantiq,pci-xway", "gpio-reset", false }, in of_gpio_try_fixup_polarity()
209 * active-high signals. However, exynos5250-spring.dts use in of_gpio_try_fixup_polarity()
210 * active-low setting. in of_gpio_try_fixup_polarity()
212 { "samsung,s5m8767-pmic", "s5m8767,pmic-buck-dvs-gpios", true }, in of_gpio_try_fixup_polarity()
213 { "samsung,s5m8767-pmic", "s5m8767,pmic-buck-ds-gpios", true }, in of_gpio_try_fixup_polarity()
218 * polarity for the reset line, while the chip actually in of_gpio_try_fixup_polarity()
221 { "ti,tsc2005", "reset-gpios", false }, in of_gpio_try_fixup_polarity()
226 for (i = 0; i < ARRAY_SIZE(gpios); i++) { in of_gpio_try_fixup_polarity()
227 if (of_device_is_compatible(np, gpios[i].compatible) && in of_gpio_try_fixup_polarity()
228 !strcmp(propname, gpios[i].propname)) { in of_gpio_try_fixup_polarity()
229 of_gpio_quirk_polarity(np, gpios[i].active_high, flags); in of_gpio_try_fixup_polarity()
245 } gpios[] = { in of_gpio_set_polarity_by_property() local
248 { "fsl,imx25-fec", "phy-reset-gpios", "phy-reset-active-high" }, in of_gpio_set_polarity_by_property()
249 { "fsl,imx27-fec", "phy-reset-gpios", "phy-reset-active-high" }, in of_gpio_set_polarity_by_property()
250 { "fsl,imx28-fec", "phy-reset-gpios", "phy-reset-active-high" }, in of_gpio_set_polarity_by_property()
251 { "fsl,imx6q-fec", "phy-reset-gpios", "phy-reset-active-high" }, in of_gpio_set_polarity_by_property()
252 { "fsl,mvf600-fec", "phy-reset-gpios", "phy-reset-active-high" }, in of_gpio_set_polarity_by_property()
253 { "fsl,imx6sx-fec", "phy-reset-gpios", "phy-reset-active-high" }, in of_gpio_set_polarity_by_property()
254 { "fsl,imx6ul-fec", "phy-reset-gpios", "phy-reset-active-high" }, in of_gpio_set_polarity_by_property()
255 { "fsl,imx8mq-fec", "phy-reset-gpios", "phy-reset-active-high" }, in of_gpio_set_polarity_by_property()
256 { "fsl,imx8qm-fec", "phy-reset-gpios", "phy-reset-active-high" }, in of_gpio_set_polarity_by_property()
257 { "fsl,s32v234-fec", "phy-reset-gpios", "phy-reset-active-high" }, in of_gpio_set_polarity_by_property()
260 { "atmel,hsmci", "cd-gpios", "cd-inverted" }, in of_gpio_set_polarity_by_property()
263 { "fsl,imx6q-pcie", "reset-gpio", "reset-gpio-active-high" }, in of_gpio_set_polarity_by_property()
264 { "fsl,imx6sx-pcie", "reset-gpio", "reset-gpio-active-high" }, in of_gpio_set_polarity_by_property()
265 { "fsl,imx6qp-pcie", "reset-gpio", "reset-gpio-active-high" }, in of_gpio_set_polarity_by_property()
266 { "fsl,imx7d-pcie", "reset-gpio", "reset-gpio-active-high" }, in of_gpio_set_polarity_by_property()
267 { "fsl,imx8mq-pcie", "reset-gpio", "reset-gpio-active-high" }, in of_gpio_set_polarity_by_property()
268 { "fsl,imx8mm-pcie", "reset-gpio", "reset-gpio-active-high" }, in of_gpio_set_polarity_by_property()
269 { "fsl,imx8mp-pcie", "reset-gpio", "reset-gpio-active-high" }, in of_gpio_set_polarity_by_property()
274 * presence or absence of "enable-active-high" solely controls in of_gpio_set_polarity_by_property()
279 { "regulator-fixed", "gpios", "enable-active-high" }, in of_gpio_set_polarity_by_property()
280 { "regulator-fixed", "gpio", "enable-active-high" }, in of_gpio_set_polarity_by_property()
281 { "reg-fixed-voltage", "gpios", "enable-active-high" }, in of_gpio_set_polarity_by_property()
282 { "reg-fixed-voltage", "gpio", "enable-active-high" }, in of_gpio_set_polarity_by_property()
285 { "regulator-gpio", "enable-gpio", "enable-active-high" }, in of_gpio_set_polarity_by_property()
286 { "regulator-gpio", "enable-gpios", "enable-active-high" }, in of_gpio_set_polarity_by_property()
297 if (of_device_is_compatible(np->parent, "atmel,hsmci")) { in of_gpio_set_polarity_by_property()
298 np_compat = np->parent; in of_gpio_set_polarity_by_property()
303 for (i = 0; i < ARRAY_SIZE(gpios); i++) { in of_gpio_set_polarity_by_property()
304 if (of_device_is_compatible(np_compat, gpios[i].compatible) && in of_gpio_set_polarity_by_property()
305 !strcmp(propname, gpios[i].gpio_propname)) { in of_gpio_set_polarity_by_property()
307 gpios[i].polarity_propname); in of_gpio_set_polarity_by_property()
326 of_device_is_compatible(np, "reg-fixed-voltage") && in of_gpio_flags_quirks()
327 of_property_read_bool(np, "gpio-open-drain")) { in of_gpio_flags_quirks()
329 pr_info("%s uses legacy open drain flag - update the DTS if you can\n", in of_gpio_flags_quirks()
334 * Legacy handling of SPI active high chip select. If we have a in of_gpio_flags_quirks()
335 * property named "cs-gpios" we need to inspect the child node in of_gpio_flags_quirks()
338 if (IS_ENABLED(CONFIG_SPI_MASTER) && !strcmp(propname, "cs-gpios") && in of_gpio_flags_quirks()
339 of_property_read_bool(np, "cs-gpios")) { in of_gpio_flags_quirks()
350 * SPI children have active low chip selects in of_gpio_flags_quirks()
352 * by just omitting "spi-cs-high" in the in of_gpio_flags_quirks()
357 * and has the "spi-cs-high" set, we get a in of_gpio_flags_quirks()
358 * conflict and the "spi-cs-high" flag will in of_gpio_flags_quirks()
362 "spi-cs-high"); in of_gpio_flags_quirks()
371 /* Legacy handling of stmmac's active-low PHY reset line */ in of_gpio_flags_quirks()
373 !strcmp(propname, "snps,reset-gpio") && in of_gpio_flags_quirks()
374 of_property_read_bool(np, "snps,reset-active-low")) in of_gpio_flags_quirks()
379 * of_get_named_gpiod_flags() - Get a GPIO descriptor and flags for GPIO API
393 struct gpio_chip *chip; in of_get_named_gpiod_flags() local
405 chip = of_find_gpiochip_by_xlate(&gpiospec); in of_get_named_gpiod_flags()
406 if (!chip) { in of_get_named_gpiod_flags()
407 desc = ERR_PTR(-EPROBE_DEFER); in of_get_named_gpiod_flags()
411 desc = of_xlate_and_get_gpiod_flags(chip, &gpiospec, flags); in of_get_named_gpiod_flags()
418 pr_debug("%s: parsed '%s' property of node '%pOF[%d]' - status (%d)\n", in of_get_named_gpiod_flags()
429 * of_get_named_gpio() - Get a GPIO number to use with GPIO API
488 const char *legacy_id; /* NULL - same as con_id */ in of_find_gpio_rename()
497 } gpios[] = { in of_find_gpio_rename() local
499 /* Himax LCD controllers used "gpios-reset" */ in of_find_gpio_rename()
500 { "reset", "gpios-reset", "himax,hx8357" }, in of_find_gpio_rename()
501 { "reset", "gpios-reset", "himax,hx8369" }, in of_find_gpio_rename()
507 { "rtc-data", "gpio-rtc-data", "moxa,moxart-rtc" }, in of_find_gpio_rename()
508 { "rtc-sclk", "gpio-rtc-sclk", "moxa,moxart-rtc" }, in of_find_gpio_rename()
509 { "rtc-reset", "gpio-rtc-reset", "moxa,moxart-rtc" }, in of_find_gpio_rename()
512 { "reset", "reset-n-io", "marvell,nfc-i2c" }, in of_find_gpio_rename()
515 { "reset", "reset-n-io", "marvell,nfc-spi" }, in of_find_gpio_rename()
518 { "reset", "reset-n-io", "marvell,nfc-uart" }, in of_find_gpio_rename()
519 { "reset", "reset-n-io", "mrvl,nfc-uart" }, in of_find_gpio_rename()
523 { "reset", "gpio-reset", "lantiq,pci-xway" }, in of_find_gpio_rename()
529 * "foo-gpios" so we have this special kludge for them. in of_find_gpio_rename()
540 { "reset", "cirrus,gpio-nreset", "cirrus,cs42l56" }, in of_find_gpio_rename()
543 { "i2s1-in-sel-gpio1", NULL, "mediatek,mt2701-cs42448-machine" }, in of_find_gpio_rename()
544 { "i2s1-in-sel-gpio2", NULL, "mediatek,mt2701-cs42448-machine" }, in of_find_gpio_rename()
547 { "reset", "gpio-reset", "ti,tlv320aic3x" }, in of_find_gpio_rename()
548 { "reset", "gpio-reset", "ti,tlv320aic33" }, in of_find_gpio_rename()
549 { "reset", "gpio-reset", "ti,tlv320aic3007" }, in of_find_gpio_rename()
550 { "reset", "gpio-reset", "ti,tlv320aic3104" }, in of_find_gpio_rename()
551 { "reset", "gpio-reset", "ti,tlv320aic3106" }, in of_find_gpio_rename()
557 * "foo-gpios" so we have this special kludge for them. in of_find_gpio_rename()
559 { "miso", "gpio-miso", "spi-gpio" }, in of_find_gpio_rename()
560 { "mosi", "gpio-mosi", "spi-gpio" }, in of_find_gpio_rename()
561 { "sck", "gpio-sck", "spi-gpio" }, in of_find_gpio_rename()
565 * The old Freescale bindings use simply "gpios" as name in of_find_gpio_rename()
566 * for the chip select lines rather than "cs-gpios" like in of_find_gpio_rename()
571 { "cs", "gpios", "fsl,spi" }, in of_find_gpio_rename()
572 { "cs", "gpios", "aeroflexgaisler,spictrl" }, in of_find_gpio_rename()
575 { "cs", "gpios", "ibm,ppc4xx-spi" }, in of_find_gpio_rename()
581 * property without the compulsory "-gpios" suffix. in of_find_gpio_rename()
591 return ERR_PTR(-ENOENT); in of_find_gpio_rename()
593 for (i = 0; i < ARRAY_SIZE(gpios); i++) { in of_find_gpio_rename()
594 if (strcmp(con_id, gpios[i].con_id)) in of_find_gpio_rename()
597 if (gpios[i].compatible && in of_find_gpio_rename()
598 !of_device_is_compatible(np, gpios[i].compatible)) in of_find_gpio_rename()
601 legacy_id = gpios[i].legacy_id ?: gpios[i].con_id; in of_find_gpio_rename()
604 pr_info("%s uses legacy gpio name '%s' instead of '%s-gpios'\n", in of_find_gpio_rename()
610 return ERR_PTR(-ENOENT); in of_find_gpio_rename()
622 return ERR_PTR(-ENOENT); in of_find_mt2701_gpio()
624 if (!of_device_is_compatible(np, "mediatek,mt2701-cs42448-machine")) in of_find_mt2701_gpio()
625 return ERR_PTR(-ENOENT); in of_find_mt2701_gpio()
627 if (!con_id || strcmp(con_id, "i2s1-in-sel")) in of_find_mt2701_gpio()
628 return ERR_PTR(-ENOENT); in of_find_mt2701_gpio()
631 legacy_id = "i2s1-in-sel-gpio1"; in of_find_mt2701_gpio()
633 legacy_id = "i2s1-in-sel-gpio2"; in of_find_mt2701_gpio()
635 return ERR_PTR(-ENOENT); in of_find_mt2701_gpio()
639 pr_info("%s is using legacy gpio name '%s' instead of '%s-gpios'\n", in of_find_mt2701_gpio()
664 /* Try GPIO property "foo-gpios" and "foo-gpio" */ in of_find_gpio()
667 snprintf(prop_name, sizeof(prop_name), "%s-%s", con_id, in of_find_gpio()
692 * of_parse_own_gpio() - Get a GPIO hog descriptor, names and flags for GPIO API
694 * @chip: GPIO chip whose hog is parsed
697 * @lflags: bitmask of gpio_lookup_flags GPIO_* values - returned from
699 * @dflags: gpiod_flags - optional GPIO initialization flags
705 struct gpio_chip *chip, in of_parse_own_gpio() argument
718 chip_np = dev_of_node(&chip->gpiodev->dev); in of_parse_own_gpio()
720 return ERR_PTR(-EINVAL); in of_parse_own_gpio()
726 ret = of_property_read_u32(chip_np, "#gpio-cells", &tmp); in of_parse_own_gpio()
734 ret = of_property_read_u32_index(np, "gpios", idx * tmp + i, in of_parse_own_gpio()
740 desc = of_xlate_and_get_gpiod_flags(chip, &gpiospec, &xlate_flags); in of_parse_own_gpio()
748 else if (of_property_read_bool(np, "output-low")) in of_parse_own_gpio()
750 else if (of_property_read_bool(np, "output-high")) in of_parse_own_gpio()
755 return ERR_PTR(-EINVAL); in of_parse_own_gpio()
758 if (name && of_property_read_string(np, "line-name", name)) in of_parse_own_gpio()
759 *name = np->name; in of_parse_own_gpio()
765 * of_gpiochip_add_hog - Add all hogs in a hog device node
766 * @chip: gpio chip to act on
771 static int of_gpiochip_add_hog(struct gpio_chip *chip, struct device_node *hog) in of_gpiochip_add_hog() argument
781 desc = of_parse_own_gpio(hog, chip, i, &name, &lflags, &dflags); in of_gpiochip_add_hog()
790 desc->hog = hog; in of_gpiochip_add_hog()
798 * of_gpiochip_scan_gpios - Scan gpio-controller for gpio definitions
799 * @chip: gpio chip to act on
805 static int of_gpiochip_scan_gpios(struct gpio_chip *chip) in of_gpiochip_scan_gpios() argument
810 for_each_available_child_of_node(dev_of_node(&chip->gpiodev->dev), np) { in of_gpiochip_scan_gpios()
811 if (!of_property_read_bool(np, "gpio-hog")) in of_gpiochip_scan_gpios()
814 ret = of_gpiochip_add_hog(chip, np); in of_gpiochip_scan_gpios()
828 * of_gpiochip_remove_hog - Remove all hogs in a hog device node
829 * @chip: gpio chip to act on
832 static void of_gpiochip_remove_hog(struct gpio_chip *chip, in of_gpiochip_remove_hog() argument
837 for_each_gpio_desc_with_flag(chip, desc, FLAG_IS_HOGGED) in of_gpiochip_remove_hog()
838 if (desc->hog == hog) in of_gpiochip_remove_hog()
842 static int of_gpiochip_match_node(struct gpio_chip *chip, void *data) in of_gpiochip_match_node() argument
844 return device_match_of_node(&chip->gpiodev->dev, data); in of_gpiochip_match_node()
856 struct gpio_chip *chip; in of_gpio_notify() local
860 * This only supports adding and removing complete gpio-hog nodes. in of_gpio_notify()
861 * Modifying an existing gpio-hog node is not supported (except for in of_gpio_notify()
867 if (!of_property_read_bool(rd->dn, "gpio-hog")) in of_gpio_notify()
870 if (of_node_test_and_set_flag(rd->dn, OF_POPULATED)) in of_gpio_notify()
873 chip = of_find_gpiochip_by_node(rd->dn->parent); in of_gpio_notify()
874 if (chip == NULL) in of_gpio_notify()
877 ret = of_gpiochip_add_hog(chip, rd->dn); in of_gpio_notify()
880 rd->dn); in of_gpio_notify()
881 of_node_clear_flag(rd->dn, OF_POPULATED); in of_gpio_notify()
887 if (!of_node_check_flag(rd->dn, OF_POPULATED)) in of_gpio_notify()
890 chip = of_find_gpiochip_by_node(rd->dn->parent); in of_gpio_notify()
891 if (chip == NULL) in of_gpio_notify()
894 of_gpiochip_remove_hog(chip, rd->dn); in of_gpio_notify()
895 of_node_clear_flag(rd->dn, OF_POPULATED); in of_gpio_notify()
908 * of_gpio_simple_xlate - translate gpiospec to the GPIO number and flags
924 * number and the flags from a single gpio cell -- this is possible, in of_gpio_simple_xlate()
927 if (gc->of_gpio_n_cells < 2) { in of_gpio_simple_xlate()
929 return -EINVAL; in of_gpio_simple_xlate()
932 if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells)) in of_gpio_simple_xlate()
933 return -EINVAL; in of_gpio_simple_xlate()
935 if (gpiospec->args[0] >= gc->ngpio) in of_gpio_simple_xlate()
936 return -EINVAL; in of_gpio_simple_xlate()
939 *flags = gpiospec->args[1]; in of_gpio_simple_xlate()
941 return gpiospec->args[0]; in of_gpio_simple_xlate()
945 #include <linux/gpio/legacy-of-mm-gpiochip.h>
947 * of_mm_gpiochip_add_data - Add memory mapped GPIO chip (bank)
948 * @np: device node of the GPIO chip
955 * - all the callbacks
956 * - of_gpio_n_cells
957 * - of_xlate callback (optional)
960 * - save_regs callback (optional)
964 * to manage GPIOs from the callbacks.
970 int ret = -ENOMEM; in of_mm_gpiochip_add_data()
971 struct gpio_chip *gc = &mm_gc->gc; in of_mm_gpiochip_add_data()
973 gc->label = kasprintf(GFP_KERNEL, "%pOF", np); in of_mm_gpiochip_add_data()
974 if (!gc->label) in of_mm_gpiochip_add_data()
977 mm_gc->regs = of_iomap(np, 0); in of_mm_gpiochip_add_data()
978 if (!mm_gc->regs) in of_mm_gpiochip_add_data()
981 gc->base = -1; in of_mm_gpiochip_add_data()
983 if (mm_gc->save_regs) in of_mm_gpiochip_add_data()
984 mm_gc->save_regs(mm_gc); in of_mm_gpiochip_add_data()
986 fwnode_handle_put(mm_gc->gc.fwnode); in of_mm_gpiochip_add_data()
987 mm_gc->gc.fwnode = fwnode_handle_get(of_fwnode_handle(np)); in of_mm_gpiochip_add_data()
996 iounmap(mm_gc->regs); in of_mm_gpiochip_add_data()
998 kfree(gc->label); in of_mm_gpiochip_add_data()
1000 pr_err("%pOF: GPIO chip registration failed with status %d\n", np, ret); in of_mm_gpiochip_add_data()
1006 * of_mm_gpiochip_remove - Remove memory mapped GPIO chip (bank)
1011 struct gpio_chip *gc = &mm_gc->gc; in of_mm_gpiochip_remove()
1014 iounmap(mm_gc->regs); in of_mm_gpiochip_remove()
1015 kfree(gc->label); in of_mm_gpiochip_remove()
1021 static int of_gpiochip_add_pin_range(struct gpio_chip *chip) in of_gpiochip_add_pin_range() argument
1028 static const char group_names_propname[] = "gpio-ranges-group-names"; in of_gpiochip_add_pin_range()
1031 np = dev_of_node(&chip->gpiodev->dev); in of_gpiochip_add_pin_range()
1038 ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, in of_gpiochip_add_pin_range()
1046 return -EPROBE_DEFER; in of_gpiochip_add_pin_range()
1060 ret = gpiochip_add_pin_range(chip, in of_gpiochip_add_pin_range()
1070 pr_err("%pOF: Illegal gpio-range format.\n", in of_gpiochip_add_pin_range()
1093 ret = gpiochip_add_pingroup_range(chip, pctldev, in of_gpiochip_add_pin_range()
1104 static int of_gpiochip_add_pin_range(struct gpio_chip *chip) { return 0; } in of_gpiochip_add_pin_range() argument
1107 int of_gpiochip_add(struct gpio_chip *chip) in of_gpiochip_add() argument
1112 np = dev_of_node(&chip->gpiodev->dev); in of_gpiochip_add()
1116 if (!chip->of_xlate) { in of_gpiochip_add()
1117 chip->of_gpio_n_cells = 2; in of_gpiochip_add()
1118 chip->of_xlate = of_gpio_simple_xlate; in of_gpiochip_add()
1121 if (chip->of_gpio_n_cells > MAX_PHANDLE_ARGS) in of_gpiochip_add()
1122 return -EINVAL; in of_gpiochip_add()
1124 ret = of_gpiochip_add_pin_range(chip); in of_gpiochip_add()
1130 ret = of_gpiochip_scan_gpios(chip); in of_gpiochip_add()
1137 void of_gpiochip_remove(struct gpio_chip *chip) in of_gpiochip_remove() argument
1139 of_node_put(dev_of_node(&chip->gpiodev->dev)); in of_gpiochip_remove()