root/drivers/mfd/ssbi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ssbi_readl
  2. ssbi_writel
  3. ssbi_wait_mask
  4. ssbi_read_bytes
  5. ssbi_write_bytes
  6. ssbi_pa_transfer
  7. ssbi_pa_read_bytes
  8. ssbi_pa_write_bytes
  9. ssbi_read
  10. ssbi_write
  11. ssbi_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /* Copyright (c) 2009-2013, The Linux Foundation. All rights reserved.
   3  * Copyright (c) 2010, Google Inc.
   4  *
   5  * Original authors: Code Aurora Forum
   6  *
   7  * Author: Dima Zavin <dima@android.com>
   8  *  - Largely rewritten from original to not be an i2c driver.
   9  */
  10 
  11 #define pr_fmt(fmt) "%s: " fmt, __func__
  12 
  13 #include <linux/delay.h>
  14 #include <linux/err.h>
  15 #include <linux/io.h>
  16 #include <linux/kernel.h>
  17 #include <linux/platform_device.h>
  18 #include <linux/slab.h>
  19 #include <linux/ssbi.h>
  20 #include <linux/module.h>
  21 #include <linux/of.h>
  22 #include <linux/of_device.h>
  23 
  24 /* SSBI 2.0 controller registers */
  25 #define SSBI2_CMD                       0x0008
  26 #define SSBI2_RD                        0x0010
  27 #define SSBI2_STATUS                    0x0014
  28 #define SSBI2_MODE2                     0x001C
  29 
  30 /* SSBI_CMD fields */
  31 #define SSBI_CMD_RDWRN                  (1 << 24)
  32 
  33 /* SSBI_STATUS fields */
  34 #define SSBI_STATUS_RD_READY            (1 << 2)
  35 #define SSBI_STATUS_READY               (1 << 1)
  36 #define SSBI_STATUS_MCHN_BUSY           (1 << 0)
  37 
  38 /* SSBI_MODE2 fields */
  39 #define SSBI_MODE2_REG_ADDR_15_8_SHFT   0x04
  40 #define SSBI_MODE2_REG_ADDR_15_8_MASK   (0x7f << SSBI_MODE2_REG_ADDR_15_8_SHFT)
  41 
  42 #define SET_SSBI_MODE2_REG_ADDR_15_8(MD, AD) \
  43         (((MD) & 0x0F) | ((((AD) >> 8) << SSBI_MODE2_REG_ADDR_15_8_SHFT) & \
  44         SSBI_MODE2_REG_ADDR_15_8_MASK))
  45 
  46 /* SSBI PMIC Arbiter command registers */
  47 #define SSBI_PA_CMD                     0x0000
  48 #define SSBI_PA_RD_STATUS               0x0004
  49 
  50 /* SSBI_PA_CMD fields */
  51 #define SSBI_PA_CMD_RDWRN               (1 << 24)
  52 #define SSBI_PA_CMD_ADDR_MASK           0x7fff /* REG_ADDR_7_0, REG_ADDR_8_14*/
  53 
  54 /* SSBI_PA_RD_STATUS fields */
  55 #define SSBI_PA_RD_STATUS_TRANS_DONE    (1 << 27)
  56 #define SSBI_PA_RD_STATUS_TRANS_DENIED  (1 << 26)
  57 
  58 #define SSBI_TIMEOUT_US                 100
  59 
  60 enum ssbi_controller_type {
  61         MSM_SBI_CTRL_SSBI = 0,
  62         MSM_SBI_CTRL_SSBI2,
  63         MSM_SBI_CTRL_PMIC_ARBITER,
  64 };
  65 
  66 struct ssbi {
  67         struct device           *slave;
  68         void __iomem            *base;
  69         spinlock_t              lock;
  70         enum ssbi_controller_type controller_type;
  71         int (*read)(struct ssbi *, u16 addr, u8 *buf, int len);
  72         int (*write)(struct ssbi *, u16 addr, const u8 *buf, int len);
  73 };
  74 
  75 static inline u32 ssbi_readl(struct ssbi *ssbi, u32 reg)
  76 {
  77         return readl(ssbi->base + reg);
  78 }
  79 
  80 static inline void ssbi_writel(struct ssbi *ssbi, u32 val, u32 reg)
  81 {
  82         writel(val, ssbi->base + reg);
  83 }
  84 
  85 /*
  86  * Via private exchange with one of the original authors, the hardware
  87  * should generally finish a transaction in about 5us.  The worst
  88  * case, is when using the arbiter and both other CPUs have just
  89  * started trying to use the SSBI bus will result in a time of about
  90  * 20us.  It should never take longer than this.
  91  *
  92  * As such, this wait merely spins, with a udelay.
  93  */
  94 static int ssbi_wait_mask(struct ssbi *ssbi, u32 set_mask, u32 clr_mask)
  95 {
  96         u32 timeout = SSBI_TIMEOUT_US;
  97         u32 val;
  98 
  99         while (timeout--) {
 100                 val = ssbi_readl(ssbi, SSBI2_STATUS);
 101                 if (((val & set_mask) == set_mask) && ((val & clr_mask) == 0))
 102                         return 0;
 103                 udelay(1);
 104         }
 105 
 106         return -ETIMEDOUT;
 107 }
 108 
 109 static int
 110 ssbi_read_bytes(struct ssbi *ssbi, u16 addr, u8 *buf, int len)
 111 {
 112         u32 cmd = SSBI_CMD_RDWRN | ((addr & 0xff) << 16);
 113         int ret = 0;
 114 
 115         if (ssbi->controller_type == MSM_SBI_CTRL_SSBI2) {
 116                 u32 mode2 = ssbi_readl(ssbi, SSBI2_MODE2);
 117                 mode2 = SET_SSBI_MODE2_REG_ADDR_15_8(mode2, addr);
 118                 ssbi_writel(ssbi, mode2, SSBI2_MODE2);
 119         }
 120 
 121         while (len) {
 122                 ret = ssbi_wait_mask(ssbi, SSBI_STATUS_READY, 0);
 123                 if (ret)
 124                         goto err;
 125 
 126                 ssbi_writel(ssbi, cmd, SSBI2_CMD);
 127                 ret = ssbi_wait_mask(ssbi, SSBI_STATUS_RD_READY, 0);
 128                 if (ret)
 129                         goto err;
 130                 *buf++ = ssbi_readl(ssbi, SSBI2_RD) & 0xff;
 131                 len--;
 132         }
 133 
 134 err:
 135         return ret;
 136 }
 137 
 138 static int
 139 ssbi_write_bytes(struct ssbi *ssbi, u16 addr, const u8 *buf, int len)
 140 {
 141         int ret = 0;
 142 
 143         if (ssbi->controller_type == MSM_SBI_CTRL_SSBI2) {
 144                 u32 mode2 = ssbi_readl(ssbi, SSBI2_MODE2);
 145                 mode2 = SET_SSBI_MODE2_REG_ADDR_15_8(mode2, addr);
 146                 ssbi_writel(ssbi, mode2, SSBI2_MODE2);
 147         }
 148 
 149         while (len) {
 150                 ret = ssbi_wait_mask(ssbi, SSBI_STATUS_READY, 0);
 151                 if (ret)
 152                         goto err;
 153 
 154                 ssbi_writel(ssbi, ((addr & 0xff) << 16) | *buf, SSBI2_CMD);
 155                 ret = ssbi_wait_mask(ssbi, 0, SSBI_STATUS_MCHN_BUSY);
 156                 if (ret)
 157                         goto err;
 158                 buf++;
 159                 len--;
 160         }
 161 
 162 err:
 163         return ret;
 164 }
 165 
 166 /*
 167  * See ssbi_wait_mask for an explanation of the time and the
 168  * busywait.
 169  */
 170 static inline int
 171 ssbi_pa_transfer(struct ssbi *ssbi, u32 cmd, u8 *data)
 172 {
 173         u32 timeout = SSBI_TIMEOUT_US;
 174         u32 rd_status = 0;
 175 
 176         ssbi_writel(ssbi, cmd, SSBI_PA_CMD);
 177 
 178         while (timeout--) {
 179                 rd_status = ssbi_readl(ssbi, SSBI_PA_RD_STATUS);
 180 
 181                 if (rd_status & SSBI_PA_RD_STATUS_TRANS_DENIED)
 182                         return -EPERM;
 183 
 184                 if (rd_status & SSBI_PA_RD_STATUS_TRANS_DONE) {
 185                         if (data)
 186                                 *data = rd_status & 0xff;
 187                         return 0;
 188                 }
 189                 udelay(1);
 190         }
 191 
 192         return -ETIMEDOUT;
 193 }
 194 
 195 static int
 196 ssbi_pa_read_bytes(struct ssbi *ssbi, u16 addr, u8 *buf, int len)
 197 {
 198         u32 cmd;
 199         int ret = 0;
 200 
 201         cmd = SSBI_PA_CMD_RDWRN | (addr & SSBI_PA_CMD_ADDR_MASK) << 8;
 202 
 203         while (len) {
 204                 ret = ssbi_pa_transfer(ssbi, cmd, buf);
 205                 if (ret)
 206                         goto err;
 207                 buf++;
 208                 len--;
 209         }
 210 
 211 err:
 212         return ret;
 213 }
 214 
 215 static int
 216 ssbi_pa_write_bytes(struct ssbi *ssbi, u16 addr, const u8 *buf, int len)
 217 {
 218         u32 cmd;
 219         int ret = 0;
 220 
 221         while (len) {
 222                 cmd = (addr & SSBI_PA_CMD_ADDR_MASK) << 8 | *buf;
 223                 ret = ssbi_pa_transfer(ssbi, cmd, NULL);
 224                 if (ret)
 225                         goto err;
 226                 buf++;
 227                 len--;
 228         }
 229 
 230 err:
 231         return ret;
 232 }
 233 
 234 int ssbi_read(struct device *dev, u16 addr, u8 *buf, int len)
 235 {
 236         struct ssbi *ssbi = dev_get_drvdata(dev);
 237         unsigned long flags;
 238         int ret;
 239 
 240         spin_lock_irqsave(&ssbi->lock, flags);
 241         ret = ssbi->read(ssbi, addr, buf, len);
 242         spin_unlock_irqrestore(&ssbi->lock, flags);
 243 
 244         return ret;
 245 }
 246 EXPORT_SYMBOL_GPL(ssbi_read);
 247 
 248 int ssbi_write(struct device *dev, u16 addr, const u8 *buf, int len)
 249 {
 250         struct ssbi *ssbi = dev_get_drvdata(dev);
 251         unsigned long flags;
 252         int ret;
 253 
 254         spin_lock_irqsave(&ssbi->lock, flags);
 255         ret = ssbi->write(ssbi, addr, buf, len);
 256         spin_unlock_irqrestore(&ssbi->lock, flags);
 257 
 258         return ret;
 259 }
 260 EXPORT_SYMBOL_GPL(ssbi_write);
 261 
 262 static int ssbi_probe(struct platform_device *pdev)
 263 {
 264         struct device_node *np = pdev->dev.of_node;
 265         struct resource *mem_res;
 266         struct ssbi *ssbi;
 267         const char *type;
 268 
 269         ssbi = devm_kzalloc(&pdev->dev, sizeof(*ssbi), GFP_KERNEL);
 270         if (!ssbi)
 271                 return -ENOMEM;
 272 
 273         mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 274         ssbi->base = devm_ioremap_resource(&pdev->dev, mem_res);
 275         if (IS_ERR(ssbi->base))
 276                 return PTR_ERR(ssbi->base);
 277 
 278         platform_set_drvdata(pdev, ssbi);
 279 
 280         type = of_get_property(np, "qcom,controller-type", NULL);
 281         if (type == NULL) {
 282                 dev_err(&pdev->dev, "Missing qcom,controller-type property\n");
 283                 return -EINVAL;
 284         }
 285         dev_info(&pdev->dev, "SSBI controller type: '%s'\n", type);
 286         if (strcmp(type, "ssbi") == 0)
 287                 ssbi->controller_type = MSM_SBI_CTRL_SSBI;
 288         else if (strcmp(type, "ssbi2") == 0)
 289                 ssbi->controller_type = MSM_SBI_CTRL_SSBI2;
 290         else if (strcmp(type, "pmic-arbiter") == 0)
 291                 ssbi->controller_type = MSM_SBI_CTRL_PMIC_ARBITER;
 292         else {
 293                 dev_err(&pdev->dev, "Unknown qcom,controller-type\n");
 294                 return -EINVAL;
 295         }
 296 
 297         if (ssbi->controller_type == MSM_SBI_CTRL_PMIC_ARBITER) {
 298                 ssbi->read = ssbi_pa_read_bytes;
 299                 ssbi->write = ssbi_pa_write_bytes;
 300         } else {
 301                 ssbi->read = ssbi_read_bytes;
 302                 ssbi->write = ssbi_write_bytes;
 303         }
 304 
 305         spin_lock_init(&ssbi->lock);
 306 
 307         return devm_of_platform_populate(&pdev->dev);
 308 }
 309 
 310 static const struct of_device_id ssbi_match_table[] = {
 311         { .compatible = "qcom,ssbi" },
 312         {}
 313 };
 314 MODULE_DEVICE_TABLE(of, ssbi_match_table);
 315 
 316 static struct platform_driver ssbi_driver = {
 317         .probe          = ssbi_probe,
 318         .driver         = {
 319                 .name   = "ssbi",
 320                 .of_match_table = ssbi_match_table,
 321         },
 322 };
 323 module_platform_driver(ssbi_driver);
 324 
 325 MODULE_LICENSE("GPL v2");
 326 MODULE_VERSION("1.0");
 327 MODULE_ALIAS("platform:ssbi");
 328 MODULE_AUTHOR("Dima Zavin <dima@android.com>");

/* [<][>][^][v][top][bottom][index][help] */