hisi-spmi-controller.c (9901B)
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 47enum 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 74struct 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 82static 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 111static 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 174done: 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 187static 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 263static 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 = spmi_controller_alloc(&pdev->dev, sizeof(*spmi_controller)); 271 if (!ctrl) { 272 dev_err(&pdev->dev, "can not allocate spmi_controller data\n"); 273 return -ENOMEM; 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 ret = -EINVAL; 282 goto err_put_controller; 283 } 284 285 spmi_controller->base = devm_ioremap(&pdev->dev, iores->start, 286 resource_size(iores)); 287 if (!spmi_controller->base) { 288 dev_err(&pdev->dev, "can not remap base addr!\n"); 289 ret = -EADDRNOTAVAIL; 290 goto err_put_controller; 291 } 292 293 ret = of_property_read_u32(pdev->dev.of_node, "hisilicon,spmi-channel", 294 &spmi_controller->channel); 295 if (ret) { 296 dev_err(&pdev->dev, "can not get channel\n"); 297 ret = -ENODEV; 298 goto err_put_controller; 299 } 300 301 platform_set_drvdata(pdev, spmi_controller); 302 dev_set_drvdata(&ctrl->dev, spmi_controller); 303 304 spin_lock_init(&spmi_controller->lock); 305 306 ctrl->nr = spmi_controller->channel; 307 ctrl->dev.parent = pdev->dev.parent; 308 ctrl->dev.of_node = of_node_get(pdev->dev.of_node); 309 310 /* Callbacks */ 311 ctrl->read_cmd = spmi_read_cmd; 312 ctrl->write_cmd = spmi_write_cmd; 313 314 ret = spmi_controller_add(ctrl); 315 if (ret) { 316 dev_err(&pdev->dev, "spmi_controller_add failed with error %d!\n", ret); 317 goto err_put_controller; 318 } 319 320 return 0; 321 322err_put_controller: 323 spmi_controller_put(ctrl); 324 return ret; 325} 326 327static int spmi_del_controller(struct platform_device *pdev) 328{ 329 struct spmi_controller *ctrl = platform_get_drvdata(pdev); 330 331 spmi_controller_remove(ctrl); 332 spmi_controller_put(ctrl); 333 return 0; 334} 335 336static const struct of_device_id spmi_controller_match_table[] = { 337 { 338 .compatible = "hisilicon,kirin970-spmi-controller", 339 }, 340 {} 341}; 342MODULE_DEVICE_TABLE(of, spmi_controller_match_table); 343 344static struct platform_driver spmi_controller_driver = { 345 .probe = spmi_controller_probe, 346 .remove = spmi_del_controller, 347 .driver = { 348 .name = "hisi_spmi_controller", 349 .of_match_table = spmi_controller_match_table, 350 }, 351}; 352 353static int __init spmi_controller_init(void) 354{ 355 return platform_driver_register(&spmi_controller_driver); 356} 357postcore_initcall(spmi_controller_init); 358 359static void __exit spmi_controller_exit(void) 360{ 361 platform_driver_unregister(&spmi_controller_driver); 362} 363module_exit(spmi_controller_exit); 364 365MODULE_LICENSE("GPL v2"); 366MODULE_VERSION("1.0"); 367MODULE_ALIAS("platform:spmi_controller");