351 lines · c
1// SPDX-License-Identifier: GPL-2.02 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 addr17 */18#define SPMI_CHANNEL_OFFSET 0x030019#define SPMI_SLAVE_OFFSET 0x2020 21#define SPMI_APB_SPMI_CMD_BASE_ADDR 0x010022 23#define SPMI_APB_SPMI_WDATA0_BASE_ADDR 0x010424#define SPMI_APB_SPMI_WDATA1_BASE_ADDR 0x010825#define SPMI_APB_SPMI_WDATA2_BASE_ADDR 0x010c26#define SPMI_APB_SPMI_WDATA3_BASE_ADDR 0x011027 28#define SPMI_APB_SPMI_STATUS_BASE_ADDR 0x020029 30#define SPMI_APB_SPMI_RDATA0_BASE_ADDR 0x020431#define SPMI_APB_SPMI_RDATA1_BASE_ADDR 0x020832#define SPMI_APB_SPMI_RDATA2_BASE_ADDR 0x020c33#define SPMI_APB_SPMI_RDATA3_BASE_ADDR 0x021034 35#define SPMI_PER_DATAREG_BYTE 436/*37 * SPMI cmd register38 */39#define SPMI_APB_SPMI_CMD_EN BIT(31)40#define SPMI_APB_SPMI_CMD_TYPE_OFFSET 2441#define SPMI_APB_SPMI_CMD_LENGTH_OFFSET 2042#define SPMI_APB_SPMI_CMD_SLAVEID_OFFSET 1643#define SPMI_APB_SPMI_CMD_ADDR_OFFSET 044 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 register63 */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 1669 70/* Maximum number of support PMIC peripherals */71#define SPMI_CONTROLLER_TIMEOUT_US 100072#define SPMI_CONTROLLER_MAX_TRANS_BYTES 1673 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 else181 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 else257 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 = 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 319static const struct of_device_id spmi_controller_match_table[] = {320 {321 .compatible = "hisilicon,kirin970-spmi-controller",322 },323 {}324};325MODULE_DEVICE_TABLE(of, spmi_controller_match_table);326 327static 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 335static int __init spmi_controller_init(void)336{337 return platform_driver_register(&spmi_controller_driver);338}339postcore_initcall(spmi_controller_init);340 341static void __exit spmi_controller_exit(void)342{343 platform_driver_unregister(&spmi_controller_driver);344}345module_exit(spmi_controller_exit);346 347MODULE_DESCRIPTION("Hisilicon 3670 SPMI Controller driver");348MODULE_LICENSE("GPL v2");349MODULE_VERSION("1.0");350MODULE_ALIAS("platform:spmi_controller");351