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