1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <linux/delay.h> 4 #include <linux/err.h> 5 #include <linux/interrupt.h> 6 #include <linux/io.h> 7 #include <linux/kernel.h> 8 #include <linux/module.h> 9 #include <linux/of.h> 10 #include <linux/platform_device.h> 11 #include <linux/seq_file.h> 12 #include <linux/slab.h> 13 #include <linux/spmi.h> 14 15 /* 16 * SPMI register addr 17 */ 18 #define SPMI_CHANNEL_OFFSET 0x0300 19 #define SPMI_SLAVE_OFFSET 0x20 20 21 #define SPMI_APB_SPMI_CMD_BASE_ADDR 0x0100 22 23 #define SPMI_APB_SPMI_WDATA0_BASE_ADDR 0x0104 24 #define SPMI_APB_SPMI_WDATA1_BASE_ADDR 0x0108 25 #define SPMI_APB_SPMI_WDATA2_BASE_ADDR 0x010c 26 #define SPMI_APB_SPMI_WDATA3_BASE_ADDR 0x0110 27 28 #define SPMI_APB_SPMI_STATUS_BASE_ADDR 0x0200 29 30 #define SPMI_APB_SPMI_RDATA0_BASE_ADDR 0x0204 31 #define SPMI_APB_SPMI_RDATA1_BASE_ADDR 0x0208 32 #define SPMI_APB_SPMI_RDATA2_BASE_ADDR 0x020c 33 #define SPMI_APB_SPMI_RDATA3_BASE_ADDR 0x0210 34 35 #define SPMI_PER_DATAREG_BYTE 4 36 /* 37 * SPMI cmd register 38 */ 39 #define SPMI_APB_SPMI_CMD_EN BIT(31) 40 #define SPMI_APB_SPMI_CMD_TYPE_OFFSET 24 41 #define SPMI_APB_SPMI_CMD_LENGTH_OFFSET 20 42 #define SPMI_APB_SPMI_CMD_SLAVEID_OFFSET 16 43 #define SPMI_APB_SPMI_CMD_ADDR_OFFSET 0 44 45 /* Command Opcodes */ 46 47 enum spmi_controller_cmd_op_code { 48 SPMI_CMD_REG_ZERO_WRITE = 0, 49 SPMI_CMD_REG_WRITE = 1, 50 SPMI_CMD_REG_READ = 2, 51 SPMI_CMD_EXT_REG_WRITE = 3, 52 SPMI_CMD_EXT_REG_READ = 4, 53 SPMI_CMD_EXT_REG_WRITE_L = 5, 54 SPMI_CMD_EXT_REG_READ_L = 6, 55 SPMI_CMD_REG_RESET = 7, 56 SPMI_CMD_REG_SLEEP = 8, 57 SPMI_CMD_REG_SHUTDOWN = 9, 58 SPMI_CMD_REG_WAKEUP = 10, 59 }; 60 61 /* 62 * SPMI status register 63 */ 64 #define SPMI_APB_TRANS_DONE BIT(0) 65 #define SPMI_APB_TRANS_FAIL BIT(2) 66 67 /* Command register fields */ 68 #define SPMI_CONTROLLER_CMD_MAX_BYTE_COUNT 16 69 70 /* Maximum number of support PMIC peripherals */ 71 #define SPMI_CONTROLLER_TIMEOUT_US 1000 72 #define SPMI_CONTROLLER_MAX_TRANS_BYTES 16 73 74 struct spmi_controller_dev { 75 struct spmi_controller *controller; 76 struct device *dev; 77 void __iomem *base; 78 spinlock_t lock; 79 u32 channel; 80 }; 81 82 static int spmi_controller_wait_for_done(struct device *dev, 83 struct spmi_controller_dev *ctrl_dev, 84 void __iomem *base, u8 sid, u16 addr) 85 { 86 u32 timeout = SPMI_CONTROLLER_TIMEOUT_US; 87 u32 status, offset; 88 89 offset = SPMI_APB_SPMI_STATUS_BASE_ADDR; 90 offset += SPMI_CHANNEL_OFFSET * ctrl_dev->channel + SPMI_SLAVE_OFFSET * sid; 91 92 do { 93 status = readl(base + offset); 94 95 if (status & SPMI_APB_TRANS_DONE) { 96 if (status & SPMI_APB_TRANS_FAIL) { 97 dev_err(dev, "%s: transaction failed (0x%x)\n", 98 __func__, status); 99 return -EIO; 100 } 101 dev_dbg(dev, "%s: status 0x%x\n", __func__, status); 102 return 0; 103 } 104 udelay(1); 105 } while (timeout--); 106 107 dev_err(dev, "%s: timeout, status 0x%x\n", __func__, status); 108 return -ETIMEDOUT; 109 } 110 111 static int spmi_read_cmd(struct spmi_controller *ctrl, 112 u8 opc, u8 slave_id, u16 slave_addr, u8 *__buf, size_t bc) 113 { 114 struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev); 115 u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel; 116 unsigned long flags; 117 u8 *buf = __buf; 118 u32 cmd, data; 119 int rc; 120 u8 op_code, i; 121 122 if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) { 123 dev_err(&ctrl->dev, 124 "spmi_controller supports 1..%d bytes per trans, but:%zu requested\n", 125 SPMI_CONTROLLER_MAX_TRANS_BYTES, bc); 126 return -EINVAL; 127 } 128 129 switch (opc) { 130 case SPMI_CMD_READ: 131 op_code = SPMI_CMD_REG_READ; 132 break; 133 case SPMI_CMD_EXT_READ: 134 op_code = SPMI_CMD_EXT_REG_READ; 135 break; 136 case SPMI_CMD_EXT_READL: 137 op_code = SPMI_CMD_EXT_REG_READ_L; 138 break; 139 default: 140 dev_err(&ctrl->dev, "invalid read cmd 0x%x\n", opc); 141 return -EINVAL; 142 } 143 144 cmd = SPMI_APB_SPMI_CMD_EN | 145 (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) | 146 ((bc - 1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) | 147 ((slave_id & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) | /* slvid */ 148 ((slave_addr & 0xffff) << SPMI_APB_SPMI_CMD_ADDR_OFFSET); /* slave_addr */ 149 150 spin_lock_irqsave(&spmi_controller->lock, flags); 151 152 writel(cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR); 153 154 rc = spmi_controller_wait_for_done(&ctrl->dev, spmi_controller, 155 spmi_controller->base, slave_id, slave_addr); 156 if (rc) 157 goto done; 158 159 for (i = 0; bc > i * SPMI_PER_DATAREG_BYTE; i++) { 160 data = readl(spmi_controller->base + chnl_ofst + 161 SPMI_SLAVE_OFFSET * slave_id + 162 SPMI_APB_SPMI_RDATA0_BASE_ADDR + 163 i * SPMI_PER_DATAREG_BYTE); 164 data = be32_to_cpu((__be32 __force)data); 165 if ((bc - i * SPMI_PER_DATAREG_BYTE) >> 2) { 166 memcpy(buf, &data, sizeof(data)); 167 buf += sizeof(data); 168 } else { 169 memcpy(buf, &data, bc % SPMI_PER_DATAREG_BYTE); 170 buf += (bc % SPMI_PER_DATAREG_BYTE); 171 } 172 } 173 174 done: 175 spin_unlock_irqrestore(&spmi_controller->lock, flags); 176 if (rc) 177 dev_err(&ctrl->dev, 178 "spmi read wait timeout op:0x%x slave_id:%d slave_addr:0x%x bc:%zu\n", 179 opc, slave_id, slave_addr, bc + 1); 180 else 181 dev_dbg(&ctrl->dev, "%s: id:%d slave_addr:0x%x, read value: %*ph\n", 182 __func__, slave_id, slave_addr, (int)bc, __buf); 183 184 return rc; 185 } 186 187 static int spmi_write_cmd(struct spmi_controller *ctrl, 188 u8 opc, u8 slave_id, u16 slave_addr, const u8 *__buf, size_t bc) 189 { 190 struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev); 191 u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel; 192 const u8 *buf = __buf; 193 unsigned long flags; 194 u32 cmd, data; 195 int rc; 196 u8 op_code, i; 197 198 if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) { 199 dev_err(&ctrl->dev, 200 "spmi_controller supports 1..%d bytes per trans, but:%zu requested\n", 201 SPMI_CONTROLLER_MAX_TRANS_BYTES, bc); 202 return -EINVAL; 203 } 204 205 switch (opc) { 206 case SPMI_CMD_WRITE: 207 op_code = SPMI_CMD_REG_WRITE; 208 break; 209 case SPMI_CMD_EXT_WRITE: 210 op_code = SPMI_CMD_EXT_REG_WRITE; 211 break; 212 case SPMI_CMD_EXT_WRITEL: 213 op_code = SPMI_CMD_EXT_REG_WRITE_L; 214 break; 215 default: 216 dev_err(&ctrl->dev, "invalid write cmd 0x%x\n", opc); 217 return -EINVAL; 218 } 219 220 cmd = SPMI_APB_SPMI_CMD_EN | 221 (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) | 222 ((bc - 1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) | 223 ((slave_id & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) | 224 ((slave_addr & 0xffff) << SPMI_APB_SPMI_CMD_ADDR_OFFSET); 225 226 /* Write data to FIFOs */ 227 spin_lock_irqsave(&spmi_controller->lock, flags); 228 229 for (i = 0; bc > i * SPMI_PER_DATAREG_BYTE; i++) { 230 data = 0; 231 if ((bc - i * SPMI_PER_DATAREG_BYTE) >> 2) { 232 memcpy(&data, buf, sizeof(data)); 233 buf += sizeof(data); 234 } else { 235 memcpy(&data, buf, bc % SPMI_PER_DATAREG_BYTE); 236 buf += (bc % SPMI_PER_DATAREG_BYTE); 237 } 238 239 writel((u32 __force)cpu_to_be32(data), 240 spmi_controller->base + chnl_ofst + 241 SPMI_APB_SPMI_WDATA0_BASE_ADDR + 242 SPMI_PER_DATAREG_BYTE * i); 243 } 244 245 /* Start the transaction */ 246 writel(cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR); 247 248 rc = spmi_controller_wait_for_done(&ctrl->dev, spmi_controller, 249 spmi_controller->base, slave_id, 250 slave_addr); 251 spin_unlock_irqrestore(&spmi_controller->lock, flags); 252 253 if (rc) 254 dev_err(&ctrl->dev, "spmi write wait timeout op:0x%x slave_id:%d slave_addr:0x%x bc:%zu\n", 255 opc, slave_id, slave_addr, bc); 256 else 257 dev_dbg(&ctrl->dev, "%s: id:%d slave_addr:0x%x, wrote value: %*ph\n", 258 __func__, slave_id, slave_addr, (int)bc, __buf); 259 260 return rc; 261 } 262 263 static int spmi_controller_probe(struct platform_device *pdev) 264 { 265 struct spmi_controller_dev *spmi_controller; 266 struct spmi_controller *ctrl; 267 struct resource *iores; 268 int ret; 269 270 ctrl = devm_spmi_controller_alloc(&pdev->dev, sizeof(*spmi_controller)); 271 if (IS_ERR(ctrl)) { 272 dev_err(&pdev->dev, "can not allocate spmi_controller data\n"); 273 return PTR_ERR(ctrl); 274 } 275 spmi_controller = spmi_controller_get_drvdata(ctrl); 276 spmi_controller->controller = ctrl; 277 278 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); 279 if (!iores) { 280 dev_err(&pdev->dev, "can not get resource!\n"); 281 return -EINVAL; 282 } 283 284 spmi_controller->base = devm_ioremap(&pdev->dev, iores->start, 285 resource_size(iores)); 286 if (!spmi_controller->base) { 287 dev_err(&pdev->dev, "can not remap base addr!\n"); 288 return -EADDRNOTAVAIL; 289 } 290 291 ret = of_property_read_u32(pdev->dev.of_node, "hisilicon,spmi-channel", 292 &spmi_controller->channel); 293 if (ret) { 294 dev_err(&pdev->dev, "can not get channel\n"); 295 return -ENODEV; 296 } 297 298 platform_set_drvdata(pdev, spmi_controller); 299 dev_set_drvdata(&ctrl->dev, spmi_controller); 300 301 spin_lock_init(&spmi_controller->lock); 302 303 ctrl->dev.parent = pdev->dev.parent; 304 ctrl->dev.of_node = of_node_get(pdev->dev.of_node); 305 306 /* Callbacks */ 307 ctrl->read_cmd = spmi_read_cmd; 308 ctrl->write_cmd = spmi_write_cmd; 309 310 ret = devm_spmi_controller_add(&pdev->dev, ctrl); 311 if (ret) { 312 dev_err(&pdev->dev, "spmi_controller_add failed with error %d!\n", ret); 313 return ret; 314 } 315 316 return 0; 317 } 318 319 static const struct of_device_id spmi_controller_match_table[] = { 320 { 321 .compatible = "hisilicon,kirin970-spmi-controller", 322 }, 323 {} 324 }; 325 MODULE_DEVICE_TABLE(of, spmi_controller_match_table); 326 327 static struct platform_driver spmi_controller_driver = { 328 .probe = spmi_controller_probe, 329 .driver = { 330 .name = "hisi_spmi_controller", 331 .of_match_table = spmi_controller_match_table, 332 }, 333 }; 334 335 static int __init spmi_controller_init(void) 336 { 337 return platform_driver_register(&spmi_controller_driver); 338 } 339 postcore_initcall(spmi_controller_init); 340 341 static void __exit spmi_controller_exit(void) 342 { 343 platform_driver_unregister(&spmi_controller_driver); 344 } 345 module_exit(spmi_controller_exit); 346 347 MODULE_DESCRIPTION("Hisilicon 3670 SPMI Controller driver"); 348 MODULE_LICENSE("GPL v2"); 349 MODULE_VERSION("1.0"); 350 MODULE_ALIAS("platform:spmi_controller"); 351