diff options
Diffstat (limited to 'arch/arm/mach-omap2/i2c.c')
-rw-r--r-- | arch/arm/mach-omap2/i2c.c | 69 |
1 files changed, 66 insertions, 3 deletions
diff --git a/arch/arm/mach-omap2/i2c.c b/arch/arm/mach-omap2/i2c.c index fc57e67b321f..4e63097e3cd8 100644 --- a/arch/arm/mach-omap2/i2c.c +++ b/arch/arm/mach-omap2/i2c.c | |||
@@ -19,11 +19,13 @@ | |||
19 | * | 19 | * |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <plat/i2c.h> | 22 | #include "soc.h" |
23 | #include "common.h" | 23 | #include "common.h" |
24 | #include <plat/omap_hwmod.h> | 24 | #include "omap_hwmod.h" |
25 | #include "omap_device.h" | ||
25 | 26 | ||
26 | #include "mux.h" | 27 | #include "mux.h" |
28 | #include "i2c.h" | ||
27 | 29 | ||
28 | /* In register I2C_CON, Bit 15 is the I2C enable bit */ | 30 | /* In register I2C_CON, Bit 15 is the I2C enable bit */ |
29 | #define I2C_EN BIT(15) | 31 | #define I2C_EN BIT(15) |
@@ -33,7 +35,9 @@ | |||
33 | /* Maximum microseconds to wait for OMAP module to softreset */ | 35 | /* Maximum microseconds to wait for OMAP module to softreset */ |
34 | #define MAX_MODULE_SOFTRESET_WAIT 10000 | 36 | #define MAX_MODULE_SOFTRESET_WAIT 10000 |
35 | 37 | ||
36 | void __init omap2_i2c_mux_pins(int bus_id) | 38 | #define MAX_OMAP_I2C_HWMOD_NAME_LEN 16 |
39 | |||
40 | static void __init omap2_i2c_mux_pins(int bus_id) | ||
37 | { | 41 | { |
38 | char mux_name[sizeof("i2c2_scl.i2c2_scl")]; | 42 | char mux_name[sizeof("i2c2_scl.i2c2_scl")]; |
39 | 43 | ||
@@ -104,3 +108,62 @@ int omap_i2c_reset(struct omap_hwmod *oh) | |||
104 | 108 | ||
105 | return 0; | 109 | return 0; |
106 | } | 110 | } |
111 | |||
112 | static int __init omap_i2c_nr_ports(void) | ||
113 | { | ||
114 | int ports = 0; | ||
115 | |||
116 | if (cpu_is_omap24xx()) | ||
117 | ports = 2; | ||
118 | else if (cpu_is_omap34xx()) | ||
119 | ports = 3; | ||
120 | else if (cpu_is_omap44xx()) | ||
121 | ports = 4; | ||
122 | return ports; | ||
123 | } | ||
124 | |||
125 | static const char name[] = "omap_i2c"; | ||
126 | |||
127 | int __init omap_i2c_add_bus(struct omap_i2c_bus_platform_data *i2c_pdata, | ||
128 | int bus_id) | ||
129 | { | ||
130 | int l; | ||
131 | struct omap_hwmod *oh; | ||
132 | struct platform_device *pdev; | ||
133 | char oh_name[MAX_OMAP_I2C_HWMOD_NAME_LEN]; | ||
134 | struct omap_i2c_bus_platform_data *pdata; | ||
135 | struct omap_i2c_dev_attr *dev_attr; | ||
136 | |||
137 | if (bus_id > omap_i2c_nr_ports()) | ||
138 | return -EINVAL; | ||
139 | |||
140 | omap2_i2c_mux_pins(bus_id); | ||
141 | |||
142 | l = snprintf(oh_name, MAX_OMAP_I2C_HWMOD_NAME_LEN, "i2c%d", bus_id); | ||
143 | WARN(l >= MAX_OMAP_I2C_HWMOD_NAME_LEN, | ||
144 | "String buffer overflow in I2C%d device setup\n", bus_id); | ||
145 | oh = omap_hwmod_lookup(oh_name); | ||
146 | if (!oh) { | ||
147 | pr_err("Could not look up %s\n", oh_name); | ||
148 | return -EEXIST; | ||
149 | } | ||
150 | |||
151 | pdata = i2c_pdata; | ||
152 | /* | ||
153 | * pass the hwmod class's CPU-specific knowledge of I2C IP revision in | ||
154 | * use, and functionality implementation flags, up to the OMAP I2C | ||
155 | * driver via platform data | ||
156 | */ | ||
157 | pdata->rev = oh->class->rev; | ||
158 | |||
159 | dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr; | ||
160 | pdata->flags = dev_attr->flags; | ||
161 | |||
162 | pdev = omap_device_build(name, bus_id, oh, pdata, | ||
163 | sizeof(struct omap_i2c_bus_platform_data), | ||
164 | NULL, 0, 0); | ||
165 | WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", name); | ||
166 | |||
167 | return PTR_RET(pdev); | ||
168 | } | ||
169 | |||