1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Airoha AN8855 Switch EFUSE Driver 4 */ 5 6 #include <linux/mod_devicetable.h> 7 #include <linux/module.h> 8 #include <linux/nvmem-provider.h> 9 #include <linux/platform_device.h> 10 #include <linux/regmap.h> 11 12 #define AN8855_EFUSE_CELL 50 13 14 #define AN8855_EFUSE_DATA0 0x1000a500 15 #define AN8855_EFUSE_R50O GENMASK(30, 24) 16 17 static int an8855_efuse_read(void *context, unsigned int offset, 18 void *val, size_t bytes) 19 { 20 struct regmap *regmap = context; 21 22 return regmap_bulk_read(regmap, AN8855_EFUSE_DATA0 + offset, 23 val, bytes / sizeof(u32)); 24 } 25 26 static int an8855_efuse_probe(struct platform_device *pdev) 27 { 28 struct nvmem_config an8855_nvmem_config = { 29 .name = "an8855-efuse", 30 .size = AN8855_EFUSE_CELL * sizeof(u32), 31 .stride = sizeof(u32), 32 .word_size = sizeof(u32), 33 .reg_read = an8855_efuse_read, 34 }; 35 struct device *dev = &pdev->dev; 36 struct nvmem_device *nvmem; 37 struct regmap *regmap; 38 39 /* Assign NVMEM priv to MFD regmap */ 40 regmap = dev_get_regmap(dev->parent, NULL); 41 if (!regmap) 42 return -ENOENT; 43 44 an8855_nvmem_config.priv = regmap; 45 an8855_nvmem_config.dev = dev; 46 nvmem = devm_nvmem_register(dev, &an8855_nvmem_config); 47 48 return PTR_ERR_OR_ZERO(nvmem); 49 } 50 51 static const struct of_device_id an8855_efuse_of_match[] = { 52 { .compatible = "airoha,an8855-efuse", }, 53 { /* sentinel */ } 54 }; 55 MODULE_DEVICE_TABLE(of, an8855_efuse_of_match); 56 57 static struct platform_driver an8855_efuse_driver = { 58 .probe = an8855_efuse_probe, 59 .driver = { 60 .name = "an8855-efuse", 61 .of_match_table = an8855_efuse_of_match, 62 }, 63 }; 64 module_platform_driver(an8855_efuse_driver); 65 66 MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>"); 67 MODULE_DESCRIPTION("Driver for AN8855 Switch EFUSE"); 68 MODULE_LICENSE("GPL"); 69