Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/base/regmap/regmap-sdw.c
26428 views
1
// SPDX-License-Identifier: GPL-2.0
2
// Copyright(c) 2015-17 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/types.h>
10
#include "internal.h"
11
12
static int regmap_sdw_write(void *context, const void *val_buf, size_t val_size)
13
{
14
struct device *dev = context;
15
struct sdw_slave *slave = dev_to_sdw_dev(dev);
16
/* First word of buffer contains the destination address */
17
u32 addr = le32_to_cpu(*(const __le32 *)val_buf);
18
const u8 *val = val_buf;
19
20
return sdw_nwrite_no_pm(slave, addr, val_size - sizeof(addr), val + sizeof(addr));
21
}
22
23
static int regmap_sdw_gather_write(void *context,
24
const void *reg_buf, size_t reg_size,
25
const void *val_buf, size_t val_size)
26
{
27
struct device *dev = context;
28
struct sdw_slave *slave = dev_to_sdw_dev(dev);
29
u32 addr = le32_to_cpu(*(const __le32 *)reg_buf);
30
31
return sdw_nwrite_no_pm(slave, addr, val_size, val_buf);
32
}
33
34
static int regmap_sdw_read(void *context,
35
const void *reg_buf, size_t reg_size,
36
void *val_buf, size_t val_size)
37
{
38
struct device *dev = context;
39
struct sdw_slave *slave = dev_to_sdw_dev(dev);
40
u32 addr = le32_to_cpu(*(const __le32 *)reg_buf);
41
42
return sdw_nread_no_pm(slave, addr, val_size, val_buf);
43
}
44
45
static const struct regmap_bus regmap_sdw = {
46
.write = regmap_sdw_write,
47
.gather_write = regmap_sdw_gather_write,
48
.read = regmap_sdw_read,
49
.reg_format_endian_default = REGMAP_ENDIAN_LITTLE,
50
.val_format_endian_default = REGMAP_ENDIAN_LITTLE,
51
};
52
53
static int regmap_sdw_config_check(const struct regmap_config *config)
54
{
55
/* Register addresses are 32 bits wide */
56
if (config->reg_bits != 32)
57
return -ENOTSUPP;
58
59
if (config->pad_bits != 0)
60
return -ENOTSUPP;
61
62
/* Only bulk writes are supported not multi-register writes */
63
if (config->can_multi_write)
64
return -ENOTSUPP;
65
66
return 0;
67
}
68
69
struct regmap *__regmap_init_sdw(struct sdw_slave *sdw,
70
const struct regmap_config *config,
71
struct lock_class_key *lock_key,
72
const char *lock_name)
73
{
74
int ret;
75
76
ret = regmap_sdw_config_check(config);
77
if (ret)
78
return ERR_PTR(ret);
79
80
return __regmap_init(&sdw->dev, &regmap_sdw,
81
&sdw->dev, config, lock_key, lock_name);
82
}
83
EXPORT_SYMBOL_GPL(__regmap_init_sdw);
84
85
struct regmap *__devm_regmap_init_sdw(struct sdw_slave *sdw,
86
const struct regmap_config *config,
87
struct lock_class_key *lock_key,
88
const char *lock_name)
89
{
90
int ret;
91
92
ret = regmap_sdw_config_check(config);
93
if (ret)
94
return ERR_PTR(ret);
95
96
return __devm_regmap_init(&sdw->dev, &regmap_sdw,
97
&sdw->dev, config, lock_key, lock_name);
98
}
99
EXPORT_SYMBOL_GPL(__devm_regmap_init_sdw);
100
101
MODULE_DESCRIPTION("regmap SoundWire Module");
102
MODULE_LICENSE("GPL v2");
103
104