1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
/*
* (C) Copyright 2016 Theobroma Systems Design und Consulting GmbH
* Written by Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <clk.h>
#include <dm.h>
#include <errno.h>
#include <i2c.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/rsb.h>
#include <asm/arch/pmic_bus.h> /* Should go away, once this driver is stand-alone */
#include <dm/pinctrl.h>
#include <linux/sizes.h>
DECLARE_GLOBAL_DATA_PTR;
struct sunxi_rsb {
void* regs;
};
/* This is just a simple wrapper around the native RSB driver, but should
in fact pull in the initialisation and hardware control in the future. */
static int sunxi_rsb_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
{
int ret = 0;
int reg = -1;
for (; nmsgs > 0; nmsgs--, msg++) {
debug("sunxi_rsb_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len);
if (msg->flags & I2C_M_RD) {
while ( (msg->len)-- && !ret ) {
debug("rsb_read(a: %d, r: %d, d: ...)\n", msg->addr, reg);
ret = rsb_read(msg->addr, reg++, (msg->buf)++); //, msg->len);
}
} else {
reg = *(msg->buf++); --(msg->len);
debug("sunxi_rsb_xfer: setting reg to %d\n", reg);
while ( (msg->len)-- && !ret ) {
debug("rsb_write(a: %d, r: %d, d: 0x%x)\n", msg->addr, reg, *(msg->buf));
ret = rsb_write(msg->addr, reg++, *(msg->buf++));
}
}
if (ret) {
debug("sunxi_rsb_xfer: error sending\n");
return -EREMOTEIO;
}
}
return ret;
}
int sunxi_rsb_set_bus_speed(struct udevice *bus, unsigned int speed)
{
debug("sunxi_rsb_set_bus_speed\n");
return 0;
}
static int sunxi_rsb_ofdata_to_platdata(struct udevice *bus)
{
debug("sunxi_rsb_ofdata_to_platdata\n");
return 0;
}
static int sunxi_rsb_probe(struct udevice *bus)
{
struct sunxi_rsb *priv = dev_get_priv(bus);
int ret;
debug("sunxi_rsb_probe\n");
/* make sure the RSB bus is initialised */
ret = pmic_bus_init();
debug("retval from pmic_bus_init(): %d\n", ret);
priv->regs = (void *)dev_get_addr(bus);
return 0;
}
static const struct dm_i2c_ops sunxi_rsb_ops = {
.xfer = sunxi_rsb_xfer,
.set_bus_speed = sunxi_rsb_set_bus_speed,
};
static const struct udevice_id sunxi_rsb_ids[] = {
{ .compatible = "allwinner,sun8i-a23-rsb" },
{ }
};
U_BOOT_DRIVER(i2c_rockchip) = {
.name = "sunxi_rsb",
.id = UCLASS_I2C,
.flags = DM_I2C_CHIP_RD_ADDRESS | DM_I2C_CHIP_WR_ADDRESS,
.of_match = sunxi_rsb_ids,
.ofdata_to_platdata = sunxi_rsb_ofdata_to_platdata,
.probe = sunxi_rsb_probe,
.priv_auto_alloc_size = sizeof(struct sunxi_rsb),
.ops = &sunxi_rsb_ops,
};
|