Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 
0003 #include <linux/delay.h>
0004 #include <linux/err.h>
0005 #include <linux/interrupt.h>
0006 #include <linux/io.h>
0007 #include <linux/kernel.h>
0008 #include <linux/module.h>
0009 #include <linux/of.h>
0010 #include <linux/platform_device.h>
0011 #include <linux/seq_file.h>
0012 #include <linux/slab.h>
0013 #include <linux/spmi.h>
0014 
0015 /*
0016  * SPMI register addr
0017  */
0018 #define SPMI_CHANNEL_OFFSET             0x0300
0019 #define SPMI_SLAVE_OFFSET               0x20
0020 
0021 #define SPMI_APB_SPMI_CMD_BASE_ADDR         0x0100
0022 
0023 #define SPMI_APB_SPMI_WDATA0_BASE_ADDR          0x0104
0024 #define SPMI_APB_SPMI_WDATA1_BASE_ADDR          0x0108
0025 #define SPMI_APB_SPMI_WDATA2_BASE_ADDR          0x010c
0026 #define SPMI_APB_SPMI_WDATA3_BASE_ADDR          0x0110
0027 
0028 #define SPMI_APB_SPMI_STATUS_BASE_ADDR          0x0200
0029 
0030 #define SPMI_APB_SPMI_RDATA0_BASE_ADDR          0x0204
0031 #define SPMI_APB_SPMI_RDATA1_BASE_ADDR          0x0208
0032 #define SPMI_APB_SPMI_RDATA2_BASE_ADDR          0x020c
0033 #define SPMI_APB_SPMI_RDATA3_BASE_ADDR          0x0210
0034 
0035 #define SPMI_PER_DATAREG_BYTE               4
0036 /*
0037  * SPMI cmd register
0038  */
0039 #define SPMI_APB_SPMI_CMD_EN                BIT(31)
0040 #define SPMI_APB_SPMI_CMD_TYPE_OFFSET           24
0041 #define SPMI_APB_SPMI_CMD_LENGTH_OFFSET         20
0042 #define SPMI_APB_SPMI_CMD_SLAVEID_OFFSET        16
0043 #define SPMI_APB_SPMI_CMD_ADDR_OFFSET           0
0044 
0045 /* Command Opcodes */
0046 
0047 enum spmi_controller_cmd_op_code {
0048     SPMI_CMD_REG_ZERO_WRITE = 0,
0049     SPMI_CMD_REG_WRITE = 1,
0050     SPMI_CMD_REG_READ = 2,
0051     SPMI_CMD_EXT_REG_WRITE = 3,
0052     SPMI_CMD_EXT_REG_READ = 4,
0053     SPMI_CMD_EXT_REG_WRITE_L = 5,
0054     SPMI_CMD_EXT_REG_READ_L = 6,
0055     SPMI_CMD_REG_RESET = 7,
0056     SPMI_CMD_REG_SLEEP = 8,
0057     SPMI_CMD_REG_SHUTDOWN = 9,
0058     SPMI_CMD_REG_WAKEUP = 10,
0059 };
0060 
0061 /*
0062  * SPMI status register
0063  */
0064 #define SPMI_APB_TRANS_DONE         BIT(0)
0065 #define SPMI_APB_TRANS_FAIL         BIT(2)
0066 
0067 /* Command register fields */
0068 #define SPMI_CONTROLLER_CMD_MAX_BYTE_COUNT  16
0069 
0070 /* Maximum number of support PMIC peripherals */
0071 #define SPMI_CONTROLLER_TIMEOUT_US      1000
0072 #define SPMI_CONTROLLER_MAX_TRANS_BYTES     16
0073 
0074 struct spmi_controller_dev {
0075     struct spmi_controller  *controller;
0076     struct device       *dev;
0077     void __iomem        *base;
0078     spinlock_t      lock;
0079     u32         channel;
0080 };
0081 
0082 static int spmi_controller_wait_for_done(struct device *dev,
0083                      struct spmi_controller_dev *ctrl_dev,
0084                      void __iomem *base, u8 sid, u16 addr)
0085 {
0086     u32 timeout = SPMI_CONTROLLER_TIMEOUT_US;
0087     u32 status, offset;
0088 
0089     offset  = SPMI_APB_SPMI_STATUS_BASE_ADDR;
0090     offset += SPMI_CHANNEL_OFFSET * ctrl_dev->channel + SPMI_SLAVE_OFFSET * sid;
0091 
0092     do {
0093         status = readl(base + offset);
0094 
0095         if (status & SPMI_APB_TRANS_DONE) {
0096             if (status & SPMI_APB_TRANS_FAIL) {
0097                 dev_err(dev, "%s: transaction failed (0x%x)\n",
0098                     __func__, status);
0099                 return -EIO;
0100             }
0101             dev_dbg(dev, "%s: status 0x%x\n", __func__, status);
0102             return 0;
0103         }
0104         udelay(1);
0105     } while (timeout--);
0106 
0107     dev_err(dev, "%s: timeout, status 0x%x\n", __func__, status);
0108     return -ETIMEDOUT;
0109 }
0110 
0111 static int spmi_read_cmd(struct spmi_controller *ctrl,
0112              u8 opc, u8 slave_id, u16 slave_addr, u8 *__buf, size_t bc)
0113 {
0114     struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev);
0115     u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel;
0116     unsigned long flags;
0117     u8 *buf = __buf;
0118     u32 cmd, data;
0119     int rc;
0120     u8 op_code, i;
0121 
0122     if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) {
0123         dev_err(&ctrl->dev,
0124             "spmi_controller supports 1..%d bytes per trans, but:%zu requested\n",
0125             SPMI_CONTROLLER_MAX_TRANS_BYTES, bc);
0126         return  -EINVAL;
0127     }
0128 
0129     switch (opc) {
0130     case SPMI_CMD_READ:
0131         op_code = SPMI_CMD_REG_READ;
0132         break;
0133     case SPMI_CMD_EXT_READ:
0134         op_code = SPMI_CMD_EXT_REG_READ;
0135         break;
0136     case SPMI_CMD_EXT_READL:
0137         op_code = SPMI_CMD_EXT_REG_READ_L;
0138         break;
0139     default:
0140         dev_err(&ctrl->dev, "invalid read cmd 0x%x\n", opc);
0141         return -EINVAL;
0142     }
0143 
0144     cmd = SPMI_APB_SPMI_CMD_EN |
0145          (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) |
0146          ((bc - 1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) |
0147          ((slave_id & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) |  /* slvid */
0148          ((slave_addr & 0xffff)  << SPMI_APB_SPMI_CMD_ADDR_OFFSET); /* slave_addr */
0149 
0150     spin_lock_irqsave(&spmi_controller->lock, flags);
0151 
0152     writel(cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR);
0153 
0154     rc = spmi_controller_wait_for_done(&ctrl->dev, spmi_controller,
0155                        spmi_controller->base, slave_id, slave_addr);
0156     if (rc)
0157         goto done;
0158 
0159     for (i = 0; bc > i * SPMI_PER_DATAREG_BYTE; i++) {
0160         data = readl(spmi_controller->base + chnl_ofst +
0161                  SPMI_SLAVE_OFFSET * slave_id +
0162                  SPMI_APB_SPMI_RDATA0_BASE_ADDR +
0163                  i * SPMI_PER_DATAREG_BYTE);
0164         data = be32_to_cpu((__be32 __force)data);
0165         if ((bc - i * SPMI_PER_DATAREG_BYTE) >> 2) {
0166             memcpy(buf, &data, sizeof(data));
0167             buf += sizeof(data);
0168         } else {
0169             memcpy(buf, &data, bc % SPMI_PER_DATAREG_BYTE);
0170             buf += (bc % SPMI_PER_DATAREG_BYTE);
0171         }
0172     }
0173 
0174 done:
0175     spin_unlock_irqrestore(&spmi_controller->lock, flags);
0176     if (rc)
0177         dev_err(&ctrl->dev,
0178             "spmi read wait timeout op:0x%x slave_id:%d slave_addr:0x%x bc:%zu\n",
0179             opc, slave_id, slave_addr, bc + 1);
0180     else
0181         dev_dbg(&ctrl->dev, "%s: id:%d slave_addr:0x%x, read value: %*ph\n",
0182             __func__, slave_id, slave_addr, (int)bc, __buf);
0183 
0184     return rc;
0185 }
0186 
0187 static int spmi_write_cmd(struct spmi_controller *ctrl,
0188               u8 opc, u8 slave_id, u16 slave_addr, const u8 *__buf, size_t bc)
0189 {
0190     struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev);
0191     u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel;
0192     const u8 *buf = __buf;
0193     unsigned long flags;
0194     u32 cmd, data;
0195     int rc;
0196     u8 op_code, i;
0197 
0198     if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) {
0199         dev_err(&ctrl->dev,
0200             "spmi_controller supports 1..%d bytes per trans, but:%zu requested\n",
0201             SPMI_CONTROLLER_MAX_TRANS_BYTES, bc);
0202         return  -EINVAL;
0203     }
0204 
0205     switch (opc) {
0206     case SPMI_CMD_WRITE:
0207         op_code = SPMI_CMD_REG_WRITE;
0208         break;
0209     case SPMI_CMD_EXT_WRITE:
0210         op_code = SPMI_CMD_EXT_REG_WRITE;
0211         break;
0212     case SPMI_CMD_EXT_WRITEL:
0213         op_code = SPMI_CMD_EXT_REG_WRITE_L;
0214         break;
0215     default:
0216         dev_err(&ctrl->dev, "invalid write cmd 0x%x\n", opc);
0217         return -EINVAL;
0218     }
0219 
0220     cmd = SPMI_APB_SPMI_CMD_EN |
0221           (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) |
0222           ((bc - 1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) |
0223           ((slave_id & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) |
0224           ((slave_addr & 0xffff)  << SPMI_APB_SPMI_CMD_ADDR_OFFSET);
0225 
0226     /* Write data to FIFOs */
0227     spin_lock_irqsave(&spmi_controller->lock, flags);
0228 
0229     for (i = 0; bc > i * SPMI_PER_DATAREG_BYTE; i++) {
0230         data = 0;
0231         if ((bc - i * SPMI_PER_DATAREG_BYTE) >> 2) {
0232             memcpy(&data, buf, sizeof(data));
0233             buf += sizeof(data);
0234         } else {
0235             memcpy(&data, buf, bc % SPMI_PER_DATAREG_BYTE);
0236             buf += (bc % SPMI_PER_DATAREG_BYTE);
0237         }
0238 
0239         writel((u32 __force)cpu_to_be32(data),
0240                spmi_controller->base + chnl_ofst +
0241                SPMI_APB_SPMI_WDATA0_BASE_ADDR +
0242                SPMI_PER_DATAREG_BYTE * i);
0243     }
0244 
0245     /* Start the transaction */
0246     writel(cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR);
0247 
0248     rc = spmi_controller_wait_for_done(&ctrl->dev, spmi_controller,
0249                        spmi_controller->base, slave_id,
0250                        slave_addr);
0251     spin_unlock_irqrestore(&spmi_controller->lock, flags);
0252 
0253     if (rc)
0254         dev_err(&ctrl->dev, "spmi write wait timeout op:0x%x slave_id:%d slave_addr:0x%x bc:%zu\n",
0255             opc, slave_id, slave_addr, bc);
0256     else
0257         dev_dbg(&ctrl->dev, "%s: id:%d slave_addr:0x%x, wrote value: %*ph\n",
0258             __func__, slave_id, slave_addr, (int)bc, __buf);
0259 
0260     return rc;
0261 }
0262 
0263 static int spmi_controller_probe(struct platform_device *pdev)
0264 {
0265     struct spmi_controller_dev *spmi_controller;
0266     struct spmi_controller *ctrl;
0267     struct resource *iores;
0268     int ret;
0269 
0270     ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*spmi_controller));
0271     if (!ctrl) {
0272         dev_err(&pdev->dev, "can not allocate spmi_controller data\n");
0273         return -ENOMEM;
0274     }
0275     spmi_controller = spmi_controller_get_drvdata(ctrl);
0276     spmi_controller->controller = ctrl;
0277 
0278     iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0279     if (!iores) {
0280         dev_err(&pdev->dev, "can not get resource!\n");
0281         ret = -EINVAL;
0282         goto err_put_controller;
0283     }
0284 
0285     spmi_controller->base = devm_ioremap(&pdev->dev, iores->start,
0286                          resource_size(iores));
0287     if (!spmi_controller->base) {
0288         dev_err(&pdev->dev, "can not remap base addr!\n");
0289         ret = -EADDRNOTAVAIL;
0290         goto err_put_controller;
0291     }
0292 
0293     ret = of_property_read_u32(pdev->dev.of_node, "hisilicon,spmi-channel",
0294                    &spmi_controller->channel);
0295     if (ret) {
0296         dev_err(&pdev->dev, "can not get channel\n");
0297         ret = -ENODEV;
0298         goto err_put_controller;
0299     }
0300 
0301     platform_set_drvdata(pdev, spmi_controller);
0302     dev_set_drvdata(&ctrl->dev, spmi_controller);
0303 
0304     spin_lock_init(&spmi_controller->lock);
0305 
0306     ctrl->nr = spmi_controller->channel;
0307     ctrl->dev.parent = pdev->dev.parent;
0308     ctrl->dev.of_node = of_node_get(pdev->dev.of_node);
0309 
0310     /* Callbacks */
0311     ctrl->read_cmd = spmi_read_cmd;
0312     ctrl->write_cmd = spmi_write_cmd;
0313 
0314     ret = spmi_controller_add(ctrl);
0315     if (ret) {
0316         dev_err(&pdev->dev, "spmi_controller_add failed with error %d!\n", ret);
0317         goto err_put_controller;
0318     }
0319 
0320     return 0;
0321 
0322 err_put_controller:
0323     spmi_controller_put(ctrl);
0324     return ret;
0325 }
0326 
0327 static int spmi_del_controller(struct platform_device *pdev)
0328 {
0329     struct spmi_controller *ctrl = platform_get_drvdata(pdev);
0330 
0331     spmi_controller_remove(ctrl);
0332     spmi_controller_put(ctrl);
0333     return 0;
0334 }
0335 
0336 static const struct of_device_id spmi_controller_match_table[] = {
0337     {
0338         .compatible = "hisilicon,kirin970-spmi-controller",
0339     },
0340     {}
0341 };
0342 MODULE_DEVICE_TABLE(of, spmi_controller_match_table);
0343 
0344 static struct platform_driver spmi_controller_driver = {
0345     .probe      = spmi_controller_probe,
0346     .remove     = spmi_del_controller,
0347     .driver     = {
0348         .name   = "hisi_spmi_controller",
0349         .of_match_table = spmi_controller_match_table,
0350     },
0351 };
0352 
0353 static int __init spmi_controller_init(void)
0354 {
0355     return platform_driver_register(&spmi_controller_driver);
0356 }
0357 postcore_initcall(spmi_controller_init);
0358 
0359 static void __exit spmi_controller_exit(void)
0360 {
0361     platform_driver_unregister(&spmi_controller_driver);
0362 }
0363 module_exit(spmi_controller_exit);
0364 
0365 MODULE_LICENSE("GPL v2");
0366 MODULE_VERSION("1.0");
0367 MODULE_ALIAS("platform:spmi_controller");