Loading drivers/base/regmap/Kconfig +5 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ # subsystems should select the appropriate symbols. config REGMAP default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SOUNDWIRE || REGMAP_SCCB || REGMAP_I3C || REGMAP_SPI_AVMM) default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SOUNDWIRE || REGMAP_SOUNDWIRE_MBQ || REGMAP_SCCB || REGMAP_I3C || REGMAP_SPI_AVMM) select IRQ_DOMAIN if REGMAP_IRQ bool Loading Loading @@ -46,6 +46,10 @@ config REGMAP_SOUNDWIRE tristate depends on SOUNDWIRE config REGMAP_SOUNDWIRE_MBQ tristate depends on SOUNDWIRE config REGMAP_SCCB tristate depends on I2C Loading drivers/base/regmap/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ obj-$(CONFIG_REGMAP_MMIO) += regmap-mmio.o obj-$(CONFIG_REGMAP_IRQ) += regmap-irq.o obj-$(CONFIG_REGMAP_W1) += regmap-w1.o obj-$(CONFIG_REGMAP_SOUNDWIRE) += regmap-sdw.o obj-$(CONFIG_REGMAP_SOUNDWIRE_MBQ) += regmap-sdw-mbq.o obj-$(CONFIG_REGMAP_SCCB) += regmap-sccb.o obj-$(CONFIG_REGMAP_I3C) += regmap-i3c.o obj-$(CONFIG_REGMAP_SPI_AVMM) += regmap-spi-avmm.o drivers/base/regmap/regmap-sdw-mbq.c 0 → 100644 +101 −0 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0 // Copyright(c) 2020 Intel Corporation. #include <linux/device.h> #include <linux/errno.h> #include <linux/module.h> #include <linux/regmap.h> #include <linux/soundwire/sdw.h> #include <linux/soundwire/sdw_registers.h> #include "internal.h" static int regmap_sdw_mbq_write(void *context, unsigned int reg, unsigned int val) { struct device *dev = context; struct sdw_slave *slave = dev_to_sdw_dev(dev); int ret; ret = sdw_write(slave, SDW_SDCA_MBQ_CTL(reg), (val >> 8) & 0xff); if (ret < 0) return ret; return sdw_write(slave, reg, val & 0xff); } static int regmap_sdw_mbq_read(void *context, unsigned int reg, unsigned int *val) { struct device *dev = context; struct sdw_slave *slave = dev_to_sdw_dev(dev); int read0; int read1; read0 = sdw_read(slave, reg); if (read0 < 0) return read0; read1 = sdw_read(slave, SDW_SDCA_MBQ_CTL(reg)); if (read1 < 0) return read1; *val = (read1 << 8) | read0; return 0; } static struct regmap_bus regmap_sdw_mbq = { .reg_read = regmap_sdw_mbq_read, .reg_write = regmap_sdw_mbq_write, .reg_format_endian_default = REGMAP_ENDIAN_LITTLE, .val_format_endian_default = REGMAP_ENDIAN_LITTLE, }; static int regmap_sdw_mbq_config_check(const struct regmap_config *config) { /* MBQ-based controls are only 16-bits for now */ if (config->val_bits != 16) return -ENOTSUPP; /* Registers are 32 bits wide */ if (config->reg_bits != 32) return -ENOTSUPP; if (config->pad_bits != 0) return -ENOTSUPP; return 0; } struct regmap *__regmap_init_sdw_mbq(struct sdw_slave *sdw, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name) { int ret; ret = regmap_sdw_mbq_config_check(config); if (ret) return ERR_PTR(ret); return __regmap_init(&sdw->dev, ®map_sdw_mbq, &sdw->dev, config, lock_key, lock_name); } EXPORT_SYMBOL_GPL(__regmap_init_sdw_mbq); struct regmap *__devm_regmap_init_sdw_mbq(struct sdw_slave *sdw, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name) { int ret; ret = regmap_sdw_mbq_config_check(config); if (ret) return ERR_PTR(ret); return __devm_regmap_init(&sdw->dev, ®map_sdw_mbq, &sdw->dev, config, lock_key, lock_name); } EXPORT_SYMBOL_GPL(__devm_regmap_init_sdw_mbq); MODULE_DESCRIPTION("Regmap SoundWire MBQ Module"); MODULE_LICENSE("GPL v2"); include/linux/regmap.h +35 −0 Original line number Diff line number Diff line Loading @@ -570,6 +570,10 @@ struct regmap *__regmap_init_sdw(struct sdw_slave *sdw, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name); struct regmap *__regmap_init_sdw_mbq(struct sdw_slave *sdw, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name); struct regmap *__regmap_init_spi_avmm(struct spi_device *spi, const struct regmap_config *config, struct lock_class_key *lock_key, Loading Loading @@ -619,6 +623,10 @@ struct regmap *__devm_regmap_init_sdw(struct sdw_slave *sdw, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name); struct regmap *__devm_regmap_init_sdw_mbq(struct sdw_slave *sdw, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name); struct regmap *__devm_regmap_init_slimbus(struct slim_device *slimbus, const struct regmap_config *config, struct lock_class_key *lock_key, Loading Loading @@ -817,6 +825,19 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg); __regmap_lockdep_wrapper(__regmap_init_sdw, #config, \ sdw, config) /** * regmap_init_sdw_mbq() - Initialise register map * * @sdw: Device that will be interacted with * @config: Configuration for register map * * The return value will be an ERR_PTR() on error or a valid pointer to * a struct regmap. */ #define regmap_init_sdw_mbq(sdw, config) \ __regmap_lockdep_wrapper(__regmap_init_sdw_mbq, #config, \ sdw, config) /** * regmap_init_spi_avmm() - Initialize register map for Intel SPI Slave * to AVMM Bus Bridge Loading Loading @@ -989,6 +1010,20 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg); __regmap_lockdep_wrapper(__devm_regmap_init_sdw, #config, \ sdw, config) /** * devm_regmap_init_sdw_mbq() - Initialise managed register map * * @sdw: Device that will be interacted with * @config: Configuration for register map * * The return value will be an ERR_PTR() on error or a valid pointer * to a struct regmap. The regmap will be automatically freed by the * device management code. */ #define devm_regmap_init_sdw_mbq(sdw, config) \ __regmap_lockdep_wrapper(__devm_regmap_init_sdw_mbq, #config, \ sdw, config) /** * devm_regmap_init_slimbus() - Initialise managed register map * Loading include/linux/soundwire/sdw_registers.h +32 −0 Original line number Diff line number Diff line Loading @@ -298,4 +298,36 @@ #define SDW_CASC_PORT_MASK_INTSTAT3 1 #define SDW_CASC_PORT_REG_OFFSET_INTSTAT3 2 /* * v1.2 device - SDCA address mapping * * Spec definition * Bits Contents * 31 0 (required by addressing range) * 30:26 0b10000 (Control Prefix) * 25 0 (Reserved) * 24:22 Function Number [2:0] * 21 Entity[6] * 20:19 Control Selector[5:4] * 18 0 (Reserved) * 17:15 Control Number[5:3] * 14 Next * 13 MBQ * 12:7 Entity[5:0] * 6:3 Control Selector[3:0] * 2:0 Control Number[2:0] */ #define SDW_SDCA_CTL(fun, ent, ctl, ch) (BIT(30) | \ (((fun) & 0x7) << 22) | \ (((ent) & 0x40) << 15) | \ (((ent) & 0x3f) << 7) | \ (((ctl) & 0x30) << 15) | \ (((ctl) & 0x0f) << 3) | \ (((ch) & 0x38) << 12) | \ ((ch) & 0x07)) #define SDW_SDCA_MBQ_CTL(reg) ((reg) | BIT(13)) #define SDW_SDCA_NEXT_CTL(reg) ((reg) | BIT(14)) #endif /* __SDW_REGISTERS_H */ Loading
drivers/base/regmap/Kconfig +5 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ # subsystems should select the appropriate symbols. config REGMAP default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SOUNDWIRE || REGMAP_SCCB || REGMAP_I3C || REGMAP_SPI_AVMM) default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SOUNDWIRE || REGMAP_SOUNDWIRE_MBQ || REGMAP_SCCB || REGMAP_I3C || REGMAP_SPI_AVMM) select IRQ_DOMAIN if REGMAP_IRQ bool Loading Loading @@ -46,6 +46,10 @@ config REGMAP_SOUNDWIRE tristate depends on SOUNDWIRE config REGMAP_SOUNDWIRE_MBQ tristate depends on SOUNDWIRE config REGMAP_SCCB tristate depends on I2C Loading
drivers/base/regmap/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ obj-$(CONFIG_REGMAP_MMIO) += regmap-mmio.o obj-$(CONFIG_REGMAP_IRQ) += regmap-irq.o obj-$(CONFIG_REGMAP_W1) += regmap-w1.o obj-$(CONFIG_REGMAP_SOUNDWIRE) += regmap-sdw.o obj-$(CONFIG_REGMAP_SOUNDWIRE_MBQ) += regmap-sdw-mbq.o obj-$(CONFIG_REGMAP_SCCB) += regmap-sccb.o obj-$(CONFIG_REGMAP_I3C) += regmap-i3c.o obj-$(CONFIG_REGMAP_SPI_AVMM) += regmap-spi-avmm.o
drivers/base/regmap/regmap-sdw-mbq.c 0 → 100644 +101 −0 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0 // Copyright(c) 2020 Intel Corporation. #include <linux/device.h> #include <linux/errno.h> #include <linux/module.h> #include <linux/regmap.h> #include <linux/soundwire/sdw.h> #include <linux/soundwire/sdw_registers.h> #include "internal.h" static int regmap_sdw_mbq_write(void *context, unsigned int reg, unsigned int val) { struct device *dev = context; struct sdw_slave *slave = dev_to_sdw_dev(dev); int ret; ret = sdw_write(slave, SDW_SDCA_MBQ_CTL(reg), (val >> 8) & 0xff); if (ret < 0) return ret; return sdw_write(slave, reg, val & 0xff); } static int regmap_sdw_mbq_read(void *context, unsigned int reg, unsigned int *val) { struct device *dev = context; struct sdw_slave *slave = dev_to_sdw_dev(dev); int read0; int read1; read0 = sdw_read(slave, reg); if (read0 < 0) return read0; read1 = sdw_read(slave, SDW_SDCA_MBQ_CTL(reg)); if (read1 < 0) return read1; *val = (read1 << 8) | read0; return 0; } static struct regmap_bus regmap_sdw_mbq = { .reg_read = regmap_sdw_mbq_read, .reg_write = regmap_sdw_mbq_write, .reg_format_endian_default = REGMAP_ENDIAN_LITTLE, .val_format_endian_default = REGMAP_ENDIAN_LITTLE, }; static int regmap_sdw_mbq_config_check(const struct regmap_config *config) { /* MBQ-based controls are only 16-bits for now */ if (config->val_bits != 16) return -ENOTSUPP; /* Registers are 32 bits wide */ if (config->reg_bits != 32) return -ENOTSUPP; if (config->pad_bits != 0) return -ENOTSUPP; return 0; } struct regmap *__regmap_init_sdw_mbq(struct sdw_slave *sdw, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name) { int ret; ret = regmap_sdw_mbq_config_check(config); if (ret) return ERR_PTR(ret); return __regmap_init(&sdw->dev, ®map_sdw_mbq, &sdw->dev, config, lock_key, lock_name); } EXPORT_SYMBOL_GPL(__regmap_init_sdw_mbq); struct regmap *__devm_regmap_init_sdw_mbq(struct sdw_slave *sdw, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name) { int ret; ret = regmap_sdw_mbq_config_check(config); if (ret) return ERR_PTR(ret); return __devm_regmap_init(&sdw->dev, ®map_sdw_mbq, &sdw->dev, config, lock_key, lock_name); } EXPORT_SYMBOL_GPL(__devm_regmap_init_sdw_mbq); MODULE_DESCRIPTION("Regmap SoundWire MBQ Module"); MODULE_LICENSE("GPL v2");
include/linux/regmap.h +35 −0 Original line number Diff line number Diff line Loading @@ -570,6 +570,10 @@ struct regmap *__regmap_init_sdw(struct sdw_slave *sdw, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name); struct regmap *__regmap_init_sdw_mbq(struct sdw_slave *sdw, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name); struct regmap *__regmap_init_spi_avmm(struct spi_device *spi, const struct regmap_config *config, struct lock_class_key *lock_key, Loading Loading @@ -619,6 +623,10 @@ struct regmap *__devm_regmap_init_sdw(struct sdw_slave *sdw, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name); struct regmap *__devm_regmap_init_sdw_mbq(struct sdw_slave *sdw, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name); struct regmap *__devm_regmap_init_slimbus(struct slim_device *slimbus, const struct regmap_config *config, struct lock_class_key *lock_key, Loading Loading @@ -817,6 +825,19 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg); __regmap_lockdep_wrapper(__regmap_init_sdw, #config, \ sdw, config) /** * regmap_init_sdw_mbq() - Initialise register map * * @sdw: Device that will be interacted with * @config: Configuration for register map * * The return value will be an ERR_PTR() on error or a valid pointer to * a struct regmap. */ #define regmap_init_sdw_mbq(sdw, config) \ __regmap_lockdep_wrapper(__regmap_init_sdw_mbq, #config, \ sdw, config) /** * regmap_init_spi_avmm() - Initialize register map for Intel SPI Slave * to AVMM Bus Bridge Loading Loading @@ -989,6 +1010,20 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg); __regmap_lockdep_wrapper(__devm_regmap_init_sdw, #config, \ sdw, config) /** * devm_regmap_init_sdw_mbq() - Initialise managed register map * * @sdw: Device that will be interacted with * @config: Configuration for register map * * The return value will be an ERR_PTR() on error or a valid pointer * to a struct regmap. The regmap will be automatically freed by the * device management code. */ #define devm_regmap_init_sdw_mbq(sdw, config) \ __regmap_lockdep_wrapper(__devm_regmap_init_sdw_mbq, #config, \ sdw, config) /** * devm_regmap_init_slimbus() - Initialise managed register map * Loading
include/linux/soundwire/sdw_registers.h +32 −0 Original line number Diff line number Diff line Loading @@ -298,4 +298,36 @@ #define SDW_CASC_PORT_MASK_INTSTAT3 1 #define SDW_CASC_PORT_REG_OFFSET_INTSTAT3 2 /* * v1.2 device - SDCA address mapping * * Spec definition * Bits Contents * 31 0 (required by addressing range) * 30:26 0b10000 (Control Prefix) * 25 0 (Reserved) * 24:22 Function Number [2:0] * 21 Entity[6] * 20:19 Control Selector[5:4] * 18 0 (Reserved) * 17:15 Control Number[5:3] * 14 Next * 13 MBQ * 12:7 Entity[5:0] * 6:3 Control Selector[3:0] * 2:0 Control Number[2:0] */ #define SDW_SDCA_CTL(fun, ent, ctl, ch) (BIT(30) | \ (((fun) & 0x7) << 22) | \ (((ent) & 0x40) << 15) | \ (((ent) & 0x3f) << 7) | \ (((ctl) & 0x30) << 15) | \ (((ctl) & 0x0f) << 3) | \ (((ch) & 0x38) << 12) | \ ((ch) & 0x07)) #define SDW_SDCA_MBQ_CTL(reg) ((reg) | BIT(13)) #define SDW_SDCA_NEXT_CTL(reg) ((reg) | BIT(14)) #endif /* __SDW_REGISTERS_H */