^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // Register map access API - I2C support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) // Copyright 2011 Wolfson Microelectronics plc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) // Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) static int regmap_smbus_byte_reg_read(void *context, unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) unsigned int *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) struct device *dev = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct i2c_client *i2c = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) if (reg > 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) ret = i2c_smbus_read_byte_data(i2c, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) *val = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static int regmap_smbus_byte_reg_write(void *context, unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) unsigned int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct device *dev = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct i2c_client *i2c = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (val > 0xff || reg > 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) return i2c_smbus_write_byte_data(i2c, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static const struct regmap_bus regmap_smbus_byte = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) .reg_write = regmap_smbus_byte_reg_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .reg_read = regmap_smbus_byte_reg_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static int regmap_smbus_word_reg_read(void *context, unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) unsigned int *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct device *dev = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct i2c_client *i2c = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if (reg > 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) ret = i2c_smbus_read_word_data(i2c, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) *val = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static int regmap_smbus_word_reg_write(void *context, unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) unsigned int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct device *dev = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct i2c_client *i2c = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (val > 0xffff || reg > 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return i2c_smbus_write_word_data(i2c, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static const struct regmap_bus regmap_smbus_word = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .reg_write = regmap_smbus_word_reg_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .reg_read = regmap_smbus_word_reg_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static int regmap_smbus_word_read_swapped(void *context, unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) unsigned int *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct device *dev = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct i2c_client *i2c = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (reg > 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) ret = i2c_smbus_read_word_swapped(i2c, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) *val = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static int regmap_smbus_word_write_swapped(void *context, unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) unsigned int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct device *dev = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct i2c_client *i2c = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (val > 0xffff || reg > 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return i2c_smbus_write_word_swapped(i2c, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static const struct regmap_bus regmap_smbus_word_swapped = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) .reg_write = regmap_smbus_word_write_swapped,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) .reg_read = regmap_smbus_word_read_swapped,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static int regmap_i2c_write(void *context, const void *data, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct device *dev = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct i2c_client *i2c = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) ret = i2c_master_send(i2c, data, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (ret == count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) else if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static int regmap_i2c_gather_write(void *context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) const void *reg, size_t reg_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) const void *val, size_t val_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct device *dev = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct i2c_client *i2c = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct i2c_msg xfer[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /* If the I2C controller can't do a gather tell the core, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * will substitute in a linear write for us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_NOSTART))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) xfer[0].addr = i2c->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) xfer[0].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) xfer[0].len = reg_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) xfer[0].buf = (void *)reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) xfer[1].addr = i2c->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) xfer[1].flags = I2C_M_NOSTART;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) xfer[1].len = val_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) xfer[1].buf = (void *)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) ret = i2c_transfer(i2c->adapter, xfer, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (ret == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static int regmap_i2c_read(void *context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) const void *reg, size_t reg_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) void *val, size_t val_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct device *dev = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct i2c_client *i2c = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct i2c_msg xfer[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) xfer[0].addr = i2c->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) xfer[0].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) xfer[0].len = reg_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) xfer[0].buf = (void *)reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) xfer[1].addr = i2c->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) xfer[1].flags = I2C_M_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) xfer[1].len = val_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) xfer[1].buf = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) ret = i2c_transfer(i2c->adapter, xfer, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (ret == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) else if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static const struct regmap_bus regmap_i2c = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) .write = regmap_i2c_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) .gather_write = regmap_i2c_gather_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) .read = regmap_i2c_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) .reg_format_endian_default = REGMAP_ENDIAN_BIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) .val_format_endian_default = REGMAP_ENDIAN_BIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static int regmap_i2c_smbus_i2c_write(void *context, const void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct device *dev = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct i2c_client *i2c = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (count < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) --count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return i2c_smbus_write_i2c_block_data(i2c, ((u8 *)data)[0], count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ((u8 *)data + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static int regmap_i2c_smbus_i2c_read(void *context, const void *reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) size_t reg_size, void *val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) size_t val_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct device *dev = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct i2c_client *i2c = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (reg_size != 1 || val_size < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) ret = i2c_smbus_read_i2c_block_data(i2c, ((u8 *)reg)[0], val_size, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (ret == val_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) else if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static const struct regmap_bus regmap_i2c_smbus_i2c_block = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) .write = regmap_i2c_smbus_i2c_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) .read = regmap_i2c_smbus_i2c_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) .max_raw_read = I2C_SMBUS_BLOCK_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) .max_raw_write = I2C_SMBUS_BLOCK_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static int regmap_i2c_smbus_i2c_write_reg16(void *context, const void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct device *dev = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct i2c_client *i2c = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (count < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return i2c_smbus_write_i2c_block_data(i2c, ((u8 *)data)[0], count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) (u8 *)data + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static int regmap_i2c_smbus_i2c_read_reg16(void *context, const void *reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) size_t reg_size, void *val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) size_t val_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct device *dev = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct i2c_client *i2c = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) int ret, count, len = val_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (reg_size != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ret = i2c_smbus_write_byte_data(i2c, ((u16 *)reg)[0] & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) ((u16 *)reg)[0] >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* Current Address Read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) ret = i2c_smbus_read_byte(i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) *((u8 *)val++) = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) } while (len > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (count == val_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) else if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static const struct regmap_bus regmap_i2c_smbus_i2c_block_reg16 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) .write = regmap_i2c_smbus_i2c_write_reg16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) .read = regmap_i2c_smbus_i2c_read_reg16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) .max_raw_read = I2C_SMBUS_BLOCK_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) .max_raw_write = I2C_SMBUS_BLOCK_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) const struct regmap_config *config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return ®map_i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) else if (config->val_bits == 8 && config->reg_bits == 8 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) i2c_check_functionality(i2c->adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) I2C_FUNC_SMBUS_I2C_BLOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return ®map_i2c_smbus_i2c_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) else if (config->val_bits == 8 && config->reg_bits == 16 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) i2c_check_functionality(i2c->adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) I2C_FUNC_SMBUS_I2C_BLOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return ®map_i2c_smbus_i2c_block_reg16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) else if (config->val_bits == 16 && config->reg_bits == 8 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) i2c_check_functionality(i2c->adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) I2C_FUNC_SMBUS_WORD_DATA))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) switch (regmap_get_val_endian(&i2c->dev, NULL, config)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) case REGMAP_ENDIAN_LITTLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return ®map_smbus_word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) case REGMAP_ENDIAN_BIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return ®map_smbus_word_swapped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) default: /* everything else is not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) else if (config->val_bits == 8 && config->reg_bits == 8 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) i2c_check_functionality(i2c->adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) I2C_FUNC_SMBUS_BYTE_DATA))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return ®map_smbus_byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return ERR_PTR(-ENOTSUPP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) struct regmap *__regmap_init_i2c(struct i2c_client *i2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) const struct regmap_config *config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) struct lock_class_key *lock_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) const char *lock_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) const struct regmap_bus *bus = regmap_get_i2c_bus(i2c, config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (IS_ERR(bus))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return ERR_CAST(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return __regmap_init(&i2c->dev, bus, &i2c->dev, config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) lock_key, lock_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) EXPORT_SYMBOL_GPL(__regmap_init_i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct regmap *__devm_regmap_init_i2c(struct i2c_client *i2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) const struct regmap_config *config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct lock_class_key *lock_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) const char *lock_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) const struct regmap_bus *bus = regmap_get_i2c_bus(i2c, config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (IS_ERR(bus))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return ERR_CAST(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return __devm_regmap_init(&i2c->dev, bus, &i2c->dev, config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) lock_key, lock_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) EXPORT_SYMBOL_GPL(__devm_regmap_init_i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) MODULE_LICENSE("GPL");