linux/drivers/base/regmap/regmap-sdw-mbq.c
<<
>>
Prefs
   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 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");
 102