summaryrefslogtreecommitdiffstats
path: root/arch/arm/boards/udoo-neo/board.c
blob: d9b9517fc1de23127b60aefc59344b1875bcd19b (plain)
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
105
106
107
108
109
110
111
112
113
114
115
116
117
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: 2014 Sascha Hauer, Pengutronix

#include <common.h>
#include <deep-probe.h>
#include <gpio.h>
#include <mach/imx/bbu.h>
#include <mach/imx/imx6.h>

/**
 * Detects the board model by checking the R184 and R185 resistors.
 * A mounted resistor (0Ohm) connects the GPIO to ground, so the
 * GPIO value will be 0.
 *
 * FULL     - Eth, WiFi, motion sensors, 1GB RAM         -> R184 not mounted - R185 mounted
 * EXTENDED - NO Eth, WiFi, motion sensors, 1GB RAM      -> R184 not mounted - R185 not mounted
 * BASE     - Eth, NO WiFi, NO motion sensors, 512MB RAM -> R184 mounted     - R185 mounted
 * BASE KS  - NO Eth, WiFi, NO motion sensors, 512MB RAM -> R184 mounted     - R185 not mounted
 */

enum imx6sx_udoneo_board_type {
	UDOO_NEO_BASIC = 0,
	UDOO_NEO_BASIC_KS = 1,
	UDOO_NEO_FULL = 2,
	UDOO_NEO_EXTENDED = 3,
	UDOO_NEO_UNKNOWN,
};

#define GPIO_R184 IMX_GPIO_NR(4, 13)
#define GPIO_R185 IMX_GPIO_NR(4, 0)

static enum imx6sx_udoneo_board_type imx6sx_udoneo_detect(struct device *dev)
{
	struct device_node *gpio_np = NULL;
	int r184, r185;
	int ret;

	gpio_np = of_find_node_by_name_address(NULL, "gpio@20a8000");
	if (gpio_np) {
		ret = of_device_ensure_probed(gpio_np);
		if (ret) {
			dev_warn(dev, "Can't probe GPIO node\n");
			goto detect_error;
		}
	} else {
		dev_warn(dev, "Can't get GPIO node\n");
		goto detect_error;
	}

	ret = gpio_request(GPIO_R184, "version r184");
	if (ret)
		goto detect_error;

	ret = gpio_request(GPIO_R185, "version r185");
	if (ret)
		goto detect_error;

	ret = gpio_direction_input(GPIO_R184);
	if (ret)
		goto detect_error;

	ret = gpio_direction_input(GPIO_R185);
	if (ret)
		goto detect_error;

	r184 = gpio_get_value(GPIO_R184);
	r185 = gpio_get_value(GPIO_R185);

	return r184 << 1 | r185 << 0;

detect_error:
	dev_warn(dev, "Board detection failed\n");

	return UDOO_NEO_UNKNOWN;
}

static int imx6sx_udoneo_probe(struct device *dev)
{
	enum imx6sx_udoneo_board_type type;
	const char *model;

	type = imx6sx_udoneo_detect(dev);
	switch (type) {
	case UDOO_NEO_FULL:
		model = "UDOO Neo Full";
		break;
	case UDOO_NEO_EXTENDED:
		model = "UDOO Neo Extended";
		break;
	case UDOO_NEO_BASIC:
		model = "UDOO Neo Basic";
		break;
	default:
		model = "UDOO Neo unknown";
	}

	barebox_set_model(model);
	barebox_set_hostname("mx6sx-udooneo");

	imx6_bbu_internal_mmc_register_handler("emmc", "/dev/mmc1.barebox",
			BBU_HANDLER_FLAG_DEFAULT);

	return 0;
}

static const struct of_device_id imx6sx_udoneo_of_match[] = {
	{ .compatible = "udoo,neofull" },
	{ /* sentinel */ },
};
BAREBOX_DEEP_PROBE_ENABLE(imx6sx_udoneo_of_match);

static struct driver imx6sx_udoneo_driver = {
	.name = "board-udoo-neo",
	.probe = imx6sx_udoneo_probe,
	.of_compatible = imx6sx_udoneo_of_match,
};
postcore_platform_driver(imx6sx_udoneo_driver);