]>
Commit | Line | Data |
---|---|---|
004e67c2 MS |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* | |
3 | * (C) Copyright 2018 | |
4 | * Mario Six, Guntermann & Drunck GmbH, [email protected] | |
5 | */ | |
6 | ||
7 | #include <common.h> | |
8 | #include <dm.h> | |
9 | #include <misc.h> | |
10 | ||
11 | struct misc_sandbox_priv { | |
12 | u8 mem[128]; | |
13 | ulong last_ioctl; | |
14 | bool enabled; | |
15 | }; | |
16 | ||
17 | int misc_sandbox_read(struct udevice *dev, int offset, void *buf, int size) | |
18 | { | |
19 | struct misc_sandbox_priv *priv = dev_get_priv(dev); | |
20 | ||
21 | memcpy(buf, priv->mem + offset, size); | |
22 | ||
8729b1ae | 23 | return size; |
004e67c2 MS |
24 | } |
25 | ||
26 | int misc_sandbox_write(struct udevice *dev, int offset, const void *buf, | |
27 | int size) | |
28 | { | |
29 | struct misc_sandbox_priv *priv = dev_get_priv(dev); | |
30 | ||
31 | memcpy(priv->mem + offset, buf, size); | |
32 | ||
8729b1ae | 33 | return size; |
004e67c2 MS |
34 | } |
35 | ||
36 | int misc_sandbox_ioctl(struct udevice *dev, unsigned long request, void *buf) | |
37 | { | |
38 | struct misc_sandbox_priv *priv = dev_get_priv(dev); | |
39 | ||
40 | priv->last_ioctl = request; | |
41 | ||
42 | return 0; | |
43 | } | |
44 | ||
45 | int misc_sandbox_call(struct udevice *dev, int msgid, void *tx_msg, | |
46 | int tx_size, void *rx_msg, int rx_size) | |
47 | { | |
48 | struct misc_sandbox_priv *priv = dev_get_priv(dev); | |
49 | ||
50 | if (msgid == 0) { | |
51 | int num = *(int *)tx_msg; | |
52 | ||
53 | switch (num) { | |
54 | case 0: | |
55 | strncpy(rx_msg, "Zero", rx_size); | |
56 | break; | |
57 | case 1: | |
58 | strncpy(rx_msg, "One", rx_size); | |
59 | break; | |
60 | case 2: | |
61 | strncpy(rx_msg, "Two", rx_size); | |
62 | break; | |
63 | default: | |
64 | return -EINVAL; | |
65 | } | |
66 | } | |
67 | ||
68 | if (msgid == 1) { | |
69 | int num = *(int *)tx_msg; | |
70 | ||
71 | switch (num) { | |
72 | case 0: | |
73 | strncpy(rx_msg, "Forty", rx_size); | |
74 | break; | |
75 | case 1: | |
76 | strncpy(rx_msg, "Forty-one", rx_size); | |
77 | break; | |
78 | case 2: | |
79 | strncpy(rx_msg, "Forty-two", rx_size); | |
80 | break; | |
81 | default: | |
82 | return -EINVAL; | |
83 | } | |
84 | } | |
85 | ||
86 | if (msgid == 2) | |
87 | memcpy(rx_msg, &priv->last_ioctl, sizeof(priv->last_ioctl)); | |
88 | ||
89 | if (msgid == 3) | |
90 | memcpy(rx_msg, &priv->enabled, sizeof(priv->enabled)); | |
91 | ||
92 | return 0; | |
93 | } | |
94 | ||
95 | int misc_sandbox_set_enabled(struct udevice *dev, bool val) | |
96 | { | |
97 | struct misc_sandbox_priv *priv = dev_get_priv(dev); | |
98 | ||
99 | priv->enabled = !priv->enabled; | |
100 | ||
101 | return 0; | |
102 | } | |
103 | ||
104 | static const struct misc_ops misc_sandbox_ops = { | |
105 | .read = misc_sandbox_read, | |
106 | .write = misc_sandbox_write, | |
107 | .ioctl = misc_sandbox_ioctl, | |
108 | .call = misc_sandbox_call, | |
109 | .set_enabled = misc_sandbox_set_enabled, | |
110 | }; | |
111 | ||
112 | int misc_sandbox_probe(struct udevice *dev) | |
113 | { | |
114 | struct misc_sandbox_priv *priv = dev_get_priv(dev); | |
115 | ||
116 | priv->enabled = true; | |
117 | ||
118 | return 0; | |
119 | } | |
120 | ||
121 | static const struct udevice_id misc_sandbox_ids[] = { | |
122 | { .compatible = "sandbox,misc_sandbox" }, | |
123 | { } | |
124 | }; | |
125 | ||
126 | U_BOOT_DRIVER(misc_sandbox) = { | |
127 | .name = "misc_sandbox", | |
128 | .id = UCLASS_MISC, | |
129 | .ops = &misc_sandbox_ops, | |
130 | .of_match = misc_sandbox_ids, | |
131 | .probe = misc_sandbox_probe, | |
41575d8e | 132 | .priv_auto = sizeof(struct misc_sandbox_priv), |
004e67c2 | 133 | }; |