root/drivers/base/regmap/regmap-spmi.c

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

DEFINITIONS

This source file includes following definitions.
  1. regmap_spmi_base_read
  2. regmap_spmi_base_gather_write
  3. regmap_spmi_base_write
  4. __regmap_init_spmi_base
  5. __devm_regmap_init_spmi_base
  6. regmap_spmi_ext_read
  7. regmap_spmi_ext_gather_write
  8. regmap_spmi_ext_write
  9. __regmap_init_spmi_ext
  10. __devm_regmap_init_spmi_ext

   1 // SPDX-License-Identifier: GPL-2.0
   2 //
   3 // Register map access API - SPMI support
   4 //
   5 // Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
   6 //
   7 // Based on regmap-i2c.c:
   8 // Copyright 2011 Wolfson Microelectronics plc
   9 // Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
  10 
  11 #include <linux/regmap.h>
  12 #include <linux/spmi.h>
  13 #include <linux/module.h>
  14 #include <linux/init.h>
  15 
  16 static int regmap_spmi_base_read(void *context,
  17                                  const void *reg, size_t reg_size,
  18                                  void *val, size_t val_size)
  19 {
  20         u8 addr = *(u8 *)reg;
  21         int err = 0;
  22 
  23         BUG_ON(reg_size != 1);
  24 
  25         while (val_size-- && !err)
  26                 err = spmi_register_read(context, addr++, val++);
  27 
  28         return err;
  29 }
  30 
  31 static int regmap_spmi_base_gather_write(void *context,
  32                                          const void *reg, size_t reg_size,
  33                                          const void *val, size_t val_size)
  34 {
  35         const u8 *data = val;
  36         u8 addr = *(u8 *)reg;
  37         int err = 0;
  38 
  39         BUG_ON(reg_size != 1);
  40 
  41         /*
  42          * SPMI defines a more bandwidth-efficient 'Register 0 Write' sequence,
  43          * use it when possible.
  44          */
  45         if (addr == 0 && val_size) {
  46                 err = spmi_register_zero_write(context, *data);
  47                 if (err)
  48                         goto err_out;
  49 
  50                 data++;
  51                 addr++;
  52                 val_size--;
  53         }
  54 
  55         while (val_size) {
  56                 err = spmi_register_write(context, addr, *data);
  57                 if (err)
  58                         goto err_out;
  59 
  60                 data++;
  61                 addr++;
  62                 val_size--;
  63         }
  64 
  65 err_out:
  66         return err;
  67 }
  68 
  69 static int regmap_spmi_base_write(void *context, const void *data,
  70                                   size_t count)
  71 {
  72         BUG_ON(count < 1);
  73         return regmap_spmi_base_gather_write(context, data, 1, data + 1,
  74                                              count - 1);
  75 }
  76 
  77 static const struct regmap_bus regmap_spmi_base = {
  78         .read                           = regmap_spmi_base_read,
  79         .write                          = regmap_spmi_base_write,
  80         .gather_write                   = regmap_spmi_base_gather_write,
  81         .reg_format_endian_default      = REGMAP_ENDIAN_NATIVE,
  82         .val_format_endian_default      = REGMAP_ENDIAN_NATIVE,
  83 };
  84 
  85 struct regmap *__regmap_init_spmi_base(struct spmi_device *sdev,
  86                                        const struct regmap_config *config,
  87                                        struct lock_class_key *lock_key,
  88                                        const char *lock_name)
  89 {
  90         return __regmap_init(&sdev->dev, &regmap_spmi_base, sdev, config,
  91                              lock_key, lock_name);
  92 }
  93 EXPORT_SYMBOL_GPL(__regmap_init_spmi_base);
  94 
  95 struct regmap *__devm_regmap_init_spmi_base(struct spmi_device *sdev,
  96                                             const struct regmap_config *config,
  97                                             struct lock_class_key *lock_key,
  98                                             const char *lock_name)
  99 {
 100         return __devm_regmap_init(&sdev->dev, &regmap_spmi_base, sdev, config,
 101                                   lock_key, lock_name);
 102 }
 103 EXPORT_SYMBOL_GPL(__devm_regmap_init_spmi_base);
 104 
 105 static int regmap_spmi_ext_read(void *context,
 106                                 const void *reg, size_t reg_size,
 107                                 void *val, size_t val_size)
 108 {
 109         int err = 0;
 110         size_t len;
 111         u16 addr;
 112 
 113         BUG_ON(reg_size != 2);
 114 
 115         addr = *(u16 *)reg;
 116 
 117         /*
 118          * Split accesses into two to take advantage of the more
 119          * bandwidth-efficient 'Extended Register Read' command when possible
 120          */
 121         while (addr <= 0xFF && val_size) {
 122                 len = min_t(size_t, val_size, 16);
 123 
 124                 err = spmi_ext_register_read(context, addr, val, len);
 125                 if (err)
 126                         goto err_out;
 127 
 128                 addr += len;
 129                 val += len;
 130                 val_size -= len;
 131         }
 132 
 133         while (val_size) {
 134                 len = min_t(size_t, val_size, 8);
 135 
 136                 err = spmi_ext_register_readl(context, addr, val, len);
 137                 if (err)
 138                         goto err_out;
 139 
 140                 addr += len;
 141                 val += len;
 142                 val_size -= len;
 143         }
 144 
 145 err_out:
 146         return err;
 147 }
 148 
 149 static int regmap_spmi_ext_gather_write(void *context,
 150                                         const void *reg, size_t reg_size,
 151                                         const void *val, size_t val_size)
 152 {
 153         int err = 0;
 154         size_t len;
 155         u16 addr;
 156 
 157         BUG_ON(reg_size != 2);
 158 
 159         addr = *(u16 *)reg;
 160 
 161         while (addr <= 0xFF && val_size) {
 162                 len = min_t(size_t, val_size, 16);
 163 
 164                 err = spmi_ext_register_write(context, addr, val, len);
 165                 if (err)
 166                         goto err_out;
 167 
 168                 addr += len;
 169                 val += len;
 170                 val_size -= len;
 171         }
 172 
 173         while (val_size) {
 174                 len = min_t(size_t, val_size, 8);
 175 
 176                 err = spmi_ext_register_writel(context, addr, val, len);
 177                 if (err)
 178                         goto err_out;
 179 
 180                 addr += len;
 181                 val += len;
 182                 val_size -= len;
 183         }
 184 
 185 err_out:
 186         return err;
 187 }
 188 
 189 static int regmap_spmi_ext_write(void *context, const void *data,
 190                                  size_t count)
 191 {
 192         BUG_ON(count < 2);
 193         return regmap_spmi_ext_gather_write(context, data, 2, data + 2,
 194                                             count - 2);
 195 }
 196 
 197 static const struct regmap_bus regmap_spmi_ext = {
 198         .read                           = regmap_spmi_ext_read,
 199         .write                          = regmap_spmi_ext_write,
 200         .gather_write                   = regmap_spmi_ext_gather_write,
 201         .reg_format_endian_default      = REGMAP_ENDIAN_NATIVE,
 202         .val_format_endian_default      = REGMAP_ENDIAN_NATIVE,
 203 };
 204 
 205 struct regmap *__regmap_init_spmi_ext(struct spmi_device *sdev,
 206                                       const struct regmap_config *config,
 207                                       struct lock_class_key *lock_key,
 208                                       const char *lock_name)
 209 {
 210         return __regmap_init(&sdev->dev, &regmap_spmi_ext, sdev, config,
 211                              lock_key, lock_name);
 212 }
 213 EXPORT_SYMBOL_GPL(__regmap_init_spmi_ext);
 214 
 215 struct regmap *__devm_regmap_init_spmi_ext(struct spmi_device *sdev,
 216                                            const struct regmap_config *config,
 217                                            struct lock_class_key *lock_key,
 218                                            const char *lock_name)
 219 {
 220         return __devm_regmap_init(&sdev->dev, &regmap_spmi_ext, sdev, config,
 221                                   lock_key, lock_name);
 222 }
 223 EXPORT_SYMBOL_GPL(__devm_regmap_init_spmi_ext);
 224 
 225 MODULE_LICENSE("GPL");

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