Linux Audio

Check our new training course

Linux debugging, profiling, tracing and performance analysis training

Mar 24-27, 2025, special US time zones
Register
Loading...
Note: File does not exist in v3.1.
  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, &regmap_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, &regmap_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");