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