aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-ux500/board-mop500-uib.c
diff options
context:
space:
mode:
authorRabin Vincent <rabin.vincent@stericsson.com>2011-01-21 00:26:16 -0500
committerLinus Walleij <linus.walleij@linaro.org>2011-03-14 09:05:10 -0400
commit705e0984444bc7109c5686c36333b27119d8a888 (patch)
tree3abc89595f1d0eabf6a7b320d2ca493af07b415e /arch/arm/mach-ux500/board-mop500-uib.c
parent871056e7dfb6164ffd6c6665752f921f9d5c6a81 (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/arm/mach-ux500/board-mop500-uib.c')
-rw-r--r--arch/arm/mach-ux500/board-mop500-uib.c135
1 files changed, 135 insertions, 0 deletions
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
17enum mop500_uib {
18 STUIB,
19 U8500UIB,
20};
21
22struct uib {
23 const char *name;
24 const char *option;
25 void (*init)(void);
26};
27
28static 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
41static struct uib *mop500_uib;
42
43static 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 */
67void 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
90static 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 */
99static 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
135module_init(mop500_uib_init);