Skip to content

Commit 38ffc8a

Browse files
committed
boardinfo: Add the board_info driver to display board info.
cat /proc/boardinfo cat /proc/boardver cat /proc/ddr Change-Id: Ib61c3a0576e96ae0913be6bd0ee463ee027a6629
1 parent b392704 commit 38ffc8a

7 files changed

Lines changed: 314 additions & 0 deletions

File tree

arch/arm/boot/dts/rk3288-tinker-board.dts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,22 @@
219219
linux,default-trigger="default-off";
220220
};
221221
};
222+
223+
board_info: board-info {
224+
compatible = "board-info";
225+
226+
hw-id0 = <&gpio2 RK_PB0 GPIO_ACTIVE_HIGH>;
227+
hw-id1 = <&gpio2 RK_PB1 GPIO_ACTIVE_HIGH>;
228+
hw-id2 = <&gpio2 RK_PB2 GPIO_ACTIVE_HIGH>;
229+
230+
pid-id0 = <&gpio2 RK_PA1 GPIO_ACTIVE_HIGH>;
231+
pid-id1 = <&gpio2 RK_PA2 GPIO_ACTIVE_HIGH>;
232+
pid-id2 = <&gpio2 RK_PA3 GPIO_ACTIVE_HIGH>;
233+
234+
ddr-id0 = <&gpio2 RK_PB4 GPIO_ACTIVE_HIGH>;
235+
ddr-id1 = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>;
236+
ddr-id2 = <&gpio2 RK_PB6 GPIO_ACTIVE_HIGH>;
237+
};
222238
};
223239

224240
&cif {

arch/arm/configs/rockchip_linux_defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# CONFIG_LOCALVERSION_AUTO is not set
22
CONFIG_DEFAULT_HOSTNAME="localhost"
3+
CONFIG_BOARDINFO=y
34
CONFIG_SYSVIPC=y
45
CONFIG_POSIX_MQUEUE=y
56
CONFIG_FHANDLE=y

drivers/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,4 +208,6 @@ source "drivers/rk_nand/Kconfig"
208208

209209
source "drivers/headset_observe/Kconfig"
210210

211+
source "drivers/boardinfo/Kconfig"
212+
211213
endmenu

drivers/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,4 @@ obj-$(CONFIG_TEE) += tee/
183183
obj-$(CONFIG_RK_NAND) += rk_nand/
184184
obj-$(CONFIG_RK_HEADSET) += headset_observe/
185185
obj-$(CONFIG_RK_FLASH) += rkflash/
186+
obj-$(CONFIG_BOARDINFO) += boardinfo/

drivers/boardinfo/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#
2+
# boardinfo drivers
3+
#
4+
# When adding new entries keep the list in alphabetical order
5+
6+
config BOARDINFO
7+
tristate "tinker boardinfo"
8+
default y
9+
help
10+
Driver to set board information.

drivers/boardinfo/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
obj-$(CONFIG_BOARDINFO) += boardinfo.o

drivers/boardinfo/boardinfo.c

Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
#include <linux/module.h>
2+
#include <linux/platform_device.h>
3+
#include <linux/gpio.h>
4+
#include <linux/of_platform.h>
5+
#include <linux/of_gpio.h>
6+
#include <linux/proc_fs.h>
7+
8+
static int hw_id0, hw_id1, hw_id2;
9+
static int pid_id0, pid_id1, pid_id2;
10+
static int ddr_id0, ddr_id1, ddr_id2;
11+
12+
static const struct of_device_id of_board_info_match[] = {
13+
{ .compatible = "board-info", },
14+
{},
15+
};
16+
MODULE_DEVICE_TABLE(of, of_board_info_match);
17+
18+
static int ver_show(struct seq_file *m, void *v)
19+
{
20+
int id0, id1, id2;
21+
int hwid;
22+
char *boardver;
23+
24+
id0 = gpio_get_value(hw_id0);
25+
id1 = gpio_get_value(hw_id1);
26+
id2 = gpio_get_value(hw_id2);
27+
28+
hwid = (id2 << 2) + (id1 << 1) + id0;
29+
30+
if (hwid == 0)
31+
boardver = "0";
32+
else if (hwid == 1)
33+
boardver = "1";
34+
else if (hwid == 2)
35+
boardver = "2";
36+
else
37+
boardver = "unknown";
38+
39+
seq_printf(m, "%s\n", boardver);
40+
return 0;
41+
}
42+
43+
static int info_show(struct seq_file *m, void *v)
44+
{
45+
int id0, id1, id2;
46+
int pid;
47+
char *boardinfo;
48+
49+
id0 = gpio_get_value(pid_id0);
50+
id1 = gpio_get_value(pid_id1);
51+
id2 = gpio_get_value(pid_id2);
52+
53+
pid = (id2 << 2) + (id1 << 1) + id0;
54+
55+
if (pid == 0)
56+
boardinfo = "Tinker Board S";
57+
else if (pid == 4)
58+
boardinfo = "Tinker R/BR";
59+
else if (pid == 7)
60+
boardinfo = "Tinker Board";
61+
else
62+
boardinfo = "unknown";
63+
64+
seq_printf(m, "%s\n", boardinfo);
65+
return 0;
66+
}
67+
68+
static int ddr_show(struct seq_file *m, void *v)
69+
{
70+
int id0, id1, id2;
71+
int ddrid;
72+
char *ddr;
73+
74+
id0 = gpio_get_value(ddr_id0);
75+
id1 = gpio_get_value(ddr_id1);
76+
id2 = gpio_get_value(ddr_id2);
77+
78+
ddrid = (id2 << 2) + (id1 << 1) + id0;
79+
80+
if (ddrid == 0)
81+
ddr = "4GB";
82+
else if (ddrid == 2)
83+
ddr = "2GB";
84+
else if (ddrid == 4)
85+
ddr = "1GB";
86+
else
87+
ddr = "unknown";
88+
89+
seq_printf(m, "%s\n", ddr);
90+
return 0;
91+
}
92+
93+
static int ver_open(struct inode *inode, struct file *file)
94+
{
95+
return single_open(file, ver_show, NULL);
96+
}
97+
98+
static int info_open(struct inode *inode, struct file *file)
99+
{
100+
return single_open(file, info_show, NULL);
101+
}
102+
103+
static int ddr_open(struct inode *inode, struct file *file)
104+
{
105+
return single_open(file, ddr_show, NULL);
106+
}
107+
108+
static struct file_operations boardver_ops = {
109+
.owner = THIS_MODULE,
110+
.open = ver_open,
111+
.read = seq_read,
112+
};
113+
114+
static struct file_operations boardinfo_ops = {
115+
.owner = THIS_MODULE,
116+
.open = info_open,
117+
.read = seq_read,
118+
};
119+
120+
static struct file_operations ddr_ops = {
121+
.owner = THIS_MODULE,
122+
.open = ddr_open,
123+
.read = seq_read,
124+
};
125+
126+
static int board_info_probe(struct platform_device *pdev)
127+
{
128+
struct device *dev = &pdev->dev;
129+
int ret;
130+
struct proc_dir_entry* file;
131+
132+
hw_id0 = of_get_named_gpio(dev->of_node, "hw-id0", 0);
133+
if (!gpio_is_valid(hw_id0)) {
134+
printk("No hw-id0 pin available in board-info\n");
135+
return -ENODEV;
136+
} else {
137+
ret = devm_gpio_request_one(dev, hw_id0, GPIOF_DIR_IN, "HW_ID0");
138+
if (ret < 0) {
139+
printk("Fail to set hw-id0 pin\n");
140+
return ret;
141+
}
142+
}
143+
144+
hw_id1 = of_get_named_gpio(dev->of_node, "hw-id1", 0);
145+
if (!gpio_is_valid(hw_id1)) {
146+
printk("No hw-id1 pin available in board-info\n");
147+
return -ENODEV;
148+
} else {
149+
ret = devm_gpio_request_one(dev, hw_id1, GPIOF_DIR_IN, "HW_ID1");
150+
if (ret < 0) {
151+
printk("Fail to set hw-id1 pin\n");
152+
return ret;
153+
}
154+
}
155+
156+
hw_id2 = of_get_named_gpio(dev->of_node, "hw-id2", 0);
157+
if (!gpio_is_valid(hw_id2)) {
158+
printk("No hw-id2 pin available in board-info\n");
159+
return -ENODEV;
160+
} else {
161+
ret = devm_gpio_request_one(dev, hw_id2, GPIOF_DIR_IN, "HW_ID2");
162+
if (ret < 0) {
163+
printk("Fail to set hw-id2 pin\n");
164+
return ret;
165+
}
166+
}
167+
168+
pid_id0 = of_get_named_gpio(dev->of_node, "pid-id0", 0);
169+
if (!gpio_is_valid(pid_id0)) {
170+
printk("No pid-id0 pin available in board-info\n");
171+
return -ENODEV;
172+
} else {
173+
ret = devm_gpio_request_one(dev, pid_id0, GPIOF_DIR_IN, "PID_ID0");
174+
if (ret < 0) {
175+
printk("Fail to set pid-id0 pin\n");
176+
return ret;
177+
}
178+
}
179+
180+
pid_id1 = of_get_named_gpio(dev->of_node, "pid-id1", 0);
181+
if (!gpio_is_valid(pid_id1)) {
182+
printk("No pid-id1 pin available in board-info\n");
183+
return -ENODEV;
184+
} else {
185+
ret = devm_gpio_request_one(dev, pid_id1, GPIOF_DIR_IN, "PID_ID1");
186+
if (ret < 0) {
187+
printk("Fail to set pid-id1 pin\n");
188+
return ret;
189+
}
190+
}
191+
192+
pid_id2 = of_get_named_gpio(dev->of_node, "pid-id2", 0);
193+
if (!gpio_is_valid(pid_id2)) {
194+
printk("No pid-id2 pin available in board-info\n");
195+
return -ENODEV;
196+
} else {
197+
ret = devm_gpio_request_one(dev, pid_id2, GPIOF_DIR_IN, "PID_ID2");
198+
if (ret < 0) {
199+
printk("Fail to set pid-id2 pin\n");
200+
return ret;
201+
}
202+
}
203+
204+
ddr_id0 = of_get_named_gpio(dev->of_node, "ddr-id0", 0);
205+
if (!gpio_is_valid(ddr_id0)) {
206+
printk("No ddr-id0 pin available in board-info\n");
207+
return -ENODEV;
208+
} else {
209+
ret = devm_gpio_request_one(dev, ddr_id0, GPIOF_DIR_IN, "DDR_ID0");
210+
if (ret < 0) {
211+
printk("Fail to set ddr-id0 pin\n");
212+
return ret;
213+
}
214+
}
215+
216+
ddr_id1 = of_get_named_gpio(dev->of_node, "ddr-id1", 0);
217+
if (!gpio_is_valid(ddr_id1)) {
218+
printk("No ddr-id1 pin available in board-info\n");
219+
return -ENODEV;
220+
} else {
221+
ret = devm_gpio_request_one(dev, ddr_id1, GPIOF_DIR_IN, "DDR_ID1");
222+
if (ret < 0) {
223+
printk("Fail to set ddr-id1 pin\n");
224+
return ret;
225+
}
226+
}
227+
228+
ddr_id2 = of_get_named_gpio(dev->of_node, "ddr-id2", 0);
229+
if (!gpio_is_valid(ddr_id2)) {
230+
printk("No ddr-id2 pin available in board-info\n");
231+
return -ENODEV;
232+
} else {
233+
ret = devm_gpio_request_one(dev, ddr_id2, GPIOF_DIR_IN, "DDR_ID2");
234+
if (ret < 0) {
235+
printk("Fail to set ddr-id2 pin\n");
236+
return ret;
237+
}
238+
}
239+
240+
file = proc_create("boardver", 0444, NULL, &boardver_ops);
241+
if (!file)
242+
return -ENOMEM;
243+
244+
file = proc_create("boardinfo", 0444, NULL, &boardinfo_ops);
245+
if (!file)
246+
return -ENOMEM;
247+
248+
file = proc_create("ddr", 0444, NULL, &ddr_ops);
249+
if (!file)
250+
return -ENOMEM;
251+
252+
return 0;
253+
}
254+
255+
static int board_info_remove(struct platform_device *pdev)
256+
{
257+
gpio_free(hw_id0);
258+
gpio_free(hw_id1);
259+
gpio_free(hw_id2);
260+
261+
gpio_free(pid_id0);
262+
gpio_free(pid_id1);
263+
gpio_free(pid_id2);
264+
265+
gpio_free(ddr_id0);
266+
gpio_free(ddr_id1);
267+
gpio_free(ddr_id2);
268+
269+
return 0;
270+
}
271+
272+
static struct platform_driver boardinfo_driver = {
273+
.probe = board_info_probe,
274+
.remove = board_info_remove,
275+
.driver = {
276+
.name = "board-info",
277+
#ifdef CONFIG_OF_GPIO
278+
.of_match_table = of_match_ptr(of_board_info_match),
279+
#endif
280+
},
281+
};
282+
283+
module_platform_driver(boardinfo_driver);

0 commit comments

Comments
 (0)