Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // Register map access API - I2C support
0004 //
0005 // Copyright 2011 Wolfson Microelectronics plc
0006 //
0007 // Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
0008 
0009 #include <linux/regmap.h>
0010 #include <linux/i2c.h>
0011 #include <linux/module.h>
0012 
0013 #include "internal.h"
0014 
0015 static int regmap_smbus_byte_reg_read(void *context, unsigned int reg,
0016                       unsigned int *val)
0017 {
0018     struct device *dev = context;
0019     struct i2c_client *i2c = to_i2c_client(dev);
0020     int ret;
0021 
0022     if (reg > 0xff)
0023         return -EINVAL;
0024 
0025     ret = i2c_smbus_read_byte_data(i2c, reg);
0026     if (ret < 0)
0027         return ret;
0028 
0029     *val = ret;
0030 
0031     return 0;
0032 }
0033 
0034 static int regmap_smbus_byte_reg_write(void *context, unsigned int reg,
0035                        unsigned int val)
0036 {
0037     struct device *dev = context;
0038     struct i2c_client *i2c = to_i2c_client(dev);
0039 
0040     if (val > 0xff || reg > 0xff)
0041         return -EINVAL;
0042 
0043     return i2c_smbus_write_byte_data(i2c, reg, val);
0044 }
0045 
0046 static const struct regmap_bus regmap_smbus_byte = {
0047     .reg_write = regmap_smbus_byte_reg_write,
0048     .reg_read = regmap_smbus_byte_reg_read,
0049 };
0050 
0051 static int regmap_smbus_word_reg_read(void *context, unsigned int reg,
0052                       unsigned int *val)
0053 {
0054     struct device *dev = context;
0055     struct i2c_client *i2c = to_i2c_client(dev);
0056     int ret;
0057 
0058     if (reg > 0xff)
0059         return -EINVAL;
0060 
0061     ret = i2c_smbus_read_word_data(i2c, reg);
0062     if (ret < 0)
0063         return ret;
0064 
0065     *val = ret;
0066 
0067     return 0;
0068 }
0069 
0070 static int regmap_smbus_word_reg_write(void *context, unsigned int reg,
0071                        unsigned int val)
0072 {
0073     struct device *dev = context;
0074     struct i2c_client *i2c = to_i2c_client(dev);
0075 
0076     if (val > 0xffff || reg > 0xff)
0077         return -EINVAL;
0078 
0079     return i2c_smbus_write_word_data(i2c, reg, val);
0080 }
0081 
0082 static const struct regmap_bus regmap_smbus_word = {
0083     .reg_write = regmap_smbus_word_reg_write,
0084     .reg_read = regmap_smbus_word_reg_read,
0085 };
0086 
0087 static int regmap_smbus_word_read_swapped(void *context, unsigned int reg,
0088                       unsigned int *val)
0089 {
0090     struct device *dev = context;
0091     struct i2c_client *i2c = to_i2c_client(dev);
0092     int ret;
0093 
0094     if (reg > 0xff)
0095         return -EINVAL;
0096 
0097     ret = i2c_smbus_read_word_swapped(i2c, reg);
0098     if (ret < 0)
0099         return ret;
0100 
0101     *val = ret;
0102 
0103     return 0;
0104 }
0105 
0106 static int regmap_smbus_word_write_swapped(void *context, unsigned int reg,
0107                        unsigned int val)
0108 {
0109     struct device *dev = context;
0110     struct i2c_client *i2c = to_i2c_client(dev);
0111 
0112     if (val > 0xffff || reg > 0xff)
0113         return -EINVAL;
0114 
0115     return i2c_smbus_write_word_swapped(i2c, reg, val);
0116 }
0117 
0118 static const struct regmap_bus regmap_smbus_word_swapped = {
0119     .reg_write = regmap_smbus_word_write_swapped,
0120     .reg_read = regmap_smbus_word_read_swapped,
0121 };
0122 
0123 static int regmap_i2c_write(void *context, const void *data, size_t count)
0124 {
0125     struct device *dev = context;
0126     struct i2c_client *i2c = to_i2c_client(dev);
0127     int ret;
0128 
0129     ret = i2c_master_send(i2c, data, count);
0130     if (ret == count)
0131         return 0;
0132     else if (ret < 0)
0133         return ret;
0134     else
0135         return -EIO;
0136 }
0137 
0138 static int regmap_i2c_gather_write(void *context,
0139                    const void *reg, size_t reg_size,
0140                    const void *val, size_t val_size)
0141 {
0142     struct device *dev = context;
0143     struct i2c_client *i2c = to_i2c_client(dev);
0144     struct i2c_msg xfer[2];
0145     int ret;
0146 
0147     /* If the I2C controller can't do a gather tell the core, it
0148      * will substitute in a linear write for us.
0149      */
0150     if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_NOSTART))
0151         return -ENOTSUPP;
0152 
0153     xfer[0].addr = i2c->addr;
0154     xfer[0].flags = 0;
0155     xfer[0].len = reg_size;
0156     xfer[0].buf = (void *)reg;
0157 
0158     xfer[1].addr = i2c->addr;
0159     xfer[1].flags = I2C_M_NOSTART;
0160     xfer[1].len = val_size;
0161     xfer[1].buf = (void *)val;
0162 
0163     ret = i2c_transfer(i2c->adapter, xfer, 2);
0164     if (ret == 2)
0165         return 0;
0166     if (ret < 0)
0167         return ret;
0168     else
0169         return -EIO;
0170 }
0171 
0172 static int regmap_i2c_read(void *context,
0173                const void *reg, size_t reg_size,
0174                void *val, size_t val_size)
0175 {
0176     struct device *dev = context;
0177     struct i2c_client *i2c = to_i2c_client(dev);
0178     struct i2c_msg xfer[2];
0179     int ret;
0180 
0181     xfer[0].addr = i2c->addr;
0182     xfer[0].flags = 0;
0183     xfer[0].len = reg_size;
0184     xfer[0].buf = (void *)reg;
0185 
0186     xfer[1].addr = i2c->addr;
0187     xfer[1].flags = I2C_M_RD;
0188     xfer[1].len = val_size;
0189     xfer[1].buf = val;
0190 
0191     ret = i2c_transfer(i2c->adapter, xfer, 2);
0192     if (ret == 2)
0193         return 0;
0194     else if (ret < 0)
0195         return ret;
0196     else
0197         return -EIO;
0198 }
0199 
0200 static const struct regmap_bus regmap_i2c = {
0201     .write = regmap_i2c_write,
0202     .gather_write = regmap_i2c_gather_write,
0203     .read = regmap_i2c_read,
0204     .reg_format_endian_default = REGMAP_ENDIAN_BIG,
0205     .val_format_endian_default = REGMAP_ENDIAN_BIG,
0206 };
0207 
0208 static int regmap_i2c_smbus_i2c_write(void *context, const void *data,
0209                       size_t count)
0210 {
0211     struct device *dev = context;
0212     struct i2c_client *i2c = to_i2c_client(dev);
0213 
0214     if (count < 1)
0215         return -EINVAL;
0216 
0217     --count;
0218     return i2c_smbus_write_i2c_block_data(i2c, ((u8 *)data)[0], count,
0219                           ((u8 *)data + 1));
0220 }
0221 
0222 static int regmap_i2c_smbus_i2c_read(void *context, const void *reg,
0223                      size_t reg_size, void *val,
0224                      size_t val_size)
0225 {
0226     struct device *dev = context;
0227     struct i2c_client *i2c = to_i2c_client(dev);
0228     int ret;
0229 
0230     if (reg_size != 1 || val_size < 1)
0231         return -EINVAL;
0232 
0233     ret = i2c_smbus_read_i2c_block_data(i2c, ((u8 *)reg)[0], val_size, val);
0234     if (ret == val_size)
0235         return 0;
0236     else if (ret < 0)
0237         return ret;
0238     else
0239         return -EIO;
0240 }
0241 
0242 static const struct regmap_bus regmap_i2c_smbus_i2c_block = {
0243     .write = regmap_i2c_smbus_i2c_write,
0244     .read = regmap_i2c_smbus_i2c_read,
0245     .max_raw_read = I2C_SMBUS_BLOCK_MAX,
0246     .max_raw_write = I2C_SMBUS_BLOCK_MAX,
0247 };
0248 
0249 static int regmap_i2c_smbus_i2c_write_reg16(void *context, const void *data,
0250                       size_t count)
0251 {
0252     struct device *dev = context;
0253     struct i2c_client *i2c = to_i2c_client(dev);
0254 
0255     if (count < 2)
0256         return -EINVAL;
0257 
0258     count--;
0259     return i2c_smbus_write_i2c_block_data(i2c, ((u8 *)data)[0], count,
0260                           (u8 *)data + 1);
0261 }
0262 
0263 static int regmap_i2c_smbus_i2c_read_reg16(void *context, const void *reg,
0264                      size_t reg_size, void *val,
0265                      size_t val_size)
0266 {
0267     struct device *dev = context;
0268     struct i2c_client *i2c = to_i2c_client(dev);
0269     int ret, count, len = val_size;
0270 
0271     if (reg_size != 2)
0272         return -EINVAL;
0273 
0274     ret = i2c_smbus_write_byte_data(i2c, ((u16 *)reg)[0] & 0xff,
0275                     ((u16 *)reg)[0] >> 8);
0276     if (ret < 0)
0277         return ret;
0278 
0279     count = 0;
0280     do {
0281         /* Current Address Read */
0282         ret = i2c_smbus_read_byte(i2c);
0283         if (ret < 0)
0284             break;
0285 
0286         *((u8 *)val++) = ret;
0287         count++;
0288         len--;
0289     } while (len > 0);
0290 
0291     if (count == val_size)
0292         return 0;
0293     else if (ret < 0)
0294         return ret;
0295     else
0296         return -EIO;
0297 }
0298 
0299 static const struct regmap_bus regmap_i2c_smbus_i2c_block_reg16 = {
0300     .write = regmap_i2c_smbus_i2c_write_reg16,
0301     .read = regmap_i2c_smbus_i2c_read_reg16,
0302     .max_raw_read = I2C_SMBUS_BLOCK_MAX,
0303     .max_raw_write = I2C_SMBUS_BLOCK_MAX,
0304 };
0305 
0306 static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c,
0307                     const struct regmap_config *config)
0308 {
0309     const struct i2c_adapter_quirks *quirks;
0310     const struct regmap_bus *bus = NULL;
0311     struct regmap_bus *ret_bus;
0312     u16 max_read = 0, max_write = 0;
0313 
0314     if (i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C))
0315         bus = &regmap_i2c;
0316     else if (config->val_bits == 8 && config->reg_bits == 8 &&
0317          i2c_check_functionality(i2c->adapter,
0318                      I2C_FUNC_SMBUS_I2C_BLOCK))
0319         bus = &regmap_i2c_smbus_i2c_block;
0320     else if (config->val_bits == 8 && config->reg_bits == 16 &&
0321         i2c_check_functionality(i2c->adapter,
0322                     I2C_FUNC_SMBUS_I2C_BLOCK))
0323         bus = &regmap_i2c_smbus_i2c_block_reg16;
0324     else if (config->val_bits == 16 && config->reg_bits == 8 &&
0325          i2c_check_functionality(i2c->adapter,
0326                      I2C_FUNC_SMBUS_WORD_DATA))
0327         switch (regmap_get_val_endian(&i2c->dev, NULL, config)) {
0328         case REGMAP_ENDIAN_LITTLE:
0329             bus = &regmap_smbus_word;
0330             break;
0331         case REGMAP_ENDIAN_BIG:
0332             bus = &regmap_smbus_word_swapped;
0333             break;
0334         default:        /* everything else is not supported */
0335             break;
0336         }
0337     else if (config->val_bits == 8 && config->reg_bits == 8 &&
0338          i2c_check_functionality(i2c->adapter,
0339                      I2C_FUNC_SMBUS_BYTE_DATA))
0340         bus = &regmap_smbus_byte;
0341 
0342     if (!bus)
0343         return ERR_PTR(-ENOTSUPP);
0344 
0345     quirks = i2c->adapter->quirks;
0346     if (quirks) {
0347         if (quirks->max_read_len &&
0348             (bus->max_raw_read == 0 || bus->max_raw_read > quirks->max_read_len))
0349             max_read = quirks->max_read_len;
0350 
0351         if (quirks->max_write_len &&
0352             (bus->max_raw_write == 0 || bus->max_raw_write > quirks->max_write_len))
0353             max_write = quirks->max_write_len;
0354 
0355         if (max_read || max_write) {
0356             ret_bus = kmemdup(bus, sizeof(*bus), GFP_KERNEL);
0357             if (!ret_bus)
0358                 return ERR_PTR(-ENOMEM);
0359             ret_bus->free_on_exit = true;
0360             ret_bus->max_raw_read = max_read;
0361             ret_bus->max_raw_write = max_write;
0362             bus = ret_bus;
0363         }
0364     }
0365 
0366     return bus;
0367 }
0368 
0369 struct regmap *__regmap_init_i2c(struct i2c_client *i2c,
0370                  const struct regmap_config *config,
0371                  struct lock_class_key *lock_key,
0372                  const char *lock_name)
0373 {
0374     const struct regmap_bus *bus = regmap_get_i2c_bus(i2c, config);
0375 
0376     if (IS_ERR(bus))
0377         return ERR_CAST(bus);
0378 
0379     return __regmap_init(&i2c->dev, bus, &i2c->dev, config,
0380                  lock_key, lock_name);
0381 }
0382 EXPORT_SYMBOL_GPL(__regmap_init_i2c);
0383 
0384 struct regmap *__devm_regmap_init_i2c(struct i2c_client *i2c,
0385                       const struct regmap_config *config,
0386                       struct lock_class_key *lock_key,
0387                       const char *lock_name)
0388 {
0389     const struct regmap_bus *bus = regmap_get_i2c_bus(i2c, config);
0390 
0391     if (IS_ERR(bus))
0392         return ERR_CAST(bus);
0393 
0394     return __devm_regmap_init(&i2c->dev, bus, &i2c->dev, config,
0395                   lock_key, lock_name);
0396 }
0397 EXPORT_SYMBOL_GPL(__devm_regmap_init_i2c);
0398 
0399 MODULE_LICENSE("GPL");