Loading drivers/base/regmap/Kconfig +4 −1 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ # subsystems should select the appropriate symbols. config REGMAP default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ) default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SWR) select LZO_COMPRESS select LZO_DECOMPRESS select IRQ_DOMAIN if REGMAP_IRQ Loading @@ -29,3 +29,6 @@ config REGMAP_MMIO config REGMAP_IRQ bool config REGMAP_SWR tristate drivers/base/regmap/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -10,3 +10,4 @@ obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o obj-$(CONFIG_REGMAP_SPMI) += regmap-spmi.o obj-$(CONFIG_REGMAP_MMIO) += regmap-mmio.o obj-$(CONFIG_REGMAP_IRQ) += regmap-irq.o obj-$(CONFIG_REGMAP_SWR) += regmap-swr.o drivers/base/regmap/regmap-swr.c 0 → 100644 +124 −0 Original line number Diff line number Diff line /* * Copyright (c) 2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #include <linux/regmap.h> #include <linux/soundwire/soundwire.h> #include <linux/module.h> #include <linux/init.h> #include "internal.h" static int regmap_swr_gather_write(void *context, const void *reg, size_t reg_size, const void *val, size_t val_size) { struct device *dev = context; struct swr_device *swr = to_swr_device(dev); struct regmap *map = dev_get_regmap(dev, NULL); size_t addr_bytes = map->format.reg_bytes; int ret = 0; int i; u32 reg_addr = 0; if (swr == NULL) { dev_err(dev, "%s: swr device is NULL\n", __func__); return -EINVAL; } if (reg_size != addr_bytes) { dev_err(dev, "%s: reg size %zd bytes not supported\n", __func__, reg_size); return -EINVAL; } reg_addr = *(u16 *)reg; for (i = 0; i < val_size; i++) { ret = swr_write(swr, swr->dev_num, (reg_addr+i), (u32 *)(val+i)); if (ret < 0) { dev_err(dev, "%s: write reg 0x%x failed, err %d\n", __func__, (reg_addr+i), ret); break; } } return ret; } static int regmap_swr_write(void *context, const void *data, size_t count) { struct device *dev = context; struct regmap *map = dev_get_regmap(dev, NULL); size_t addr_bytes = map->format.reg_bytes; WARN_ON(count < addr_bytes); return regmap_swr_gather_write(context, data, addr_bytes, (data + addr_bytes), (count - addr_bytes)); } static int regmap_swr_read(void *context, const void *reg, size_t reg_size, void *val, size_t val_size) { struct device *dev = context; struct swr_device *swr = to_swr_device(dev); struct regmap *map = dev_get_regmap(dev, NULL); size_t addr_bytes = map->format.reg_bytes; int ret = 0; u32 reg_addr = 0; if (swr == NULL) { dev_err(dev, "%s: swr is NULL\n", __func__); return -EINVAL; } if (reg_size != addr_bytes) { dev_err(dev, "%s: register size %zd bytes not supported\n", __func__, reg_size); return -EINVAL; } reg_addr = *(u32 *)reg; ret = swr_read(swr, swr->dev_num, reg_addr, val, val_size); if (ret < 0) dev_err(dev, "%s: codec reg 0x%x read failed %d\n", __func__, reg_addr, ret); return ret; } static struct regmap_bus regmap_swr = { .write = regmap_swr_write, .gather_write = regmap_swr_gather_write, .read = regmap_swr_read, .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, .val_format_endian_default = REGMAP_ENDIAN_NATIVE, }; struct regmap *__regmap_init_swr(struct swr_device *swr, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name) { return __regmap_init(&swr->dev, ®map_swr, &swr->dev, config, lock_key, lock_name); } EXPORT_SYMBOL(__regmap_init_swr); struct regmap *__devm_regmap_init_swr(struct swr_device *swr, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name) { return __devm_regmap_init(&swr->dev, ®map_swr, &swr->dev, config, lock_key, lock_name); } EXPORT_SYMBOL(__devm_regmap_init_swr); MODULE_LICENSE("GPL v2"); include/linux/regmap.h +35 −1 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ struct regmap; struct regmap_range_cfg; struct regmap_field; struct snd_ac97; struct swr_device; /* An enum of all the supported cache types */ enum regcache_type { Loading Loading @@ -457,7 +458,10 @@ struct regmap *__regmap_init_ac97(struct snd_ac97 *ac97, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name); struct regmap *__regmap_init_swr(struct swr_device *dev, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name); struct regmap *__devm_regmap_init(struct device *dev, const struct regmap_bus *bus, void *bus_context, Loading Loading @@ -490,6 +494,10 @@ struct regmap *__devm_regmap_init_ac97(struct snd_ac97 *ac97, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name); struct regmap *__devm_regmap_init_swr(struct swr_device *dev, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name); /* * Wrapper for regmap_init macros to include a unique lockdep key and name Loading Loading @@ -623,6 +631,18 @@ int regmap_attach_dev(struct device *dev, struct regmap *map, ac97, config) bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg); /** * regmap_init_swr(): Initialise register map * * @swr: 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_swr(swr, config) \ __regmap_lockdep_wrapper(__regmap_init_swr, #config, \ swr, config) /** * devm_regmap_init(): Initialise managed register map * Loading Loading @@ -738,6 +758,20 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg); __regmap_lockdep_wrapper(__devm_regmap_init_ac97, #config, \ ac97, config) /** * devm_regmap_init_swr(): Initialise managed register map * * @swr: 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_swr(swr, config) \ __regmap_lockdep_wrapper(__devm_regmap_init_swr, #config, \ swr, config) void regmap_exit(struct regmap *map); int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config); Loading Loading
drivers/base/regmap/Kconfig +4 −1 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ # subsystems should select the appropriate symbols. config REGMAP default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ) default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SWR) select LZO_COMPRESS select LZO_DECOMPRESS select IRQ_DOMAIN if REGMAP_IRQ Loading @@ -29,3 +29,6 @@ config REGMAP_MMIO config REGMAP_IRQ bool config REGMAP_SWR tristate
drivers/base/regmap/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -10,3 +10,4 @@ obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o obj-$(CONFIG_REGMAP_SPMI) += regmap-spmi.o obj-$(CONFIG_REGMAP_MMIO) += regmap-mmio.o obj-$(CONFIG_REGMAP_IRQ) += regmap-irq.o obj-$(CONFIG_REGMAP_SWR) += regmap-swr.o
drivers/base/regmap/regmap-swr.c 0 → 100644 +124 −0 Original line number Diff line number Diff line /* * Copyright (c) 2015, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #include <linux/regmap.h> #include <linux/soundwire/soundwire.h> #include <linux/module.h> #include <linux/init.h> #include "internal.h" static int regmap_swr_gather_write(void *context, const void *reg, size_t reg_size, const void *val, size_t val_size) { struct device *dev = context; struct swr_device *swr = to_swr_device(dev); struct regmap *map = dev_get_regmap(dev, NULL); size_t addr_bytes = map->format.reg_bytes; int ret = 0; int i; u32 reg_addr = 0; if (swr == NULL) { dev_err(dev, "%s: swr device is NULL\n", __func__); return -EINVAL; } if (reg_size != addr_bytes) { dev_err(dev, "%s: reg size %zd bytes not supported\n", __func__, reg_size); return -EINVAL; } reg_addr = *(u16 *)reg; for (i = 0; i < val_size; i++) { ret = swr_write(swr, swr->dev_num, (reg_addr+i), (u32 *)(val+i)); if (ret < 0) { dev_err(dev, "%s: write reg 0x%x failed, err %d\n", __func__, (reg_addr+i), ret); break; } } return ret; } static int regmap_swr_write(void *context, const void *data, size_t count) { struct device *dev = context; struct regmap *map = dev_get_regmap(dev, NULL); size_t addr_bytes = map->format.reg_bytes; WARN_ON(count < addr_bytes); return regmap_swr_gather_write(context, data, addr_bytes, (data + addr_bytes), (count - addr_bytes)); } static int regmap_swr_read(void *context, const void *reg, size_t reg_size, void *val, size_t val_size) { struct device *dev = context; struct swr_device *swr = to_swr_device(dev); struct regmap *map = dev_get_regmap(dev, NULL); size_t addr_bytes = map->format.reg_bytes; int ret = 0; u32 reg_addr = 0; if (swr == NULL) { dev_err(dev, "%s: swr is NULL\n", __func__); return -EINVAL; } if (reg_size != addr_bytes) { dev_err(dev, "%s: register size %zd bytes not supported\n", __func__, reg_size); return -EINVAL; } reg_addr = *(u32 *)reg; ret = swr_read(swr, swr->dev_num, reg_addr, val, val_size); if (ret < 0) dev_err(dev, "%s: codec reg 0x%x read failed %d\n", __func__, reg_addr, ret); return ret; } static struct regmap_bus regmap_swr = { .write = regmap_swr_write, .gather_write = regmap_swr_gather_write, .read = regmap_swr_read, .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, .val_format_endian_default = REGMAP_ENDIAN_NATIVE, }; struct regmap *__regmap_init_swr(struct swr_device *swr, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name) { return __regmap_init(&swr->dev, ®map_swr, &swr->dev, config, lock_key, lock_name); } EXPORT_SYMBOL(__regmap_init_swr); struct regmap *__devm_regmap_init_swr(struct swr_device *swr, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name) { return __devm_regmap_init(&swr->dev, ®map_swr, &swr->dev, config, lock_key, lock_name); } EXPORT_SYMBOL(__devm_regmap_init_swr); MODULE_LICENSE("GPL v2");
include/linux/regmap.h +35 −1 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ struct regmap; struct regmap_range_cfg; struct regmap_field; struct snd_ac97; struct swr_device; /* An enum of all the supported cache types */ enum regcache_type { Loading Loading @@ -457,7 +458,10 @@ struct regmap *__regmap_init_ac97(struct snd_ac97 *ac97, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name); struct regmap *__regmap_init_swr(struct swr_device *dev, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name); struct regmap *__devm_regmap_init(struct device *dev, const struct regmap_bus *bus, void *bus_context, Loading Loading @@ -490,6 +494,10 @@ struct regmap *__devm_regmap_init_ac97(struct snd_ac97 *ac97, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name); struct regmap *__devm_regmap_init_swr(struct swr_device *dev, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name); /* * Wrapper for regmap_init macros to include a unique lockdep key and name Loading Loading @@ -623,6 +631,18 @@ int regmap_attach_dev(struct device *dev, struct regmap *map, ac97, config) bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg); /** * regmap_init_swr(): Initialise register map * * @swr: 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_swr(swr, config) \ __regmap_lockdep_wrapper(__regmap_init_swr, #config, \ swr, config) /** * devm_regmap_init(): Initialise managed register map * Loading Loading @@ -738,6 +758,20 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg); __regmap_lockdep_wrapper(__devm_regmap_init_ac97, #config, \ ac97, config) /** * devm_regmap_init_swr(): Initialise managed register map * * @swr: 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_swr(swr, config) \ __regmap_lockdep_wrapper(__devm_regmap_init_swr, #config, \ swr, config) void regmap_exit(struct regmap *map); int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config); Loading