1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * UP Board FPGA driver. 4 * 5 * FPGA provides more GPIO driving power, LEDS and pin mux function. 6 * 7 * Copyright (c) AAEON. All rights reserved. 8 * Copyright (C) 2024 Bootlin 9 * 10 * Author: Gary Wang <garywang@aaeon.com.tw> 11 * Author: Thomas Richard <thomas.richard@bootlin.com> 12 */ 13 14 #include <linux/bitfield.h> 15 #include <linux/device.h> 16 #include <linux/err.h> 17 #include <linux/gpio/consumer.h> 18 #include <linux/mfd/core.h> 19 #include <linux/mfd/upboard-fpga.h> 20 #include <linux/module.h> 21 #include <linux/mod_devicetable.h> 22 #include <linux/platform_device.h> 23 #include <linux/property.h> 24 #include <linux/regmap.h> 25 #include <linux/sysfs.h> 26 27 #define UPBOARD_AAEON_MANUFACTURER_ID 0x01 28 #define UPBOARD_MANUFACTURER_ID_MASK GENMASK(7, 0) 29 30 #define UPBOARD_ADDRESS_SIZE 7 31 #define UPBOARD_REGISTER_SIZE 16 32 33 #define UPBOARD_READ_FLAG BIT(UPBOARD_ADDRESS_SIZE) 34 35 #define UPBOARD_FW_ID_MAJOR_SUPPORTED 0x0 36 37 #define UPBOARD_FW_ID_BUILD_MASK GENMASK(15, 12) 38 #define UPBOARD_FW_ID_MAJOR_MASK GENMASK(11, 8) 39 #define UPBOARD_FW_ID_MINOR_MASK GENMASK(7, 4) 40 #define UPBOARD_FW_ID_PATCH_MASK GENMASK(3, 0) 41 42 static int upboard_fpga_read(void *context, unsigned int reg, unsigned int *val) 43 { 44 struct upboard_fpga *fpga = context; 45 int i; 46 47 /* Clear to start new transaction */ 48 gpiod_set_value(fpga->clear_gpio, 0); 49 gpiod_set_value(fpga->clear_gpio, 1); 50 51 reg |= UPBOARD_READ_FLAG; 52 53 /* Send clock and addr from strobe & datain pins */ 54 for (i = UPBOARD_ADDRESS_SIZE; i >= 0; i--) { 55 gpiod_set_value(fpga->strobe_gpio, 0); 56 gpiod_set_value(fpga->datain_gpio, !!(reg & BIT(i))); 57 gpiod_set_value(fpga->strobe_gpio, 1); 58 } 59 60 gpiod_set_value(fpga->strobe_gpio, 0); 61 *val = 0; 62 63 /* Read data from dataout pin */ 64 for (i = UPBOARD_REGISTER_SIZE - 1; i >= 0; i--) { 65 gpiod_set_value(fpga->strobe_gpio, 1); 66 gpiod_set_value(fpga->strobe_gpio, 0); 67 *val |= gpiod_get_value(fpga->dataout_gpio) << i; 68 } 69 70 gpiod_set_value(fpga->strobe_gpio, 1); 71 72 return 0; 73 } 74 75 static int upboard_fpga_write(void *context, unsigned int reg, unsigned int val) 76 { 77 struct upboard_fpga *fpga = context; 78 int i; 79 80 /* Clear to start new transcation */ 81 gpiod_set_value(fpga->clear_gpio, 0); 82 gpiod_set_value(fpga->clear_gpio, 1); 83 84 /* Send clock and addr from strobe & datain pins */ 85 for (i = UPBOARD_ADDRESS_SIZE; i >= 0; i--) { 86 gpiod_set_value(fpga->strobe_gpio, 0); 87 gpiod_set_value(fpga->datain_gpio, !!(reg & BIT(i))); 88 gpiod_set_value(fpga->strobe_gpio, 1); 89 } 90 91 gpiod_set_value(fpga->strobe_gpio, 0); 92 93 /* Write data to datain pin */ 94 for (i = UPBOARD_REGISTER_SIZE - 1; i >= 0; i--) { 95 gpiod_set_value(fpga->datain_gpio, !!(val & BIT(i))); 96 gpiod_set_value(fpga->strobe_gpio, 1); 97 gpiod_set_value(fpga->strobe_gpio, 0); 98 } 99 100 gpiod_set_value(fpga->strobe_gpio, 1); 101 102 return 0; 103 } 104 105 static const struct regmap_range upboard_up_readable_ranges[] = { 106 regmap_reg_range(UPBOARD_REG_PLATFORM_ID, UPBOARD_REG_FIRMWARE_ID), 107 regmap_reg_range(UPBOARD_REG_FUNC_EN0, UPBOARD_REG_FUNC_EN0), 108 regmap_reg_range(UPBOARD_REG_GPIO_EN0, UPBOARD_REG_GPIO_EN1), 109 regmap_reg_range(UPBOARD_REG_GPIO_DIR0, UPBOARD_REG_GPIO_DIR1), 110 }; 111 112 static const struct regmap_range upboard_up_writable_ranges[] = { 113 regmap_reg_range(UPBOARD_REG_FUNC_EN0, UPBOARD_REG_FUNC_EN0), 114 regmap_reg_range(UPBOARD_REG_GPIO_EN0, UPBOARD_REG_GPIO_EN1), 115 regmap_reg_range(UPBOARD_REG_GPIO_DIR0, UPBOARD_REG_GPIO_DIR1), 116 }; 117 118 static const struct regmap_access_table upboard_up_readable_table = { 119 .yes_ranges = upboard_up_readable_ranges, 120 .n_yes_ranges = ARRAY_SIZE(upboard_up_readable_ranges), 121 }; 122 123 static const struct regmap_access_table upboard_up_writable_table = { 124 .yes_ranges = upboard_up_writable_ranges, 125 .n_yes_ranges = ARRAY_SIZE(upboard_up_writable_ranges), 126 }; 127 128 static const struct regmap_config upboard_up_regmap_config = { 129 .reg_bits = UPBOARD_ADDRESS_SIZE, 130 .val_bits = UPBOARD_REGISTER_SIZE, 131 .max_register = UPBOARD_REG_MAX, 132 .reg_read = upboard_fpga_read, 133 .reg_write = upboard_fpga_write, 134 .fast_io = false, 135 .cache_type = REGCACHE_NONE, 136 .rd_table = &upboard_up_readable_table, 137 .wr_table = &upboard_up_writable_table, 138 }; 139 140 static const struct regmap_range upboard_up2_readable_ranges[] = { 141 regmap_reg_range(UPBOARD_REG_PLATFORM_ID, UPBOARD_REG_FIRMWARE_ID), 142 regmap_reg_range(UPBOARD_REG_FUNC_EN0, UPBOARD_REG_FUNC_EN1), 143 regmap_reg_range(UPBOARD_REG_GPIO_EN0, UPBOARD_REG_GPIO_EN2), 144 regmap_reg_range(UPBOARD_REG_GPIO_DIR0, UPBOARD_REG_GPIO_DIR2), 145 }; 146 147 static const struct regmap_range upboard_up2_writable_ranges[] = { 148 regmap_reg_range(UPBOARD_REG_FUNC_EN0, UPBOARD_REG_FUNC_EN1), 149 regmap_reg_range(UPBOARD_REG_GPIO_EN0, UPBOARD_REG_GPIO_EN2), 150 regmap_reg_range(UPBOARD_REG_GPIO_DIR0, UPBOARD_REG_GPIO_DIR2), 151 }; 152 153 static const struct regmap_access_table upboard_up2_readable_table = { 154 .yes_ranges = upboard_up2_readable_ranges, 155 .n_yes_ranges = ARRAY_SIZE(upboard_up2_readable_ranges), 156 }; 157 158 static const struct regmap_access_table upboard_up2_writable_table = { 159 .yes_ranges = upboard_up2_writable_ranges, 160 .n_yes_ranges = ARRAY_SIZE(upboard_up2_writable_ranges), 161 }; 162 163 static const struct regmap_config upboard_up2_regmap_config = { 164 .reg_bits = UPBOARD_ADDRESS_SIZE, 165 .val_bits = UPBOARD_REGISTER_SIZE, 166 .max_register = UPBOARD_REG_MAX, 167 .reg_read = upboard_fpga_read, 168 .reg_write = upboard_fpga_write, 169 .fast_io = false, 170 .cache_type = REGCACHE_NONE, 171 .rd_table = &upboard_up2_readable_table, 172 .wr_table = &upboard_up2_writable_table, 173 }; 174 175 static const struct mfd_cell upboard_up_mfd_cells[] = { 176 { .name = "upboard-pinctrl" }, 177 { .name = "upboard-leds" }, 178 }; 179 180 static const struct upboard_fpga_data upboard_up_fpga_data = { 181 .type = UPBOARD_UP_FPGA, 182 .regmap_config = &upboard_up_regmap_config, 183 }; 184 185 static const struct upboard_fpga_data upboard_up2_fpga_data = { 186 .type = UPBOARD_UP2_FPGA, 187 .regmap_config = &upboard_up2_regmap_config, 188 }; 189 190 static int upboard_fpga_gpio_init(struct upboard_fpga *fpga) 191 { 192 fpga->enable_gpio = devm_gpiod_get(fpga->dev, "enable", GPIOD_ASIS); 193 if (IS_ERR(fpga->enable_gpio)) 194 return PTR_ERR(fpga->enable_gpio); 195 196 fpga->clear_gpio = devm_gpiod_get(fpga->dev, "clear", GPIOD_OUT_LOW); 197 if (IS_ERR(fpga->clear_gpio)) 198 return PTR_ERR(fpga->clear_gpio); 199 200 fpga->strobe_gpio = devm_gpiod_get(fpga->dev, "strobe", GPIOD_OUT_LOW); 201 if (IS_ERR(fpga->strobe_gpio)) 202 return PTR_ERR(fpga->strobe_gpio); 203 204 fpga->datain_gpio = devm_gpiod_get(fpga->dev, "datain", GPIOD_OUT_LOW); 205 if (IS_ERR(fpga->datain_gpio)) 206 return PTR_ERR(fpga->datain_gpio); 207 208 fpga->dataout_gpio = devm_gpiod_get(fpga->dev, "dataout", GPIOD_IN); 209 if (IS_ERR(fpga->dataout_gpio)) 210 return PTR_ERR(fpga->dataout_gpio); 211 212 gpiod_set_value(fpga->enable_gpio, 1); 213 214 return 0; 215 } 216 217 static int upboard_fpga_get_firmware_version(struct upboard_fpga *fpga) 218 { 219 unsigned int platform_id, manufacturer_id; 220 int ret; 221 222 if (!fpga) 223 return -ENOMEM; 224 225 ret = regmap_read(fpga->regmap, UPBOARD_REG_PLATFORM_ID, &platform_id); 226 if (ret) 227 return ret; 228 229 manufacturer_id = platform_id & UPBOARD_MANUFACTURER_ID_MASK; 230 if (manufacturer_id != UPBOARD_AAEON_MANUFACTURER_ID) 231 return dev_err_probe(fpga->dev, -ENODEV, 232 "driver not compatible with custom FPGA FW from manufacturer id %#02x.", 233 manufacturer_id); 234 235 ret = regmap_read(fpga->regmap, UPBOARD_REG_FIRMWARE_ID, &fpga->firmware_version); 236 if (ret) 237 return ret; 238 239 if (FIELD_GET(UPBOARD_FW_ID_MAJOR_MASK, fpga->firmware_version) != 240 UPBOARD_FW_ID_MAJOR_SUPPORTED) 241 return dev_err_probe(fpga->dev, -ENODEV, 242 "unsupported FPGA FW v%lu.%lu.%lu build %#02lx", 243 FIELD_GET(UPBOARD_FW_ID_MAJOR_MASK, fpga->firmware_version), 244 FIELD_GET(UPBOARD_FW_ID_MINOR_MASK, fpga->firmware_version), 245 FIELD_GET(UPBOARD_FW_ID_PATCH_MASK, fpga->firmware_version), 246 FIELD_GET(UPBOARD_FW_ID_BUILD_MASK, fpga->firmware_version)); 247 return 0; 248 } 249 250 static ssize_t upboard_fpga_version_show(struct device *dev, struct device_attribute *attr, 251 char *buf) 252 { 253 struct upboard_fpga *fpga = dev_get_drvdata(dev); 254 255 return sysfs_emit(buf, "FPGA FW v%lu.%lu.%lu build %#02lx\n", 256 FIELD_GET(UPBOARD_FW_ID_MAJOR_MASK, fpga->firmware_version), 257 FIELD_GET(UPBOARD_FW_ID_MINOR_MASK, fpga->firmware_version), 258 FIELD_GET(UPBOARD_FW_ID_PATCH_MASK, fpga->firmware_version), 259 FIELD_GET(UPBOARD_FW_ID_BUILD_MASK, fpga->firmware_version)); 260 } 261 262 static DEVICE_ATTR_RO(upboard_fpga_version); 263 264 static struct attribute *upboard_fpga_attrs[] = { 265 &dev_attr_upboard_fpga_version.attr, 266 NULL 267 }; 268 269 ATTRIBUTE_GROUPS(upboard_fpga); 270 271 static int upboard_fpga_probe(struct platform_device *pdev) 272 { 273 struct device *dev = &pdev->dev; 274 struct upboard_fpga *fpga; 275 int ret; 276 277 fpga = devm_kzalloc(dev, sizeof(*fpga), GFP_KERNEL); 278 if (!fpga) 279 return -ENOMEM; 280 281 fpga->fpga_data = device_get_match_data(dev); 282 283 fpga->dev = dev; 284 285 platform_set_drvdata(pdev, fpga); 286 287 fpga->regmap = devm_regmap_init(dev, NULL, fpga, fpga->fpga_data->regmap_config); 288 if (IS_ERR(fpga->regmap)) 289 return PTR_ERR(fpga->regmap); 290 291 ret = upboard_fpga_gpio_init(fpga); 292 if (ret) 293 return dev_err_probe(dev, ret, "Failed to initialize FPGA common GPIOs"); 294 295 ret = upboard_fpga_get_firmware_version(fpga); 296 if (ret) 297 return ret; 298 299 return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, upboard_up_mfd_cells, 300 ARRAY_SIZE(upboard_up_mfd_cells), NULL, 0, NULL); 301 } 302 303 static const struct acpi_device_id upboard_fpga_acpi_match[] = { 304 { "AANT0F01", (kernel_ulong_t)&upboard_up2_fpga_data }, 305 { "AANT0F04", (kernel_ulong_t)&upboard_up_fpga_data }, 306 {} 307 }; 308 MODULE_DEVICE_TABLE(acpi, upboard_fpga_acpi_match); 309 310 static struct platform_driver upboard_fpga_driver = { 311 .driver = { 312 .name = "upboard-fpga", 313 .acpi_match_table = upboard_fpga_acpi_match, 314 .dev_groups = upboard_fpga_groups, 315 }, 316 .probe = upboard_fpga_probe, 317 }; 318 319 module_platform_driver(upboard_fpga_driver); 320 321 MODULE_AUTHOR("Gary Wang <garywang@aaeon.com.tw>"); 322 MODULE_AUTHOR("Thomas Richard <thomas.richard@bootlin.com>"); 323 MODULE_DESCRIPTION("UP Board FPGA driver"); 324 MODULE_LICENSE("GPL"); 325