1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Layerscape GPIO QIXIS FPGA driver 4 * 5 * Copyright 2025 NXP 6 */ 7 8 #include <linux/device.h> 9 #include <linux/gpio/driver.h> 10 #include <linux/gpio/regmap.h> 11 #include <linux/kernel.h> 12 #include <linux/mod_devicetable.h> 13 #include <linux/module.h> 14 #include <linux/platform_device.h> 15 #include <linux/regmap.h> 16 17 struct qixis_cpld_gpio_config { 18 u64 output_lines; 19 }; 20 21 static const struct qixis_cpld_gpio_config lx2160ardb_sfp_cfg = { 22 .output_lines = BIT(0), 23 }; 24 25 static const struct qixis_cpld_gpio_config ls1046aqds_stat_pres2_cfg = { 26 .output_lines = 0x0, 27 }; 28 29 static const struct regmap_config regmap_config_8r_8v = { 30 .reg_bits = 8, 31 .val_bits = 8, 32 }; 33 34 static int qixis_cpld_gpio_probe(struct platform_device *pdev) 35 { 36 DECLARE_BITMAP(fixed_direction_output, 8); 37 const struct qixis_cpld_gpio_config *cfg; 38 struct gpio_regmap_config config = {0}; 39 struct regmap *regmap; 40 void __iomem *reg; 41 u32 base; 42 int ret; 43 44 if (!pdev->dev.parent) 45 return -ENODEV; 46 47 cfg = device_get_match_data(&pdev->dev); 48 49 ret = device_property_read_u32(&pdev->dev, "reg", &base); 50 if (ret) 51 return ret; 52 53 regmap = dev_get_regmap(pdev->dev.parent, NULL); 54 if (!regmap) { 55 /* In case there is no regmap configured by the parent device, 56 * create our own from the MMIO space. 57 */ 58 reg = devm_platform_ioremap_resource(pdev, 0); 59 if (IS_ERR(reg)) 60 return PTR_ERR(reg); 61 62 regmap = devm_regmap_init_mmio(&pdev->dev, reg, ®map_config_8r_8v); 63 if (!regmap) 64 return -ENODEV; 65 66 /* In this case, the offset of our register is 0 inside the 67 * regmap area that we just created. 68 */ 69 base = 0; 70 } 71 config.reg_dat_base = GPIO_REGMAP_ADDR(base); 72 config.reg_set_base = GPIO_REGMAP_ADDR(base); 73 74 config.drvdata = (void *)cfg; 75 config.regmap = regmap; 76 config.parent = &pdev->dev; 77 config.ngpio_per_reg = 8; 78 config.ngpio = 8; 79 80 bitmap_from_u64(fixed_direction_output, cfg->output_lines); 81 config.fixed_direction_output = fixed_direction_output; 82 83 return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(&pdev->dev, &config)); 84 } 85 86 static const struct of_device_id qixis_cpld_gpio_of_match[] = { 87 { 88 .compatible = "fsl,lx2160ardb-fpga-gpio-sfp", 89 .data = &lx2160ardb_sfp_cfg, 90 }, 91 { 92 .compatible = "fsl,ls1046aqds-fpga-gpio-stat-pres2", 93 .data = &ls1046aqds_stat_pres2_cfg, 94 }, 95 96 {} 97 }; 98 MODULE_DEVICE_TABLE(of, qixis_cpld_gpio_of_match); 99 100 static struct platform_driver qixis_cpld_gpio_driver = { 101 .probe = qixis_cpld_gpio_probe, 102 .driver = { 103 .name = "gpio-qixis-cpld", 104 .of_match_table = qixis_cpld_gpio_of_match, 105 }, 106 }; 107 module_platform_driver(qixis_cpld_gpio_driver); 108 109 MODULE_LICENSE("GPL"); 110 MODULE_AUTHOR("Ioana Ciornei <ioana.ciornei@nxp.com>"); 111 MODULE_DESCRIPTION("Layerscape GPIO QIXIS FPGA driver"); 112