1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <linux/iopoll.h> 4 #include <linux/module.h> 5 #include <linux/nvmem-provider.h> 6 #include <linux/of.h> 7 #include <linux/platform_device.h> 8 9 #define OTP_OTP_PWR_DN(t) (t + 0x00) 10 #define OTP_OTP_PWR_DN_OTP_PWRDN_N BIT(0) 11 #define OTP_OTP_ADDR_HI(t) (t + 0x04) 12 #define OTP_OTP_ADDR_LO(t) (t + 0x08) 13 #define OTP_OTP_PRGM_DATA(t) (t + 0x10) 14 #define OTP_OTP_PRGM_MODE(t) (t + 0x14) 15 #define OTP_OTP_PRGM_MODE_OTP_PGM_MODE_BYTE BIT(0) 16 #define OTP_OTP_RD_DATA(t) (t + 0x18) 17 #define OTP_OTP_FUNC_CMD(t) (t + 0x20) 18 #define OTP_OTP_FUNC_CMD_OTP_PROGRAM BIT(1) 19 #define OTP_OTP_FUNC_CMD_OTP_READ BIT(0) 20 #define OTP_OTP_CMD_GO(t) (t + 0x28) 21 #define OTP_OTP_CMD_GO_OTP_GO BIT(0) 22 #define OTP_OTP_PASS_FAIL(t) (t + 0x2c) 23 #define OTP_OTP_PASS_FAIL_OTP_READ_PROHIBITED BIT(3) 24 #define OTP_OTP_PASS_FAIL_OTP_WRITE_PROHIBITED BIT(2) 25 #define OTP_OTP_PASS_FAIL_OTP_FAIL BIT(0) 26 #define OTP_OTP_STATUS(t) (t + 0x30) 27 #define OTP_OTP_STATUS_OTP_CPUMPEN BIT(1) 28 #define OTP_OTP_STATUS_OTP_BUSY BIT(0) 29 30 #define OTP_MEM_SIZE 8192 31 #define OTP_SLEEP_US 10 32 #define OTP_TIMEOUT_US 500000 33 34 struct lan9662_otp { 35 struct device *dev; 36 void __iomem *base; 37 }; 38 39 static bool lan9662_otp_wait_flag_clear(void __iomem *reg, u32 flag) 40 { 41 u32 val; 42 43 return readl_poll_timeout(reg, val, !(val & flag), 44 OTP_SLEEP_US, OTP_TIMEOUT_US); 45 } 46 47 static int lan9662_otp_power(struct lan9662_otp *otp, bool up) 48 { 49 void __iomem *pwrdn = OTP_OTP_PWR_DN(otp->base); 50 51 if (up) { 52 writel(readl(pwrdn) & ~OTP_OTP_PWR_DN_OTP_PWRDN_N, pwrdn); 53 if (lan9662_otp_wait_flag_clear(OTP_OTP_STATUS(otp->base), 54 OTP_OTP_STATUS_OTP_CPUMPEN)) 55 return -ETIMEDOUT; 56 } else { 57 writel(readl(pwrdn) | OTP_OTP_PWR_DN_OTP_PWRDN_N, pwrdn); 58 } 59 60 return 0; 61 } 62 63 static int lan9662_otp_execute(struct lan9662_otp *otp) 64 { 65 if (lan9662_otp_wait_flag_clear(OTP_OTP_CMD_GO(otp->base), 66 OTP_OTP_CMD_GO_OTP_GO)) 67 return -ETIMEDOUT; 68 69 if (lan9662_otp_wait_flag_clear(OTP_OTP_STATUS(otp->base), 70 OTP_OTP_STATUS_OTP_BUSY)) 71 return -ETIMEDOUT; 72 73 return 0; 74 } 75 76 static void lan9662_otp_set_address(struct lan9662_otp *otp, u32 offset) 77 { 78 writel(0xff & (offset >> 8), OTP_OTP_ADDR_HI(otp->base)); 79 writel(0xff & offset, OTP_OTP_ADDR_LO(otp->base)); 80 } 81 82 static int lan9662_otp_read_byte(struct lan9662_otp *otp, u32 offset, u8 *dst) 83 { 84 u32 pass; 85 int rc; 86 87 lan9662_otp_set_address(otp, offset); 88 writel(OTP_OTP_FUNC_CMD_OTP_READ, OTP_OTP_FUNC_CMD(otp->base)); 89 writel(OTP_OTP_CMD_GO_OTP_GO, OTP_OTP_CMD_GO(otp->base)); 90 rc = lan9662_otp_execute(otp); 91 if (!rc) { 92 pass = readl(OTP_OTP_PASS_FAIL(otp->base)); 93 if (pass & OTP_OTP_PASS_FAIL_OTP_READ_PROHIBITED) 94 return -EACCES; 95 *dst = (u8) readl(OTP_OTP_RD_DATA(otp->base)); 96 } 97 return rc; 98 } 99 100 static int lan9662_otp_write_byte(struct lan9662_otp *otp, u32 offset, u8 data) 101 { 102 u32 pass; 103 int rc; 104 105 lan9662_otp_set_address(otp, offset); 106 writel(OTP_OTP_PRGM_MODE_OTP_PGM_MODE_BYTE, OTP_OTP_PRGM_MODE(otp->base)); 107 writel(data, OTP_OTP_PRGM_DATA(otp->base)); 108 writel(OTP_OTP_FUNC_CMD_OTP_PROGRAM, OTP_OTP_FUNC_CMD(otp->base)); 109 writel(OTP_OTP_CMD_GO_OTP_GO, OTP_OTP_CMD_GO(otp->base)); 110 111 rc = lan9662_otp_execute(otp); 112 if (!rc) { 113 pass = readl(OTP_OTP_PASS_FAIL(otp->base)); 114 if (pass & OTP_OTP_PASS_FAIL_OTP_WRITE_PROHIBITED) 115 return -EACCES; 116 if (pass & OTP_OTP_PASS_FAIL_OTP_FAIL) 117 return -EIO; 118 } 119 return rc; 120 } 121 122 static int lan9662_otp_read(void *context, unsigned int offset, 123 void *_val, size_t bytes) 124 { 125 struct lan9662_otp *otp = context; 126 u8 *val = _val; 127 uint8_t data; 128 int i, rc = 0; 129 130 lan9662_otp_power(otp, true); 131 for (i = 0; i < bytes; i++) { 132 rc = lan9662_otp_read_byte(otp, offset + i, &data); 133 if (rc < 0) 134 break; 135 *val++ = data; 136 } 137 lan9662_otp_power(otp, false); 138 139 return rc; 140 } 141 142 static int lan9662_otp_write(void *context, unsigned int offset, 143 void *_val, size_t bytes) 144 { 145 struct lan9662_otp *otp = context; 146 u8 *val = _val; 147 u8 data, newdata; 148 int i, rc = 0; 149 150 lan9662_otp_power(otp, true); 151 for (i = 0; i < bytes; i++) { 152 /* Skip zero bytes */ 153 if (val[i]) { 154 rc = lan9662_otp_read_byte(otp, offset + i, &data); 155 if (rc < 0) 156 break; 157 158 newdata = data | val[i]; 159 if (newdata == data) 160 continue; 161 162 rc = lan9662_otp_write_byte(otp, offset + i, 163 newdata); 164 if (rc < 0) 165 break; 166 } 167 } 168 lan9662_otp_power(otp, false); 169 170 return rc; 171 } 172 173 static struct nvmem_config otp_config = { 174 .name = "lan9662-otp", 175 .stride = 1, 176 .word_size = 1, 177 .reg_read = lan9662_otp_read, 178 .reg_write = lan9662_otp_write, 179 .size = OTP_MEM_SIZE, 180 }; 181 182 static int lan9662_otp_probe(struct platform_device *pdev) 183 { 184 struct device *dev = &pdev->dev; 185 struct nvmem_device *nvmem; 186 struct lan9662_otp *otp; 187 188 otp = devm_kzalloc(&pdev->dev, sizeof(*otp), GFP_KERNEL); 189 if (!otp) 190 return -ENOMEM; 191 192 otp->dev = dev; 193 otp->base = devm_platform_ioremap_resource(pdev, 0); 194 if (IS_ERR(otp->base)) 195 return PTR_ERR(otp->base); 196 197 otp_config.priv = otp; 198 otp_config.dev = dev; 199 200 nvmem = devm_nvmem_register(dev, &otp_config); 201 202 return PTR_ERR_OR_ZERO(nvmem); 203 } 204 205 static const struct of_device_id lan9662_otp_match[] = { 206 { .compatible = "microchip,lan9662-otp", }, 207 { }, 208 }; 209 MODULE_DEVICE_TABLE(of, lan9662_otp_match); 210 211 static struct platform_driver lan9662_otp_driver = { 212 .probe = lan9662_otp_probe, 213 .driver = { 214 .name = "lan9662-otp", 215 .of_match_table = lan9662_otp_match, 216 }, 217 }; 218 module_platform_driver(lan9662_otp_driver); 219 220 MODULE_AUTHOR("Horatiu Vultur <horatiu.vultur@microchip.com>"); 221 MODULE_DESCRIPTION("lan9662 OTP driver"); 222 MODULE_LICENSE("GPL"); 223