1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Delta TN48M CPLD GPIO driver 4 * 5 * Copyright (C) 2021 Sartura Ltd. 6 * 7 * Author: Robert Marko <robert.marko@sartura.hr> 8 */ 9 10 #include <linux/device.h> 11 #include <linux/gpio/driver.h> 12 #include <linux/gpio/regmap.h> 13 #include <linux/module.h> 14 #include <linux/platform_device.h> 15 #include <linux/regmap.h> 16 17 enum tn48m_gpio_type { 18 TN48M_GP0 = 1, 19 TN48M_GPI, 20 }; 21 22 struct tn48m_gpio_config { 23 int ngpio; 24 int ngpio_per_reg; 25 enum tn48m_gpio_type type; 26 }; 27 28 static const struct tn48m_gpio_config tn48m_gpo_config = { 29 .ngpio = 4, 30 .ngpio_per_reg = 4, 31 .type = TN48M_GP0, 32 }; 33 34 static const struct tn48m_gpio_config tn48m_gpi_config = { 35 .ngpio = 4, 36 .ngpio_per_reg = 4, 37 .type = TN48M_GPI, 38 }; 39 40 static int tn48m_gpio_probe(struct platform_device *pdev) 41 { 42 const struct tn48m_gpio_config *gpio_config; 43 struct gpio_regmap_config config = {}; 44 struct regmap *regmap; 45 u32 base; 46 int ret; 47 48 if (!pdev->dev.parent) 49 return -ENODEV; 50 51 gpio_config = device_get_match_data(&pdev->dev); 52 if (!gpio_config) 53 return -ENODEV; 54 55 ret = device_property_read_u32(&pdev->dev, "reg", &base); 56 if (ret) 57 return ret; 58 59 regmap = dev_get_regmap(pdev->dev.parent, NULL); 60 if (!regmap) 61 return -ENODEV; 62 63 config.regmap = regmap; 64 config.parent = &pdev->dev; 65 config.ngpio = gpio_config->ngpio; 66 config.ngpio_per_reg = gpio_config->ngpio_per_reg; 67 switch (gpio_config->type) { 68 case TN48M_GP0: 69 config.reg_set_base = base; 70 break; 71 case TN48M_GPI: 72 config.reg_dat_base = base; 73 break; 74 default: 75 return -EINVAL; 76 } 77 78 return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(&pdev->dev, &config)); 79 } 80 81 static const struct of_device_id tn48m_gpio_of_match[] = { 82 { .compatible = "delta,tn48m-gpo", .data = &tn48m_gpo_config }, 83 { .compatible = "delta,tn48m-gpi", .data = &tn48m_gpi_config }, 84 { } 85 }; 86 MODULE_DEVICE_TABLE(of, tn48m_gpio_of_match); 87 88 static struct platform_driver tn48m_gpio_driver = { 89 .driver = { 90 .name = "delta-tn48m-gpio", 91 .of_match_table = tn48m_gpio_of_match, 92 }, 93 .probe = tn48m_gpio_probe, 94 }; 95 module_platform_driver(tn48m_gpio_driver); 96 97 MODULE_AUTHOR("Robert Marko <robert.marko@sartura.hr>"); 98 MODULE_DESCRIPTION("Delta TN48M CPLD GPIO driver"); 99 MODULE_LICENSE("GPL"); 100