diff options
author | Rabin Vincent <rabin.vincent@stericsson.com> | 2011-01-21 00:26:16 -0500 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2011-03-14 09:05:10 -0400 |
commit | 705e0984444bc7109c5686c36333b27119d8a888 (patch) | |
tree | 3abc89595f1d0eabf6a7b320d2ca493af07b415e /arch | |
parent | 871056e7dfb6164ffd6c6665752f921f9d5c6a81 (diff) |
mach-ux500: dynamic UIB (user interface boards) detection
Add support for dynamic detection of the UIB used (at the cost of one i2c error
on the lesser-used UIB) and also provide an override via a command line
parameter if needed.
Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
Signed-off-by: Sundar Iyer <sundar.iyer@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-ux500/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500-stuib.c | 14 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500-u8500uib.c | 14 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500-uib.c | 135 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500.h | 8 |
6 files changed, 173 insertions, 4 deletions
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index 0352272dc600..ef67952ed420 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile | |||
@@ -8,7 +8,9 @@ obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o | |||
8 | obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o prcmu.o | 8 | obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o prcmu.o |
9 | obj-$(CONFIG_MACH_U8500) += board-mop500.o board-mop500-sdi.o \ | 9 | obj-$(CONFIG_MACH_U8500) += board-mop500.o board-mop500-sdi.o \ |
10 | board-mop500-keypads.o \ | 10 | board-mop500-keypads.o \ |
11 | board-mop500-regulators.o | 11 | board-mop500-regulators.o \ |
12 | board-mop500-uib.o board-mop500-stuib.o \ | ||
13 | board-mop500-u8500uib.o | ||
12 | obj-$(CONFIG_MACH_U5500) += board-u5500.o board-u5500-sdi.o | 14 | obj-$(CONFIG_MACH_U5500) += board-u5500.o board-u5500-sdi.o |
13 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | 15 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o |
14 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | 16 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o |
diff --git a/arch/arm/mach-ux500/board-mop500-stuib.c b/arch/arm/mach-ux500/board-mop500-stuib.c new file mode 100644 index 000000000000..7fa30217cc01 --- /dev/null +++ b/arch/arm/mach-ux500/board-mop500-stuib.c | |||
@@ -0,0 +1,14 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * License terms: GNU General Public License (GPL), version 2 | ||
5 | */ | ||
6 | |||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/init.h> | ||
9 | |||
10 | #include "board-mop500.h" | ||
11 | |||
12 | void __init mop500_stuib_init(void) | ||
13 | { | ||
14 | } | ||
diff --git a/arch/arm/mach-ux500/board-mop500-u8500uib.c b/arch/arm/mach-ux500/board-mop500-u8500uib.c new file mode 100644 index 000000000000..e81c65b2f721 --- /dev/null +++ b/arch/arm/mach-ux500/board-mop500-u8500uib.c | |||
@@ -0,0 +1,14 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * License terms: GNU General Public License (GPL), version 2 | ||
5 | */ | ||
6 | |||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/init.h> | ||
9 | |||
10 | #include "board-mop500.h" | ||
11 | |||
12 | void __init mop500_u8500uib_init(void) | ||
13 | { | ||
14 | } | ||
diff --git a/arch/arm/mach-ux500/board-mop500-uib.c b/arch/arm/mach-ux500/board-mop500-uib.c new file mode 100644 index 000000000000..69cce41f602a --- /dev/null +++ b/arch/arm/mach-ux500/board-mop500-uib.c | |||
@@ -0,0 +1,135 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | ||
5 | * License terms: GNU General Public License (GPL), version 2 | ||
6 | */ | ||
7 | |||
8 | #define pr_fmt(fmt) "mop500-uib: " fmt | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/i2c.h> | ||
13 | |||
14 | #include <mach/hardware.h> | ||
15 | #include "board-mop500.h" | ||
16 | |||
17 | enum mop500_uib { | ||
18 | STUIB, | ||
19 | U8500UIB, | ||
20 | }; | ||
21 | |||
22 | struct uib { | ||
23 | const char *name; | ||
24 | const char *option; | ||
25 | void (*init)(void); | ||
26 | }; | ||
27 | |||
28 | static struct __initdata uib mop500_uibs[] = { | ||
29 | [STUIB] = { | ||
30 | .name = "ST-UIB", | ||
31 | .option = "stuib", | ||
32 | .init = mop500_stuib_init, | ||
33 | }, | ||
34 | [U8500UIB] = { | ||
35 | .name = "U8500-UIB", | ||
36 | .option = "u8500uib", | ||
37 | .init = mop500_u8500uib_init, | ||
38 | }, | ||
39 | }; | ||
40 | |||
41 | static struct uib *mop500_uib; | ||
42 | |||
43 | static int __init mop500_uib_setup(char *str) | ||
44 | { | ||
45 | int i; | ||
46 | |||
47 | for (i = 0; i < ARRAY_SIZE(mop500_uibs); i++) { | ||
48 | struct uib *uib = &mop500_uibs[i]; | ||
49 | |||
50 | if (!strcmp(str, uib->option)) { | ||
51 | mop500_uib = uib; | ||
52 | break; | ||
53 | } | ||
54 | } | ||
55 | |||
56 | if (i == ARRAY_SIZE(mop500_uibs)) | ||
57 | pr_err("invalid uib= option (%s)\n", str); | ||
58 | |||
59 | return 1; | ||
60 | } | ||
61 | __setup("uib=", mop500_uib_setup); | ||
62 | |||
63 | /* | ||
64 | * The UIBs are detected after the I2C host controllers are registered, so | ||
65 | * i2c_register_board_info() can't be used. | ||
66 | */ | ||
67 | void mop500_uib_i2c_add(int busnum, struct i2c_board_info *info, | ||
68 | unsigned n) | ||
69 | { | ||
70 | struct i2c_adapter *adap; | ||
71 | struct i2c_client *client; | ||
72 | int i; | ||
73 | |||
74 | adap = i2c_get_adapter(busnum); | ||
75 | if (!adap) { | ||
76 | pr_err("failed to get adapter i2c%d\n", busnum); | ||
77 | return; | ||
78 | } | ||
79 | |||
80 | for (i = 0; i < n; i++) { | ||
81 | client = i2c_new_device(adap, &info[i]); | ||
82 | if (!client) | ||
83 | pr_err("failed to register %s to i2c%d\n", | ||
84 | info[i].type, busnum); | ||
85 | } | ||
86 | |||
87 | i2c_put_adapter(adap); | ||
88 | } | ||
89 | |||
90 | static void __init __mop500_uib_init(struct uib *uib, const char *why) | ||
91 | { | ||
92 | pr_info("%s (%s)\n", uib->name, why); | ||
93 | uib->init(); | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * Detect the UIB attached based on the presence or absence of i2c devices. | ||
98 | */ | ||
99 | static int __init mop500_uib_init(void) | ||
100 | { | ||
101 | struct uib *uib = mop500_uib; | ||
102 | struct i2c_adapter *i2c0; | ||
103 | int ret; | ||
104 | |||
105 | if (!cpu_is_u8500()) | ||
106 | return -ENODEV; | ||
107 | |||
108 | if (uib) { | ||
109 | __mop500_uib_init(uib, "from uib= boot argument"); | ||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | i2c0 = i2c_get_adapter(0); | ||
114 | if (!i2c0) { | ||
115 | __mop500_uib_init(&mop500_uibs[STUIB], | ||
116 | "fallback, could not get i2c0"); | ||
117 | return -ENODEV; | ||
118 | } | ||
119 | |||
120 | /* U8500-UIB has the TC35893 at 0x44 on I2C0, the ST-UIB doesn't. */ | ||
121 | ret = i2c_smbus_xfer(i2c0, 0x44, 0, I2C_SMBUS_WRITE, 0, | ||
122 | I2C_SMBUS_QUICK, NULL); | ||
123 | i2c_put_adapter(i2c0); | ||
124 | |||
125 | if (ret == 0) | ||
126 | uib = &mop500_uibs[U8500UIB]; | ||
127 | else | ||
128 | uib = &mop500_uibs[STUIB]; | ||
129 | |||
130 | __mop500_uib_init(uib, "detected"); | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | module_init(mop500_uib_init); | ||
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index a393f57ed2a8..1a839ccad4f8 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c | |||
@@ -207,8 +207,6 @@ static void __init u8500_init_machine(void) | |||
207 | mop500_spi_init(); | 207 | mop500_spi_init(); |
208 | mop500_uart_init(); | 208 | mop500_uart_init(); |
209 | 209 | ||
210 | mop500_keypad_init(); | ||
211 | |||
212 | platform_device_register(&ab8500_device); | 210 | platform_device_register(&ab8500_device); |
213 | 211 | ||
214 | i2c_register_board_info(0, mop500_i2c0_devices, | 212 | i2c_register_board_info(0, mop500_i2c0_devices, |
diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h index 3104ae2a02c2..cedf8ebaad95 100644 --- a/arch/arm/mach-ux500/board-mop500.h +++ b/arch/arm/mach-ux500/board-mop500.h | |||
@@ -14,8 +14,14 @@ | |||
14 | #define GPIO_SDMMC_EN MOP500_EGPIO(17) | 14 | #define GPIO_SDMMC_EN MOP500_EGPIO(17) |
15 | #define GPIO_SDMMC_1V8_3V_SEL MOP500_EGPIO(18) | 15 | #define GPIO_SDMMC_1V8_3V_SEL MOP500_EGPIO(18) |
16 | 16 | ||
17 | struct i2c_board_info; | ||
18 | |||
17 | extern void mop500_sdi_init(void); | 19 | extern void mop500_sdi_init(void); |
18 | extern void mop500_sdi_tc35892_init(void); | 20 | extern void mop500_sdi_tc35892_init(void); |
19 | extern void mop500_keypad_init(void); | 21 | void __init mop500_u8500uib_init(void); |
22 | void __init mop500_stuib_init(void); | ||
23 | |||
24 | void mop500_uib_i2c_add(int busnum, struct i2c_board_info *info, | ||
25 | unsigned n); | ||
20 | 26 | ||
21 | #endif | 27 | #endif |