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