0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/bitops.h>
0009 #include <linux/device.h>
0010 #include <linux/io.h>
0011 #include <linux/ioport.h>
0012 #include <linux/mod_devicetable.h>
0013 #include <linux/module.h>
0014 #include <linux/pinctrl/pinconf.h>
0015 #include <linux/pinctrl/pinconf-generic.h>
0016 #include <linux/pinctrl/pinctrl.h>
0017 #include <linux/platform_device.h>
0018
0019 #define DA850_PUPD_ENA 0x00
0020 #define DA850_PUPD_SEL 0x04
0021
0022 struct da850_pupd_data {
0023 void __iomem *base;
0024 struct pinctrl_desc desc;
0025 struct pinctrl_dev *pinctrl;
0026 };
0027
0028 static const char * const da850_pupd_group_names[] = {
0029 "cp0", "cp1", "cp2", "cp3", "cp4", "cp5", "cp6", "cp7",
0030 "cp8", "cp9", "cp10", "cp11", "cp12", "cp13", "cp14", "cp15",
0031 "cp16", "cp17", "cp18", "cp19", "cp20", "cp21", "cp22", "cp23",
0032 "cp24", "cp25", "cp26", "cp27", "cp28", "cp29", "cp30", "cp31",
0033 };
0034
0035 static int da850_pupd_get_groups_count(struct pinctrl_dev *pctldev)
0036 {
0037 return ARRAY_SIZE(da850_pupd_group_names);
0038 }
0039
0040 static const char *da850_pupd_get_group_name(struct pinctrl_dev *pctldev,
0041 unsigned int selector)
0042 {
0043 return da850_pupd_group_names[selector];
0044 }
0045
0046 static int da850_pupd_get_group_pins(struct pinctrl_dev *pctldev,
0047 unsigned int selector,
0048 const unsigned int **pins,
0049 unsigned int *num_pins)
0050 {
0051 *num_pins = 0;
0052
0053 return 0;
0054 }
0055
0056 static const struct pinctrl_ops da850_pupd_pctlops = {
0057 .get_groups_count = da850_pupd_get_groups_count,
0058 .get_group_name = da850_pupd_get_group_name,
0059 .get_group_pins = da850_pupd_get_group_pins,
0060 .dt_node_to_map = pinconf_generic_dt_node_to_map_group,
0061 .dt_free_map = pinconf_generic_dt_free_map,
0062 };
0063
0064 static int da850_pupd_pin_config_group_get(struct pinctrl_dev *pctldev,
0065 unsigned int selector,
0066 unsigned long *config)
0067 {
0068 struct da850_pupd_data *data = pinctrl_dev_get_drvdata(pctldev);
0069 enum pin_config_param param = pinconf_to_config_param(*config);
0070 u32 val;
0071 u16 arg;
0072
0073 val = readl(data->base + DA850_PUPD_ENA);
0074 arg = !!(~val & BIT(selector));
0075
0076 switch (param) {
0077 case PIN_CONFIG_BIAS_DISABLE:
0078 break;
0079 case PIN_CONFIG_BIAS_PULL_UP:
0080 case PIN_CONFIG_BIAS_PULL_DOWN:
0081 if (arg) {
0082
0083 arg = 0;
0084 break;
0085 }
0086 val = readl(data->base + DA850_PUPD_SEL);
0087 if (param == PIN_CONFIG_BIAS_PULL_DOWN)
0088 val = ~val;
0089 arg = !!(val & BIT(selector));
0090 break;
0091 default:
0092 return -EINVAL;
0093 }
0094
0095 *config = pinconf_to_config_packed(param, arg);
0096
0097 return 0;
0098 }
0099
0100 static int da850_pupd_pin_config_group_set(struct pinctrl_dev *pctldev,
0101 unsigned int selector,
0102 unsigned long *configs,
0103 unsigned int num_configs)
0104 {
0105 struct da850_pupd_data *data = pinctrl_dev_get_drvdata(pctldev);
0106 u32 ena, sel;
0107 enum pin_config_param param;
0108 int i;
0109
0110 ena = readl(data->base + DA850_PUPD_ENA);
0111 sel = readl(data->base + DA850_PUPD_SEL);
0112
0113 for (i = 0; i < num_configs; i++) {
0114 param = pinconf_to_config_param(configs[i]);
0115
0116 switch (param) {
0117 case PIN_CONFIG_BIAS_DISABLE:
0118 ena &= ~BIT(selector);
0119 break;
0120 case PIN_CONFIG_BIAS_PULL_UP:
0121 ena |= BIT(selector);
0122 sel |= BIT(selector);
0123 break;
0124 case PIN_CONFIG_BIAS_PULL_DOWN:
0125 ena |= BIT(selector);
0126 sel &= ~BIT(selector);
0127 break;
0128 default:
0129 return -EINVAL;
0130 }
0131 }
0132
0133 writel(sel, data->base + DA850_PUPD_SEL);
0134 writel(ena, data->base + DA850_PUPD_ENA);
0135
0136 return 0;
0137 }
0138
0139 static const struct pinconf_ops da850_pupd_confops = {
0140 .is_generic = true,
0141 .pin_config_group_get = da850_pupd_pin_config_group_get,
0142 .pin_config_group_set = da850_pupd_pin_config_group_set,
0143 };
0144
0145 static int da850_pupd_probe(struct platform_device *pdev)
0146 {
0147 struct device *dev = &pdev->dev;
0148 struct da850_pupd_data *data;
0149
0150 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
0151 if (!data)
0152 return -ENOMEM;
0153
0154 data->base = devm_platform_ioremap_resource(pdev, 0);
0155 if (IS_ERR(data->base)) {
0156 dev_err(dev, "Could not map resource\n");
0157 return PTR_ERR(data->base);
0158 }
0159
0160 data->desc.name = dev_name(dev);
0161 data->desc.pctlops = &da850_pupd_pctlops;
0162 data->desc.confops = &da850_pupd_confops;
0163 data->desc.owner = THIS_MODULE;
0164
0165 data->pinctrl = devm_pinctrl_register(dev, &data->desc, data);
0166 if (IS_ERR(data->pinctrl)) {
0167 dev_err(dev, "Failed to register pinctrl\n");
0168 return PTR_ERR(data->pinctrl);
0169 }
0170
0171 platform_set_drvdata(pdev, data);
0172
0173 return 0;
0174 }
0175
0176 static int da850_pupd_remove(struct platform_device *pdev)
0177 {
0178 return 0;
0179 }
0180
0181 static const struct of_device_id da850_pupd_of_match[] = {
0182 { .compatible = "ti,da850-pupd" },
0183 { }
0184 };
0185 MODULE_DEVICE_TABLE(of, da850_pupd_of_match);
0186
0187 static struct platform_driver da850_pupd_driver = {
0188 .driver = {
0189 .name = "ti-da850-pupd",
0190 .of_match_table = da850_pupd_of_match,
0191 },
0192 .probe = da850_pupd_probe,
0193 .remove = da850_pupd_remove,
0194 };
0195 module_platform_driver(da850_pupd_driver);
0196
0197 MODULE_AUTHOR("David Lechner <david@lechnology.com>");
0198 MODULE_DESCRIPTION("TI DA850/OMAP-L138/AM18XX pullup/pulldown configuration");
0199 MODULE_LICENSE("GPL");