regmap-sdw-mbq.c (2454B)
1// SPDX-License-Identifier: GPL-2.0 2// Copyright(c) 2020 Intel Corporation. 3 4#include <linux/device.h> 5#include <linux/errno.h> 6#include <linux/module.h> 7#include <linux/regmap.h> 8#include <linux/soundwire/sdw.h> 9#include <linux/soundwire/sdw_registers.h> 10#include "internal.h" 11 12static int regmap_sdw_mbq_write(void *context, unsigned int reg, unsigned int val) 13{ 14 struct device *dev = context; 15 struct sdw_slave *slave = dev_to_sdw_dev(dev); 16 int ret; 17 18 ret = sdw_write_no_pm(slave, SDW_SDCA_MBQ_CTL(reg), (val >> 8) & 0xff); 19 if (ret < 0) 20 return ret; 21 22 return sdw_write_no_pm(slave, reg, val & 0xff); 23} 24 25static int regmap_sdw_mbq_read(void *context, unsigned int reg, unsigned int *val) 26{ 27 struct device *dev = context; 28 struct sdw_slave *slave = dev_to_sdw_dev(dev); 29 int read0; 30 int read1; 31 32 read0 = sdw_read_no_pm(slave, reg); 33 if (read0 < 0) 34 return read0; 35 36 read1 = sdw_read_no_pm(slave, SDW_SDCA_MBQ_CTL(reg)); 37 if (read1 < 0) 38 return read1; 39 40 *val = (read1 << 8) | read0; 41 42 return 0; 43} 44 45static const struct regmap_bus regmap_sdw_mbq = { 46 .reg_read = regmap_sdw_mbq_read, 47 .reg_write = regmap_sdw_mbq_write, 48 .reg_format_endian_default = REGMAP_ENDIAN_LITTLE, 49 .val_format_endian_default = REGMAP_ENDIAN_LITTLE, 50}; 51 52static int regmap_sdw_mbq_config_check(const struct regmap_config *config) 53{ 54 /* MBQ-based controls are only 16-bits for now */ 55 if (config->val_bits != 16) 56 return -ENOTSUPP; 57 58 /* Registers are 32 bits wide */ 59 if (config->reg_bits != 32) 60 return -ENOTSUPP; 61 62 if (config->pad_bits != 0) 63 return -ENOTSUPP; 64 65 return 0; 66} 67 68struct regmap *__regmap_init_sdw_mbq(struct sdw_slave *sdw, 69 const struct regmap_config *config, 70 struct lock_class_key *lock_key, 71 const char *lock_name) 72{ 73 int ret; 74 75 ret = regmap_sdw_mbq_config_check(config); 76 if (ret) 77 return ERR_PTR(ret); 78 79 return __regmap_init(&sdw->dev, ®map_sdw_mbq, 80 &sdw->dev, config, lock_key, lock_name); 81} 82EXPORT_SYMBOL_GPL(__regmap_init_sdw_mbq); 83 84struct regmap *__devm_regmap_init_sdw_mbq(struct sdw_slave *sdw, 85 const struct regmap_config *config, 86 struct lock_class_key *lock_key, 87 const char *lock_name) 88{ 89 int ret; 90 91 ret = regmap_sdw_mbq_config_check(config); 92 if (ret) 93 return ERR_PTR(ret); 94 95 return __devm_regmap_init(&sdw->dev, ®map_sdw_mbq, 96 &sdw->dev, config, lock_key, lock_name); 97} 98EXPORT_SYMBOL_GPL(__devm_regmap_init_sdw_mbq); 99 100MODULE_DESCRIPTION("Regmap SoundWire MBQ Module"); 101MODULE_LICENSE("GPL");