Loading drivers/base/regmap/regmap-i2c.c +61 −0 Original line number Diff line number Diff line Loading @@ -246,6 +246,63 @@ static const struct regmap_bus regmap_i2c_smbus_i2c_block = { .max_raw_write = I2C_SMBUS_BLOCK_MAX, }; static int regmap_i2c_smbus_i2c_write_reg16(void *context, const void *data, size_t count) { struct device *dev = context; struct i2c_client *i2c = to_i2c_client(dev); if (count < 2) return -EINVAL; count--; return i2c_smbus_write_i2c_block_data(i2c, ((u8 *)data)[0], count, (u8 *)data + 1); } static int regmap_i2c_smbus_i2c_read_reg16(void *context, const void *reg, size_t reg_size, void *val, size_t val_size) { struct device *dev = context; struct i2c_client *i2c = to_i2c_client(dev); int ret, count, len = val_size; if (reg_size != 2) return -EINVAL; ret = i2c_smbus_write_byte_data(i2c, ((u16 *)reg)[0] & 0xff, ((u16 *)reg)[0] >> 8); if (ret < 0) return ret; count = 0; do { /* Current Address Read */ ret = i2c_smbus_read_byte(i2c); if (ret < 0) break; *((u8 *)val++) = ret; count++; len--; } while (len > 0); if (count == val_size) return 0; else if (ret < 0) return ret; else return -EIO; } static const struct regmap_bus regmap_i2c_smbus_i2c_block_reg16 = { .write = regmap_i2c_smbus_i2c_write_reg16, .read = regmap_i2c_smbus_i2c_read_reg16, .max_raw_read = I2C_SMBUS_BLOCK_MAX, .max_raw_write = I2C_SMBUS_BLOCK_MAX, }; static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c, const struct regmap_config *config) { Loading @@ -255,6 +312,10 @@ static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c, i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) return ®map_i2c_smbus_i2c_block; else if (config->val_bits == 8 && config->reg_bits == 16 && i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) return ®map_i2c_smbus_i2c_block_reg16; else if (config->val_bits == 16 && config->reg_bits == 8 && i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_WORD_DATA)) Loading drivers/base/regmap/regmap-irq.c +68 −16 Original line number Diff line number Diff line Loading @@ -541,8 +541,9 @@ static const struct irq_domain_ops regmap_domain_ops = { }; /** * regmap_add_irq_chip() - Use standard regmap IRQ controller handling * regmap_add_irq_chip_np() - Use standard regmap IRQ controller handling * * @np: The device_node where the IRQ domain should be added to. * @map: The regmap for the device. * @irq: The IRQ the device uses to signal interrupts. * @irq_flags: The IRQF_ flags to use for the primary interrupt. Loading @@ -556,8 +557,9 @@ static const struct irq_domain_ops regmap_domain_ops = { * register cache. The chip driver is responsible for restoring the * register values used by the IRQ controller over suspend and resume. */ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, int irq_base, const struct regmap_irq_chip *chip, int regmap_add_irq_chip_np(struct device_node *np, struct regmap *map, int irq, int irq_flags, int irq_base, const struct regmap_irq_chip *chip, struct regmap_irq_chip_data **data) { struct regmap_irq_chip_data *d; Loading Loading @@ -769,12 +771,10 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, } if (irq_base) d->domain = irq_domain_add_legacy(map->dev->of_node, chip->num_irqs, irq_base, 0, ®map_domain_ops, d); d->domain = irq_domain_add_legacy(np, chip->num_irqs, irq_base, 0, ®map_domain_ops, d); else d->domain = irq_domain_add_linear(map->dev->of_node, chip->num_irqs, d->domain = irq_domain_add_linear(np, chip->num_irqs, ®map_domain_ops, d); if (!d->domain) { dev_err(map->dev, "Failed to create IRQ domain\n"); Loading Loading @@ -808,6 +808,30 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, kfree(d); return ret; } EXPORT_SYMBOL_GPL(regmap_add_irq_chip_np); /** * regmap_add_irq_chip() - Use standard regmap IRQ controller handling * * @map: The regmap for the device. * @irq: The IRQ the device uses to signal interrupts. * @irq_flags: The IRQF_ flags to use for the primary interrupt. * @irq_base: Allocate at specific IRQ number if irq_base > 0. * @chip: Configuration for the interrupt controller. * @data: Runtime data structure for the controller, allocated on success. * * Returns 0 on success or an errno on failure. * * This is the same as regmap_add_irq_chip_np, except that the device * node of the regmap is used. */ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, int irq_base, const struct regmap_irq_chip *chip, struct regmap_irq_chip_data **data) { return regmap_add_irq_chip_np(map->dev->of_node, map, irq, irq_flags, irq_base, chip, data); } EXPORT_SYMBOL_GPL(regmap_add_irq_chip); /** Loading Loading @@ -875,9 +899,10 @@ static int devm_regmap_irq_chip_match(struct device *dev, void *res, void *data) } /** * devm_regmap_add_irq_chip() - Resource manager regmap_add_irq_chip() * devm_regmap_add_irq_chip_np() - Resource manager regmap_add_irq_chip_np() * * @dev: The device pointer on which irq_chip belongs to. * @np: The device_node where the IRQ domain should be added to. * @map: The regmap for the device. * @irq: The IRQ the device uses to signal interrupts * @irq_flags: The IRQF_ flags to use for the primary interrupt. Loading @@ -890,8 +915,9 @@ static int devm_regmap_irq_chip_match(struct device *dev, void *res, void *data) * The ®map_irq_chip_data will be automatically released when the device is * unbound. */ int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq, int irq_flags, int irq_base, int devm_regmap_add_irq_chip_np(struct device *dev, struct device_node *np, struct regmap *map, int irq, int irq_flags, int irq_base, const struct regmap_irq_chip *chip, struct regmap_irq_chip_data **data) { Loading @@ -903,7 +929,7 @@ int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq, if (!ptr) return -ENOMEM; ret = regmap_add_irq_chip(map, irq, irq_flags, irq_base, ret = regmap_add_irq_chip_np(np, map, irq, irq_flags, irq_base, chip, &d); if (ret < 0) { devres_free(ptr); Loading @@ -915,6 +941,32 @@ int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq, *data = d; return 0; } EXPORT_SYMBOL_GPL(devm_regmap_add_irq_chip_np); /** * devm_regmap_add_irq_chip() - Resource manager regmap_add_irq_chip() * * @dev: The device pointer on which irq_chip belongs to. * @map: The regmap for the device. * @irq: The IRQ the device uses to signal interrupts * @irq_flags: The IRQF_ flags to use for the primary interrupt. * @irq_base: Allocate at specific IRQ number if irq_base > 0. * @chip: Configuration for the interrupt controller. * @data: Runtime data structure for the controller, allocated on success * * Returns 0 on success or an errno on failure. * * The ®map_irq_chip_data will be automatically released when the device is * unbound. */ int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq, int irq_flags, int irq_base, const struct regmap_irq_chip *chip, struct regmap_irq_chip_data **data) { return devm_regmap_add_irq_chip_np(dev, map->dev->of_node, map, irq, irq_flags, irq_base, chip, data); } EXPORT_SYMBOL_GPL(devm_regmap_add_irq_chip); /** Loading drivers/base/regmap/regmap.c +23 −0 Original line number Diff line number Diff line Loading @@ -827,6 +827,7 @@ struct regmap *__regmap_init(struct device *dev, } else if (!bus->read || !bus->write) { map->reg_read = _regmap_bus_reg_read; map->reg_write = _regmap_bus_reg_write; map->reg_update_bits = bus->reg_update_bits; map->defer_caching = false; goto skip_format_initialization; Loading Loading @@ -2936,6 +2937,28 @@ int regmap_update_bits_base(struct regmap *map, unsigned int reg, } EXPORT_SYMBOL_GPL(regmap_update_bits_base); /** * regmap_test_bits() - Check if all specified bits are set in a register. * * @map: Register map to operate on * @reg: Register to read from * @bits: Bits to test * * Returns -1 if the underlying regmap_read() fails, 0 if at least one of the * tested bits is not set and 1 if all tested bits are set. */ int regmap_test_bits(struct regmap *map, unsigned int reg, unsigned int bits) { unsigned int val, ret; ret = regmap_read(map, reg, &val); if (ret) return ret; return (val & bits) == bits; } EXPORT_SYMBOL_GPL(regmap_test_bits); void regmap_async_complete_cb(struct regmap_async *async, int ret) { struct regmap *map = async->map; Loading include/linux/regmap.h +70 −39 Original line number Diff line number Diff line Loading @@ -17,10 +17,12 @@ #include <linux/err.h> #include <linux/bug.h> #include <linux/lockdep.h> #include <linux/iopoll.h> struct module; struct clk; struct device; struct device_node; struct i2c_client; struct i3c_device; struct irq_domain; Loading Loading @@ -71,6 +73,13 @@ struct reg_sequence { unsigned int delay_us; }; #define REG_SEQ(_reg, _def, _delay_us) { \ .reg = _reg, \ .def = _def, \ .delay_us = _delay_us, \ } #define REG_SEQ0(_reg, _def) REG_SEQ(_reg, _def, 0) #define regmap_update_bits(map, reg, mask, val) \ regmap_update_bits_base(map, reg, mask, val, NULL, false, false) #define regmap_update_bits_async(map, reg, mask, val)\ Loading Loading @@ -122,26 +131,10 @@ struct reg_sequence { */ #define regmap_read_poll_timeout(map, addr, val, cond, sleep_us, timeout_us) \ ({ \ u64 __timeout_us = (timeout_us); \ unsigned long __sleep_us = (sleep_us); \ ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \ int __ret; \ might_sleep_if(__sleep_us); \ for (;;) { \ __ret = regmap_read((map), (addr), &(val)); \ if (__ret) \ break; \ if (cond) \ break; \ if ((__timeout_us) && \ ktime_compare(ktime_get(), __timeout) > 0) { \ __ret = regmap_read((map), (addr), &(val)); \ break; \ } \ if (__sleep_us) \ usleep_range((__sleep_us >> 2) + 1, __sleep_us); \ } \ __ret ?: ((cond) ? 0 : -ETIMEDOUT); \ int __ret, __tmp; \ __tmp = read_poll_timeout(regmap_read, __ret, __ret || (cond), \ sleep_us, timeout_us, false, (map), (addr), &(val)); \ __ret ?: __tmp; \ }) /** Loading Loading @@ -209,25 +202,10 @@ struct reg_sequence { */ #define regmap_field_read_poll_timeout(field, val, cond, sleep_us, timeout_us) \ ({ \ u64 __timeout_us = (timeout_us); \ unsigned long __sleep_us = (sleep_us); \ ktime_t timeout = ktime_add_us(ktime_get(), __timeout_us); \ int pollret; \ might_sleep_if(__sleep_us); \ for (;;) { \ pollret = regmap_field_read((field), &(val)); \ if (pollret) \ break; \ if (cond) \ break; \ if (__timeout_us && ktime_compare(ktime_get(), timeout) > 0) { \ pollret = regmap_field_read((field), &(val)); \ break; \ } \ if (__sleep_us) \ usleep_range((__sleep_us >> 2) + 1, __sleep_us); \ } \ pollret ?: ((cond) ? 0 : -ETIMEDOUT); \ int __ret, __tmp; \ __tmp = read_poll_timeout(regmap_field_read, __ret, __ret || (cond), \ sleep_us, timeout_us, false, (field), &(val)); \ __ret ?: __tmp; \ }) #ifdef CONFIG_REGMAP Loading Loading @@ -1111,6 +1089,21 @@ bool regmap_reg_in_ranges(unsigned int reg, const struct regmap_range *ranges, unsigned int nranges); static inline int regmap_set_bits(struct regmap *map, unsigned int reg, unsigned int bits) { return regmap_update_bits_base(map, reg, bits, bits, NULL, false, false); } static inline int regmap_clear_bits(struct regmap *map, unsigned int reg, unsigned int bits) { return regmap_update_bits_base(map, reg, bits, 0, NULL, false, false); } int regmap_test_bits(struct regmap *map, unsigned int reg, unsigned int bits); /** * struct reg_field - Description of an register field * Loading @@ -1134,6 +1127,14 @@ struct reg_field { .msb = _msb, \ } #define REG_FIELD_ID(_reg, _lsb, _msb, _size, _offset) { \ .reg = _reg, \ .lsb = _lsb, \ .msb = _msb, \ .id_size = _size, \ .id_offset = _offset, \ } struct regmap_field *regmap_field_alloc(struct regmap *regmap, struct reg_field reg_field); void regmap_field_free(struct regmap_field *field); Loading Loading @@ -1310,12 +1311,21 @@ struct regmap_irq_chip_data; int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, int irq_base, const struct regmap_irq_chip *chip, struct regmap_irq_chip_data **data); int regmap_add_irq_chip_np(struct device_node *np, struct regmap *map, int irq, int irq_flags, int irq_base, const struct regmap_irq_chip *chip, struct regmap_irq_chip_data **data); void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *data); int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq, int irq_flags, int irq_base, const struct regmap_irq_chip *chip, struct regmap_irq_chip_data **data); int devm_regmap_add_irq_chip_np(struct device *dev, struct device_node *np, struct regmap *map, int irq, int irq_flags, int irq_base, const struct regmap_irq_chip *chip, struct regmap_irq_chip_data **data); void devm_regmap_del_irq_chip(struct device *dev, int irq, struct regmap_irq_chip_data *data); Loading Loading @@ -1410,6 +1420,27 @@ static inline int regmap_update_bits_base(struct regmap *map, unsigned int reg, return -EINVAL; } static inline int regmap_set_bits(struct regmap *map, unsigned int reg, unsigned int bits) { WARN_ONCE(1, "regmap API is disabled"); return -EINVAL; } static inline int regmap_clear_bits(struct regmap *map, unsigned int reg, unsigned int bits) { WARN_ONCE(1, "regmap API is disabled"); return -EINVAL; } static inline int regmap_test_bits(struct regmap *map, unsigned int reg, unsigned int bits) { WARN_ONCE(1, "regmap API is disabled"); return -EINVAL; } static inline int regmap_field_update_bits_base(struct regmap_field *field, unsigned int mask, unsigned int val, bool *change, bool async, bool force) Loading Loading
drivers/base/regmap/regmap-i2c.c +61 −0 Original line number Diff line number Diff line Loading @@ -246,6 +246,63 @@ static const struct regmap_bus regmap_i2c_smbus_i2c_block = { .max_raw_write = I2C_SMBUS_BLOCK_MAX, }; static int regmap_i2c_smbus_i2c_write_reg16(void *context, const void *data, size_t count) { struct device *dev = context; struct i2c_client *i2c = to_i2c_client(dev); if (count < 2) return -EINVAL; count--; return i2c_smbus_write_i2c_block_data(i2c, ((u8 *)data)[0], count, (u8 *)data + 1); } static int regmap_i2c_smbus_i2c_read_reg16(void *context, const void *reg, size_t reg_size, void *val, size_t val_size) { struct device *dev = context; struct i2c_client *i2c = to_i2c_client(dev); int ret, count, len = val_size; if (reg_size != 2) return -EINVAL; ret = i2c_smbus_write_byte_data(i2c, ((u16 *)reg)[0] & 0xff, ((u16 *)reg)[0] >> 8); if (ret < 0) return ret; count = 0; do { /* Current Address Read */ ret = i2c_smbus_read_byte(i2c); if (ret < 0) break; *((u8 *)val++) = ret; count++; len--; } while (len > 0); if (count == val_size) return 0; else if (ret < 0) return ret; else return -EIO; } static const struct regmap_bus regmap_i2c_smbus_i2c_block_reg16 = { .write = regmap_i2c_smbus_i2c_write_reg16, .read = regmap_i2c_smbus_i2c_read_reg16, .max_raw_read = I2C_SMBUS_BLOCK_MAX, .max_raw_write = I2C_SMBUS_BLOCK_MAX, }; static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c, const struct regmap_config *config) { Loading @@ -255,6 +312,10 @@ static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c, i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) return ®map_i2c_smbus_i2c_block; else if (config->val_bits == 8 && config->reg_bits == 16 && i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) return ®map_i2c_smbus_i2c_block_reg16; else if (config->val_bits == 16 && config->reg_bits == 8 && i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_WORD_DATA)) Loading
drivers/base/regmap/regmap-irq.c +68 −16 Original line number Diff line number Diff line Loading @@ -541,8 +541,9 @@ static const struct irq_domain_ops regmap_domain_ops = { }; /** * regmap_add_irq_chip() - Use standard regmap IRQ controller handling * regmap_add_irq_chip_np() - Use standard regmap IRQ controller handling * * @np: The device_node where the IRQ domain should be added to. * @map: The regmap for the device. * @irq: The IRQ the device uses to signal interrupts. * @irq_flags: The IRQF_ flags to use for the primary interrupt. Loading @@ -556,8 +557,9 @@ static const struct irq_domain_ops regmap_domain_ops = { * register cache. The chip driver is responsible for restoring the * register values used by the IRQ controller over suspend and resume. */ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, int irq_base, const struct regmap_irq_chip *chip, int regmap_add_irq_chip_np(struct device_node *np, struct regmap *map, int irq, int irq_flags, int irq_base, const struct regmap_irq_chip *chip, struct regmap_irq_chip_data **data) { struct regmap_irq_chip_data *d; Loading Loading @@ -769,12 +771,10 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, } if (irq_base) d->domain = irq_domain_add_legacy(map->dev->of_node, chip->num_irqs, irq_base, 0, ®map_domain_ops, d); d->domain = irq_domain_add_legacy(np, chip->num_irqs, irq_base, 0, ®map_domain_ops, d); else d->domain = irq_domain_add_linear(map->dev->of_node, chip->num_irqs, d->domain = irq_domain_add_linear(np, chip->num_irqs, ®map_domain_ops, d); if (!d->domain) { dev_err(map->dev, "Failed to create IRQ domain\n"); Loading Loading @@ -808,6 +808,30 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, kfree(d); return ret; } EXPORT_SYMBOL_GPL(regmap_add_irq_chip_np); /** * regmap_add_irq_chip() - Use standard regmap IRQ controller handling * * @map: The regmap for the device. * @irq: The IRQ the device uses to signal interrupts. * @irq_flags: The IRQF_ flags to use for the primary interrupt. * @irq_base: Allocate at specific IRQ number if irq_base > 0. * @chip: Configuration for the interrupt controller. * @data: Runtime data structure for the controller, allocated on success. * * Returns 0 on success or an errno on failure. * * This is the same as regmap_add_irq_chip_np, except that the device * node of the regmap is used. */ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, int irq_base, const struct regmap_irq_chip *chip, struct regmap_irq_chip_data **data) { return regmap_add_irq_chip_np(map->dev->of_node, map, irq, irq_flags, irq_base, chip, data); } EXPORT_SYMBOL_GPL(regmap_add_irq_chip); /** Loading Loading @@ -875,9 +899,10 @@ static int devm_regmap_irq_chip_match(struct device *dev, void *res, void *data) } /** * devm_regmap_add_irq_chip() - Resource manager regmap_add_irq_chip() * devm_regmap_add_irq_chip_np() - Resource manager regmap_add_irq_chip_np() * * @dev: The device pointer on which irq_chip belongs to. * @np: The device_node where the IRQ domain should be added to. * @map: The regmap for the device. * @irq: The IRQ the device uses to signal interrupts * @irq_flags: The IRQF_ flags to use for the primary interrupt. Loading @@ -890,8 +915,9 @@ static int devm_regmap_irq_chip_match(struct device *dev, void *res, void *data) * The ®map_irq_chip_data will be automatically released when the device is * unbound. */ int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq, int irq_flags, int irq_base, int devm_regmap_add_irq_chip_np(struct device *dev, struct device_node *np, struct regmap *map, int irq, int irq_flags, int irq_base, const struct regmap_irq_chip *chip, struct regmap_irq_chip_data **data) { Loading @@ -903,7 +929,7 @@ int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq, if (!ptr) return -ENOMEM; ret = regmap_add_irq_chip(map, irq, irq_flags, irq_base, ret = regmap_add_irq_chip_np(np, map, irq, irq_flags, irq_base, chip, &d); if (ret < 0) { devres_free(ptr); Loading @@ -915,6 +941,32 @@ int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq, *data = d; return 0; } EXPORT_SYMBOL_GPL(devm_regmap_add_irq_chip_np); /** * devm_regmap_add_irq_chip() - Resource manager regmap_add_irq_chip() * * @dev: The device pointer on which irq_chip belongs to. * @map: The regmap for the device. * @irq: The IRQ the device uses to signal interrupts * @irq_flags: The IRQF_ flags to use for the primary interrupt. * @irq_base: Allocate at specific IRQ number if irq_base > 0. * @chip: Configuration for the interrupt controller. * @data: Runtime data structure for the controller, allocated on success * * Returns 0 on success or an errno on failure. * * The ®map_irq_chip_data will be automatically released when the device is * unbound. */ int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq, int irq_flags, int irq_base, const struct regmap_irq_chip *chip, struct regmap_irq_chip_data **data) { return devm_regmap_add_irq_chip_np(dev, map->dev->of_node, map, irq, irq_flags, irq_base, chip, data); } EXPORT_SYMBOL_GPL(devm_regmap_add_irq_chip); /** Loading
drivers/base/regmap/regmap.c +23 −0 Original line number Diff line number Diff line Loading @@ -827,6 +827,7 @@ struct regmap *__regmap_init(struct device *dev, } else if (!bus->read || !bus->write) { map->reg_read = _regmap_bus_reg_read; map->reg_write = _regmap_bus_reg_write; map->reg_update_bits = bus->reg_update_bits; map->defer_caching = false; goto skip_format_initialization; Loading Loading @@ -2936,6 +2937,28 @@ int regmap_update_bits_base(struct regmap *map, unsigned int reg, } EXPORT_SYMBOL_GPL(regmap_update_bits_base); /** * regmap_test_bits() - Check if all specified bits are set in a register. * * @map: Register map to operate on * @reg: Register to read from * @bits: Bits to test * * Returns -1 if the underlying regmap_read() fails, 0 if at least one of the * tested bits is not set and 1 if all tested bits are set. */ int regmap_test_bits(struct regmap *map, unsigned int reg, unsigned int bits) { unsigned int val, ret; ret = regmap_read(map, reg, &val); if (ret) return ret; return (val & bits) == bits; } EXPORT_SYMBOL_GPL(regmap_test_bits); void regmap_async_complete_cb(struct regmap_async *async, int ret) { struct regmap *map = async->map; Loading
include/linux/regmap.h +70 −39 Original line number Diff line number Diff line Loading @@ -17,10 +17,12 @@ #include <linux/err.h> #include <linux/bug.h> #include <linux/lockdep.h> #include <linux/iopoll.h> struct module; struct clk; struct device; struct device_node; struct i2c_client; struct i3c_device; struct irq_domain; Loading Loading @@ -71,6 +73,13 @@ struct reg_sequence { unsigned int delay_us; }; #define REG_SEQ(_reg, _def, _delay_us) { \ .reg = _reg, \ .def = _def, \ .delay_us = _delay_us, \ } #define REG_SEQ0(_reg, _def) REG_SEQ(_reg, _def, 0) #define regmap_update_bits(map, reg, mask, val) \ regmap_update_bits_base(map, reg, mask, val, NULL, false, false) #define regmap_update_bits_async(map, reg, mask, val)\ Loading Loading @@ -122,26 +131,10 @@ struct reg_sequence { */ #define regmap_read_poll_timeout(map, addr, val, cond, sleep_us, timeout_us) \ ({ \ u64 __timeout_us = (timeout_us); \ unsigned long __sleep_us = (sleep_us); \ ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \ int __ret; \ might_sleep_if(__sleep_us); \ for (;;) { \ __ret = regmap_read((map), (addr), &(val)); \ if (__ret) \ break; \ if (cond) \ break; \ if ((__timeout_us) && \ ktime_compare(ktime_get(), __timeout) > 0) { \ __ret = regmap_read((map), (addr), &(val)); \ break; \ } \ if (__sleep_us) \ usleep_range((__sleep_us >> 2) + 1, __sleep_us); \ } \ __ret ?: ((cond) ? 0 : -ETIMEDOUT); \ int __ret, __tmp; \ __tmp = read_poll_timeout(regmap_read, __ret, __ret || (cond), \ sleep_us, timeout_us, false, (map), (addr), &(val)); \ __ret ?: __tmp; \ }) /** Loading Loading @@ -209,25 +202,10 @@ struct reg_sequence { */ #define regmap_field_read_poll_timeout(field, val, cond, sleep_us, timeout_us) \ ({ \ u64 __timeout_us = (timeout_us); \ unsigned long __sleep_us = (sleep_us); \ ktime_t timeout = ktime_add_us(ktime_get(), __timeout_us); \ int pollret; \ might_sleep_if(__sleep_us); \ for (;;) { \ pollret = regmap_field_read((field), &(val)); \ if (pollret) \ break; \ if (cond) \ break; \ if (__timeout_us && ktime_compare(ktime_get(), timeout) > 0) { \ pollret = regmap_field_read((field), &(val)); \ break; \ } \ if (__sleep_us) \ usleep_range((__sleep_us >> 2) + 1, __sleep_us); \ } \ pollret ?: ((cond) ? 0 : -ETIMEDOUT); \ int __ret, __tmp; \ __tmp = read_poll_timeout(regmap_field_read, __ret, __ret || (cond), \ sleep_us, timeout_us, false, (field), &(val)); \ __ret ?: __tmp; \ }) #ifdef CONFIG_REGMAP Loading Loading @@ -1111,6 +1089,21 @@ bool regmap_reg_in_ranges(unsigned int reg, const struct regmap_range *ranges, unsigned int nranges); static inline int regmap_set_bits(struct regmap *map, unsigned int reg, unsigned int bits) { return regmap_update_bits_base(map, reg, bits, bits, NULL, false, false); } static inline int regmap_clear_bits(struct regmap *map, unsigned int reg, unsigned int bits) { return regmap_update_bits_base(map, reg, bits, 0, NULL, false, false); } int regmap_test_bits(struct regmap *map, unsigned int reg, unsigned int bits); /** * struct reg_field - Description of an register field * Loading @@ -1134,6 +1127,14 @@ struct reg_field { .msb = _msb, \ } #define REG_FIELD_ID(_reg, _lsb, _msb, _size, _offset) { \ .reg = _reg, \ .lsb = _lsb, \ .msb = _msb, \ .id_size = _size, \ .id_offset = _offset, \ } struct regmap_field *regmap_field_alloc(struct regmap *regmap, struct reg_field reg_field); void regmap_field_free(struct regmap_field *field); Loading Loading @@ -1310,12 +1311,21 @@ struct regmap_irq_chip_data; int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags, int irq_base, const struct regmap_irq_chip *chip, struct regmap_irq_chip_data **data); int regmap_add_irq_chip_np(struct device_node *np, struct regmap *map, int irq, int irq_flags, int irq_base, const struct regmap_irq_chip *chip, struct regmap_irq_chip_data **data); void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *data); int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq, int irq_flags, int irq_base, const struct regmap_irq_chip *chip, struct regmap_irq_chip_data **data); int devm_regmap_add_irq_chip_np(struct device *dev, struct device_node *np, struct regmap *map, int irq, int irq_flags, int irq_base, const struct regmap_irq_chip *chip, struct regmap_irq_chip_data **data); void devm_regmap_del_irq_chip(struct device *dev, int irq, struct regmap_irq_chip_data *data); Loading Loading @@ -1410,6 +1420,27 @@ static inline int regmap_update_bits_base(struct regmap *map, unsigned int reg, return -EINVAL; } static inline int regmap_set_bits(struct regmap *map, unsigned int reg, unsigned int bits) { WARN_ONCE(1, "regmap API is disabled"); return -EINVAL; } static inline int regmap_clear_bits(struct regmap *map, unsigned int reg, unsigned int bits) { WARN_ONCE(1, "regmap API is disabled"); return -EINVAL; } static inline int regmap_test_bits(struct regmap *map, unsigned int reg, unsigned int bits) { WARN_ONCE(1, "regmap API is disabled"); return -EINVAL; } static inline int regmap_field_update_bits_base(struct regmap_field *field, unsigned int mask, unsigned int val, bool *change, bool async, bool force) Loading