Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // Copyright(c) 2020 Intel Corporation.
0003 
0004 #include <linux/device.h>
0005 #include <linux/errno.h>
0006 #include <linux/module.h>
0007 #include <linux/regmap.h>
0008 #include <linux/soundwire/sdw.h>
0009 #include <linux/soundwire/sdw_registers.h>
0010 #include "internal.h"
0011 
0012 static int regmap_sdw_mbq_write(void *context, unsigned int reg, unsigned int val)
0013 {
0014     struct device *dev = context;
0015     struct sdw_slave *slave = dev_to_sdw_dev(dev);
0016     int ret;
0017 
0018     ret = sdw_write_no_pm(slave, SDW_SDCA_MBQ_CTL(reg), (val >> 8) & 0xff);
0019     if (ret < 0)
0020         return ret;
0021 
0022     return sdw_write_no_pm(slave, reg, val & 0xff);
0023 }
0024 
0025 static int regmap_sdw_mbq_read(void *context, unsigned int reg, unsigned int *val)
0026 {
0027     struct device *dev = context;
0028     struct sdw_slave *slave = dev_to_sdw_dev(dev);
0029     int read0;
0030     int read1;
0031 
0032     read0 = sdw_read_no_pm(slave, reg);
0033     if (read0 < 0)
0034         return read0;
0035 
0036     read1 = sdw_read_no_pm(slave, SDW_SDCA_MBQ_CTL(reg));
0037     if (read1 < 0)
0038         return read1;
0039 
0040     *val = (read1 << 8) | read0;
0041 
0042     return 0;
0043 }
0044 
0045 static const struct regmap_bus regmap_sdw_mbq = {
0046     .reg_read = regmap_sdw_mbq_read,
0047     .reg_write = regmap_sdw_mbq_write,
0048     .reg_format_endian_default = REGMAP_ENDIAN_LITTLE,
0049     .val_format_endian_default = REGMAP_ENDIAN_LITTLE,
0050 };
0051 
0052 static int regmap_sdw_mbq_config_check(const struct regmap_config *config)
0053 {
0054     /* MBQ-based controls are only 16-bits for now */
0055     if (config->val_bits != 16)
0056         return -ENOTSUPP;
0057 
0058     /* Registers are 32 bits wide */
0059     if (config->reg_bits != 32)
0060         return -ENOTSUPP;
0061 
0062     if (config->pad_bits != 0)
0063         return -ENOTSUPP;
0064 
0065     return 0;
0066 }
0067 
0068 struct regmap *__regmap_init_sdw_mbq(struct sdw_slave *sdw,
0069                      const struct regmap_config *config,
0070                      struct lock_class_key *lock_key,
0071                      const char *lock_name)
0072 {
0073     int ret;
0074 
0075     ret = regmap_sdw_mbq_config_check(config);
0076     if (ret)
0077         return ERR_PTR(ret);
0078 
0079     return __regmap_init(&sdw->dev, &regmap_sdw_mbq,
0080             &sdw->dev, config, lock_key, lock_name);
0081 }
0082 EXPORT_SYMBOL_GPL(__regmap_init_sdw_mbq);
0083 
0084 struct regmap *__devm_regmap_init_sdw_mbq(struct sdw_slave *sdw,
0085                       const struct regmap_config *config,
0086                       struct lock_class_key *lock_key,
0087                       const char *lock_name)
0088 {
0089     int ret;
0090 
0091     ret = regmap_sdw_mbq_config_check(config);
0092     if (ret)
0093         return ERR_PTR(ret);
0094 
0095     return __devm_regmap_init(&sdw->dev, &regmap_sdw_mbq,
0096             &sdw->dev, config, lock_key, lock_name);
0097 }
0098 EXPORT_SYMBOL_GPL(__devm_regmap_init_sdw_mbq);
0099 
0100 MODULE_DESCRIPTION("Regmap SoundWire MBQ Module");
0101 MODULE_LICENSE("GPL");