blob: e5c0e6e25cf672452869f9b8807d193a56aba324 [file] [log] [blame]
Linus Walleijed781d32012-05-03 00:44:52 +02001
Srinidhi Kasagaraa44ef42009-11-28 08:17:18 +01002/*
3 * Copyright (C) 2008-2009 ST-Ericsson
4 *
5 * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2, as
9 * published by the Free Software Foundation.
10 *
11 */
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/interrupt.h>
15#include <linux/platform_device.h>
16#include <linux/io.h>
Rabin Vincentb8410a12010-08-09 19:18:17 +053017#include <linux/i2c.h>
Rabin Vincentea05a572010-06-03 07:58:42 +010018#include <linux/gpio.h>
Srinidhi Kasagaraa44ef42009-11-28 08:17:18 +010019#include <linux/amba/bus.h>
20#include <linux/amba/pl022.h>
Linus Walleij5d7b8462010-10-14 13:57:59 +020021#include <linux/amba/serial.h>
Srinidhi Kasagaraa44ef42009-11-28 08:17:18 +010022#include <linux/spi/spi.h>
Linus Walleijee66e652011-12-02 14:16:33 +010023#include <linux/mfd/abx500/ab8500.h>
Bengt Jonsson79568b92011-03-11 11:54:46 +010024#include <linux/regulator/ab8500.h>
Sundar Iyer20406eb2010-12-13 09:33:14 +053025#include <linux/mfd/tc3589x.h>
Linus Walleijfe67dfc2011-03-07 11:48:15 +010026#include <linux/mfd/tps6105x.h>
Linus Walleijee66e652011-12-02 14:16:33 +010027#include <linux/mfd/abx500/ab8500-gpio.h>
Philippe Langlaisdd7b2a02011-01-12 11:26:20 +010028#include <linux/leds-lp5521.h>
Philippe Langlaisa71b8192011-01-14 10:53:59 +010029#include <linux/input.h>
Robert Marklund350abe02011-06-20 15:55:46 +020030#include <linux/smsc911x.h>
Philippe Langlaisa71b8192011-01-14 10:53:59 +010031#include <linux/gpio_keys.h>
Shreshtha Kumar Sahu1a7d4362011-06-13 10:11:44 +020032#include <linux/delay.h>
Srinidhi Kasagaraa44ef42009-11-28 08:17:18 +010033
Arnd Bergmann2d334292012-03-07 15:04:07 +000034#include <linux/of.h>
35#include <linux/of_platform.h>
36
Robert Marklund350abe02011-06-20 15:55:46 +020037#include <linux/leds.h>
Srinidhi Kasagaraa44ef42009-11-28 08:17:18 +010038#include <asm/mach-types.h>
39#include <asm/mach/arch.h>
Marc Zyngierbbf5f382011-09-06 10:23:45 +010040#include <asm/hardware/gic.h>
Srinidhi Kasagaraa44ef42009-11-28 08:17:18 +010041
Srinidhi Kasagard48a41c2010-02-03 13:02:48 +010042#include <plat/i2c.h>
Linus Walleij5d7b8462010-10-14 13:57:59 +020043#include <plat/ste_dma40.h>
Shreshtha Kumar Sahu1a7d4362011-06-13 10:11:44 +020044#include <plat/pincfg.h>
Linus Walleij0f332862011-08-22 08:33:30 +010045#include <plat/gpio-nomadik.h>
Srinidhi Kasagaraa44ef42009-11-28 08:17:18 +010046
47#include <mach/hardware.h>
48#include <mach/setup.h>
Rabin Vincent9e4e7fe2010-05-03 08:03:52 +010049#include <mach/devices.h>
Linus Walleij29aeb3c2010-09-06 22:15:08 +010050#include <mach/irqs.h>
Srinidhi Kasagaraa44ef42009-11-28 08:17:18 +010051
Shreshtha Kumar Sahu1a7d4362011-06-13 10:11:44 +020052#include "pins-db8500.h"
Linus Walleij5d7b8462010-10-14 13:57:59 +020053#include "ste-dma40-db8500.h"
Rabin Vincentfbf1ead2010-09-29 19:46:32 +053054#include "devices-db8500.h"
Hanumath Prasad008f8a22010-08-19 12:06:32 +010055#include "board-mop500.h"
Bengt Jonssona1e516e2010-12-10 11:08:48 +010056#include "board-mop500-regulators.h"
Ola Liljac0af14d2012-04-20 11:32:59 +020057#include "board-mop500-msp.h"
Rabin Vincentea05a572010-06-03 07:58:42 +010058
Robert Marklund350abe02011-06-20 15:55:46 +020059static struct gpio_led snowball_led_array[] = {
60 {
61 .name = "user_led",
62 .default_trigger = "none",
63 .gpio = 142,
64 },
65};
66
67static struct gpio_led_platform_data snowball_led_data = {
68 .leds = snowball_led_array,
69 .num_leds = ARRAY_SIZE(snowball_led_array),
70};
71
72static struct platform_device snowball_led_dev = {
73 .name = "leds-gpio",
74 .dev = {
75 .platform_data = &snowball_led_data,
76 },
77};
78
Bibek Basu3ef374a2011-02-15 12:56:16 +053079static struct ab8500_gpio_platform_data ab8500_gpio_pdata = {
Philippe Langlaisa1524ee2012-02-13 10:52:25 +010080 .gpio_base = MOP500_AB8500_PIN_GPIO(1),
Bibek Basu3ef374a2011-02-15 12:56:16 +053081 .irq_base = MOP500_AB8500_VIR_GPIO_IRQ_BASE,
82 /* config_reg is the initial configuration of ab8500 pins.
83 * The pins can be configured as GPIO or alt functions based
84 * on value present in GpioSel1 to GpioSel6 and AlternatFunction
85 * register. This is the array of 7 configuration settings.
86 * One has to compile time decide these settings. Below is the
Lucas De Marchi25985ed2011-03-30 22:57:33 -030087 * explanation of these setting
Bibek Basu3ef374a2011-02-15 12:56:16 +053088 * GpioSel1 = 0x00 => Pins GPIO1 to GPIO8 are not used as GPIO
89 * GpioSel2 = 0x1E => Pins GPIO10 to GPIO13 are configured as GPIO
90 * GpioSel3 = 0x80 => Pin GPIO24 is configured as GPIO
91 * GpioSel4 = 0x01 => Pin GPIo25 is configured as GPIO
92 * GpioSel5 = 0x7A => Pins GPIO34, GPIO36 to GPIO39 are conf as GPIO
93 * GpioSel6 = 0x00 => Pins GPIO41 & GPIo42 are not configured as GPIO
94 * AlternaFunction = 0x00 => If Pins GPIO10 to 13 are not configured
95 * as GPIO then this register selectes the alternate fucntions
96 */
97 .config_reg = {0x00, 0x1E, 0x80, 0x01,
98 0x7A, 0x00, 0x00},
99};
100
Robert Marklund350abe02011-06-20 15:55:46 +0200101static struct gpio_keys_button snowball_key_array[] = {
102 {
103 .gpio = 32,
104 .type = EV_KEY,
105 .code = KEY_1,
106 .desc = "userpb",
107 .active_low = 1,
108 .debounce_interval = 50,
109 .wakeup = 1,
110 },
111 {
112 .gpio = 151,
113 .type = EV_KEY,
114 .code = KEY_2,
115 .desc = "extkb1",
116 .active_low = 1,
117 .debounce_interval = 50,
118 .wakeup = 1,
119 },
120 {
121 .gpio = 152,
122 .type = EV_KEY,
123 .code = KEY_3,
124 .desc = "extkb2",
125 .active_low = 1,
126 .debounce_interval = 50,
127 .wakeup = 1,
128 },
129 {
130 .gpio = 161,
131 .type = EV_KEY,
132 .code = KEY_4,
133 .desc = "extkb3",
134 .active_low = 1,
135 .debounce_interval = 50,
136 .wakeup = 1,
137 },
138 {
139 .gpio = 162,
140 .type = EV_KEY,
141 .code = KEY_5,
142 .desc = "extkb4",
143 .active_low = 1,
144 .debounce_interval = 50,
145 .wakeup = 1,
146 },
147};
148
149static struct gpio_keys_platform_data snowball_key_data = {
150 .buttons = snowball_key_array,
151 .nbuttons = ARRAY_SIZE(snowball_key_array),
152};
153
154static struct platform_device snowball_key_dev = {
155 .name = "gpio-keys",
156 .id = -1,
157 .dev = {
158 .platform_data = &snowball_key_data,
159 }
160};
161
162static struct smsc911x_platform_config snowball_sbnet_cfg = {
163 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
164 .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
165 .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
166 .shift = 1,
167};
168
169static struct resource sbnet_res[] = {
170 {
171 .name = "smsc911x-memory",
172 .start = (0x5000 << 16),
173 .end = (0x5000 << 16) + 0xffff,
174 .flags = IORESOURCE_MEM,
175 },
176 {
177 .start = NOMADIK_GPIO_TO_IRQ(140),
178 .end = NOMADIK_GPIO_TO_IRQ(140),
179 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
180 },
181};
182
183static struct platform_device snowball_sbnet_dev = {
184 .name = "smsc911x",
185 .num_resources = ARRAY_SIZE(sbnet_res),
186 .resource = sbnet_res,
187 .dev = {
188 .platform_data = &snowball_sbnet_cfg,
189 },
190};
191
Rabin Vincent39ae7022010-07-26 11:12:15 +0100192static struct ab8500_platform_data ab8500_platdata = {
193 .irq_base = MOP500_AB8500_IRQ_BASE,
Bengt Jonssondfa3a822011-03-09 13:34:17 +0100194 .regulator_reg_init = ab8500_regulator_reg_init,
195 .num_regulator_reg_init = ARRAY_SIZE(ab8500_regulator_reg_init),
Bengt Jonssona1e516e2010-12-10 11:08:48 +0100196 .regulator = ab8500_regulators,
197 .num_regulator = ARRAY_SIZE(ab8500_regulators),
Bibek Basu3ef374a2011-02-15 12:56:16 +0530198 .gpio = &ab8500_gpio_pdata,
Rabin Vincent39ae7022010-07-26 11:12:15 +0100199};
200
Linus Walleij29aeb3c2010-09-06 22:15:08 +0100201static struct resource ab8500_resources[] = {
202 [0] = {
Rabin Vincent22039b72010-12-08 11:07:56 +0530203 .start = IRQ_DB8500_AB8500,
204 .end = IRQ_DB8500_AB8500,
205 .flags = IORESOURCE_IRQ
Linus Walleij29aeb3c2010-09-06 22:15:08 +0100206 }
207};
208
209struct platform_device ab8500_device = {
210 .name = "ab8500-i2c",
211 .id = 0,
212 .dev = {
213 .platform_data = &ab8500_platdata,
214 },
215 .num_resources = 1,
216 .resource = ab8500_resources,
217};
218
Rabin Vincentb8410a12010-08-09 19:18:17 +0530219/*
Linus Walleijfe67dfc2011-03-07 11:48:15 +0100220 * TPS61052
221 */
222
223static struct tps6105x_platform_data mop500_tps61052_data = {
224 .mode = TPS6105X_MODE_VOLTAGE,
225 .regulator_data = &tps61052_regulator,
226};
227
228/*
Rabin Vincentb8410a12010-08-09 19:18:17 +0530229 * TC35892
230 */
231
Sundar Iyer20406eb2010-12-13 09:33:14 +0530232static void mop500_tc35892_init(struct tc3589x *tc3589x, unsigned int base)
Rabin Vincentb8410a12010-08-09 19:18:17 +0530233{
Lee Jones18403422012-02-06 11:22:21 -0800234 struct device *parent = NULL;
235#if 0
236 /* FIXME: Is the sdi actually part of tc3589x? */
237 parent = tc3589x->dev;
238#endif
239 mop500_sdi_tc35892_init(parent);
Rabin Vincentb8410a12010-08-09 19:18:17 +0530240}
241
Sundar Iyer20406eb2010-12-13 09:33:14 +0530242static struct tc3589x_gpio_platform_data mop500_tc35892_gpio_data = {
Rabin Vincentb8410a12010-08-09 19:18:17 +0530243 .gpio_base = MOP500_EGPIO(0),
244 .setup = mop500_tc35892_init,
245};
246
Sundar Iyer20406eb2010-12-13 09:33:14 +0530247static struct tc3589x_platform_data mop500_tc35892_data = {
Sundar Iyer611b7592010-12-13 09:33:15 +0530248 .block = TC3589x_BLOCK_GPIO,
Rabin Vincentb8410a12010-08-09 19:18:17 +0530249 .gpio = &mop500_tc35892_gpio_data,
250 .irq_base = MOP500_EGPIO_IRQ_BASE,
251};
252
Philippe Langlaisdd7b2a02011-01-12 11:26:20 +0100253static struct lp5521_led_config lp5521_pri_led[] = {
254 [0] = {
255 .chan_nr = 0,
256 .led_current = 0x2f,
257 .max_current = 0x5f,
258 },
259 [1] = {
260 .chan_nr = 1,
261 .led_current = 0x2f,
262 .max_current = 0x5f,
263 },
264 [2] = {
265 .chan_nr = 2,
266 .led_current = 0x2f,
267 .max_current = 0x5f,
268 },
269};
270
271static struct lp5521_platform_data __initdata lp5521_pri_data = {
272 .label = "lp5521_pri",
273 .led_config = &lp5521_pri_led[0],
274 .num_channels = 3,
275 .clock_mode = LP5521_CLOCK_EXT,
276};
277
278static struct lp5521_led_config lp5521_sec_led[] = {
279 [0] = {
280 .chan_nr = 0,
281 .led_current = 0x2f,
282 .max_current = 0x5f,
283 },
284 [1] = {
285 .chan_nr = 1,
286 .led_current = 0x2f,
287 .max_current = 0x5f,
288 },
289 [2] = {
290 .chan_nr = 2,
291 .led_current = 0x2f,
292 .max_current = 0x5f,
293 },
294};
295
296static struct lp5521_platform_data __initdata lp5521_sec_data = {
297 .label = "lp5521_sec",
298 .led_config = &lp5521_sec_led[0],
299 .num_channels = 3,
300 .clock_mode = LP5521_CLOCK_EXT,
301};
302
Linus Walleijfe67dfc2011-03-07 11:48:15 +0100303static struct i2c_board_info __initdata mop500_i2c0_devices[] = {
Rabin Vincentb8410a12010-08-09 19:18:17 +0530304 {
Sundar Iyer20406eb2010-12-13 09:33:14 +0530305 I2C_BOARD_INFO("tc3589x", 0x42),
Philippe Langlaisdd7b2a02011-01-12 11:26:20 +0100306 .irq = NOMADIK_GPIO_TO_IRQ(217),
Rabin Vincentb8410a12010-08-09 19:18:17 +0530307 .platform_data = &mop500_tc35892_data,
308 },
Linus Walleijcf568c52011-03-30 14:31:42 +0200309 /* I2C0 devices only available prior to HREFv60 */
Linus Walleijfe67dfc2011-03-07 11:48:15 +0100310 {
311 I2C_BOARD_INFO("tps61052", 0x33),
312 .platform_data = &mop500_tps61052_data,
313 },
314};
315
Linus Walleijcf568c52011-03-30 14:31:42 +0200316#define NUM_PRE_V60_I2C0_DEVICES 1
317
Philippe Langlaisdd7b2a02011-01-12 11:26:20 +0100318static struct i2c_board_info __initdata mop500_i2c2_devices[] = {
319 {
320 /* lp5521 LED driver, 1st device */
321 I2C_BOARD_INFO("lp5521", 0x33),
322 .platform_data = &lp5521_pri_data,
323 },
324 {
325 /* lp5521 LED driver, 2st device */
326 I2C_BOARD_INFO("lp5521", 0x34),
327 .platform_data = &lp5521_sec_data,
328 },
Lee Jonesbb3b2182011-01-13 14:41:22 +0000329 {
330 /* Light sensor Rohm BH1780GLI */
331 I2C_BOARD_INFO("bh1780", 0x29),
332 },
Philippe Langlaisdd7b2a02011-01-12 11:26:20 +0100333};
334
Linus Walleij2b030bd2011-05-13 12:31:13 +0200335#define U8500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, t_out, _sm) \
Rabin Vincentf9faf232010-05-03 08:24:37 +0100336static struct nmk_i2c_controller u8500_i2c##id##_data = { \
Srinidhi Kasagard48a41c2010-02-03 13:02:48 +0100337 /* \
338 * slave data setup time, which is \
339 * 250 ns,100ns,10ns which is 14,6,2 \
340 * respectively for a 48 Mhz \
341 * i2c clock \
342 */ \
343 .slsu = _slsu, \
344 /* Tx FIFO threshold */ \
345 .tft = _tft, \
346 /* Rx FIFO threshold */ \
347 .rft = _rft, \
348 /* std. mode operation */ \
349 .clk_freq = clk, \
Linus Walleij2b030bd2011-05-13 12:31:13 +0200350 /* Slave response timeout(ms) */\
351 .timeout = t_out, \
Srinidhi Kasagard48a41c2010-02-03 13:02:48 +0100352 .sm = _sm, \
353}
354
355/*
356 * The board uses 4 i2c controllers, initialize all of
357 * them with slave data setup time of 250 ns,
Linus Walleij2b030bd2011-05-13 12:31:13 +0200358 * Tx & Rx FIFO threshold values as 8 and standard
Srinidhi Kasagard48a41c2010-02-03 13:02:48 +0100359 * mode of operation
360 */
Linus Walleij2b030bd2011-05-13 12:31:13 +0200361U8500_I2C_CONTROLLER(0, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST);
362U8500_I2C_CONTROLLER(1, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST);
363U8500_I2C_CONTROLLER(2, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST);
364U8500_I2C_CONTROLLER(3, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST);
Srinidhi Kasagard48a41c2010-02-03 13:02:48 +0100365
Lee Jones18403422012-02-06 11:22:21 -0800366static void __init mop500_i2c_init(struct device *parent)
Rabin Vincentfbf1ead2010-09-29 19:46:32 +0530367{
Lee Jones18403422012-02-06 11:22:21 -0800368 db8500_add_i2c0(parent, &u8500_i2c0_data);
369 db8500_add_i2c1(parent, &u8500_i2c1_data);
370 db8500_add_i2c2(parent, &u8500_i2c2_data);
371 db8500_add_i2c3(parent, &u8500_i2c3_data);
Rabin Vincentfbf1ead2010-09-29 19:46:32 +0530372}
Srinidhi Kasagaraa44ef42009-11-28 08:17:18 +0100373
Philippe Langlaisa71b8192011-01-14 10:53:59 +0100374static struct gpio_keys_button mop500_gpio_keys[] = {
375 {
376 .desc = "SFH7741 Proximity Sensor",
377 .type = EV_SW,
378 .code = SW_FRONT_PROXIMITY,
Philippe Langlaisa71b8192011-01-14 10:53:59 +0100379 .active_low = 0,
380 .can_disable = 1,
381 }
382};
383
384static struct regulator *prox_regulator;
385static int mop500_prox_activate(struct device *dev);
386static void mop500_prox_deactivate(struct device *dev);
387
388static struct gpio_keys_platform_data mop500_gpio_keys_data = {
389 .buttons = mop500_gpio_keys,
390 .nbuttons = ARRAY_SIZE(mop500_gpio_keys),
391 .enable = mop500_prox_activate,
392 .disable = mop500_prox_deactivate,
393};
394
395static struct platform_device mop500_gpio_keys_device = {
396 .name = "gpio-keys",
397 .id = 0,
398 .dev = {
399 .platform_data = &mop500_gpio_keys_data,
400 },
401};
402
403static int mop500_prox_activate(struct device *dev)
404{
405 prox_regulator = regulator_get(&mop500_gpio_keys_device.dev,
406 "vcc");
407 if (IS_ERR(prox_regulator)) {
408 dev_err(&mop500_gpio_keys_device.dev,
409 "no regulator\n");
410 return PTR_ERR(prox_regulator);
411 }
412 regulator_enable(prox_regulator);
413 return 0;
414}
415
416static void mop500_prox_deactivate(struct device *dev)
417{
418 regulator_disable(prox_regulator);
419 regulator_put(prox_regulator);
420}
421
Srinidhi Kasagard48a41c2010-02-03 13:02:48 +0100422/* add any platform devices here - TODO */
Robert Marklund350abe02011-06-20 15:55:46 +0200423static struct platform_device *mop500_platform_devs[] __initdata = {
Philippe Langlaisa71b8192011-01-14 10:53:59 +0100424 &mop500_gpio_keys_device,
Robert Marklund350abe02011-06-20 15:55:46 +0200425 &ab8500_device,
Srinidhi Kasagard48a41c2010-02-03 13:02:48 +0100426};
427
Linus Walleij5d7b8462010-10-14 13:57:59 +0200428#ifdef CONFIG_STE_DMA40
429static struct stedma40_chan_cfg ssp0_dma_cfg_rx = {
430 .mode = STEDMA40_MODE_LOGICAL,
431 .dir = STEDMA40_PERIPH_TO_MEM,
432 .src_dev_type = DB8500_DMA_DEV8_SSP0_RX,
433 .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
434 .src_info.data_width = STEDMA40_BYTE_WIDTH,
435 .dst_info.data_width = STEDMA40_BYTE_WIDTH,
436};
437
438static struct stedma40_chan_cfg ssp0_dma_cfg_tx = {
439 .mode = STEDMA40_MODE_LOGICAL,
440 .dir = STEDMA40_MEM_TO_PERIPH,
441 .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
442 .dst_dev_type = DB8500_DMA_DEV8_SSP0_TX,
443 .src_info.data_width = STEDMA40_BYTE_WIDTH,
444 .dst_info.data_width = STEDMA40_BYTE_WIDTH,
445};
446#endif
447
Lee Jones15daf692012-03-15 16:47:11 +0000448static struct pl022_ssp_controller ssp0_plat = {
Linus Walleij5d7b8462010-10-14 13:57:59 +0200449 .bus_id = 0,
450#ifdef CONFIG_STE_DMA40
451 .enable_dma = 1,
452 .dma_filter = stedma40_filter,
453 .dma_rx_param = &ssp0_dma_cfg_rx,
454 .dma_tx_param = &ssp0_dma_cfg_tx,
455#else
456 .enable_dma = 0,
457#endif
458 /* on this platform, gpio 31,142,144,214 &
459 * 224 are connected as chip selects
460 */
461 .num_chipselect = 5,
462};
463
Lee Jones18403422012-02-06 11:22:21 -0800464static void __init mop500_spi_init(struct device *parent)
Rabin Vincentfbf1ead2010-09-29 19:46:32 +0530465{
Lee Jones15daf692012-03-15 16:47:11 +0000466 db8500_add_ssp0(parent, &ssp0_plat);
Rabin Vincentfbf1ead2010-09-29 19:46:32 +0530467}
468
Linus Walleij5d7b8462010-10-14 13:57:59 +0200469#ifdef CONFIG_STE_DMA40
470static struct stedma40_chan_cfg uart0_dma_cfg_rx = {
471 .mode = STEDMA40_MODE_LOGICAL,
472 .dir = STEDMA40_PERIPH_TO_MEM,
473 .src_dev_type = DB8500_DMA_DEV13_UART0_RX,
474 .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
475 .src_info.data_width = STEDMA40_BYTE_WIDTH,
476 .dst_info.data_width = STEDMA40_BYTE_WIDTH,
477};
478
479static struct stedma40_chan_cfg uart0_dma_cfg_tx = {
480 .mode = STEDMA40_MODE_LOGICAL,
481 .dir = STEDMA40_MEM_TO_PERIPH,
482 .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
483 .dst_dev_type = DB8500_DMA_DEV13_UART0_TX,
484 .src_info.data_width = STEDMA40_BYTE_WIDTH,
485 .dst_info.data_width = STEDMA40_BYTE_WIDTH,
486};
487
488static struct stedma40_chan_cfg uart1_dma_cfg_rx = {
489 .mode = STEDMA40_MODE_LOGICAL,
490 .dir = STEDMA40_PERIPH_TO_MEM,
491 .src_dev_type = DB8500_DMA_DEV12_UART1_RX,
492 .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
493 .src_info.data_width = STEDMA40_BYTE_WIDTH,
494 .dst_info.data_width = STEDMA40_BYTE_WIDTH,
495};
496
497static struct stedma40_chan_cfg uart1_dma_cfg_tx = {
498 .mode = STEDMA40_MODE_LOGICAL,
499 .dir = STEDMA40_MEM_TO_PERIPH,
500 .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
501 .dst_dev_type = DB8500_DMA_DEV12_UART1_TX,
502 .src_info.data_width = STEDMA40_BYTE_WIDTH,
503 .dst_info.data_width = STEDMA40_BYTE_WIDTH,
504};
505
506static struct stedma40_chan_cfg uart2_dma_cfg_rx = {
507 .mode = STEDMA40_MODE_LOGICAL,
508 .dir = STEDMA40_PERIPH_TO_MEM,
509 .src_dev_type = DB8500_DMA_DEV11_UART2_RX,
510 .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
511 .src_info.data_width = STEDMA40_BYTE_WIDTH,
512 .dst_info.data_width = STEDMA40_BYTE_WIDTH,
513};
514
515static struct stedma40_chan_cfg uart2_dma_cfg_tx = {
516 .mode = STEDMA40_MODE_LOGICAL,
517 .dir = STEDMA40_MEM_TO_PERIPH,
518 .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
519 .dst_dev_type = DB8500_DMA_DEV11_UART2_TX,
520 .src_info.data_width = STEDMA40_BYTE_WIDTH,
521 .dst_info.data_width = STEDMA40_BYTE_WIDTH,
522};
523#endif
524
Shreshtha Kumar Sahu1a7d4362011-06-13 10:11:44 +0200525
526static pin_cfg_t mop500_pins_uart0[] = {
527 GPIO0_U0_CTSn | PIN_INPUT_PULLUP,
528 GPIO1_U0_RTSn | PIN_OUTPUT_HIGH,
529 GPIO2_U0_RXD | PIN_INPUT_PULLUP,
530 GPIO3_U0_TXD | PIN_OUTPUT_HIGH,
531};
532
533#define PRCC_K_SOFTRST_SET 0x18
534#define PRCC_K_SOFTRST_CLEAR 0x1C
535static void ux500_uart0_reset(void)
536{
537 void __iomem *prcc_rst_set, *prcc_rst_clr;
538
539 prcc_rst_set = (void __iomem *)IO_ADDRESS(U8500_CLKRST1_BASE +
540 PRCC_K_SOFTRST_SET);
541 prcc_rst_clr = (void __iomem *)IO_ADDRESS(U8500_CLKRST1_BASE +
542 PRCC_K_SOFTRST_CLEAR);
543
544 /* Activate soft reset PRCC_K_SOFTRST_CLEAR */
545 writel((readl(prcc_rst_clr) | 0x1), prcc_rst_clr);
546 udelay(1);
547
548 /* Release soft reset PRCC_K_SOFTRST_SET */
549 writel((readl(prcc_rst_set) | 0x1), prcc_rst_set);
550 udelay(1);
551}
552
553static void ux500_uart0_init(void)
554{
555 int ret;
556
557 ret = nmk_config_pins(mop500_pins_uart0,
558 ARRAY_SIZE(mop500_pins_uart0));
559 if (ret < 0)
560 pr_err("pl011: uart pins_enable failed\n");
561}
562
563static void ux500_uart0_exit(void)
564{
565 int ret;
566
567 ret = nmk_config_pins_sleep(mop500_pins_uart0,
568 ARRAY_SIZE(mop500_pins_uart0));
569 if (ret < 0)
570 pr_err("pl011: uart pins_disable failed\n");
571}
572
Linus Walleij5d7b8462010-10-14 13:57:59 +0200573static struct amba_pl011_data uart0_plat = {
574#ifdef CONFIG_STE_DMA40
575 .dma_filter = stedma40_filter,
576 .dma_rx_param = &uart0_dma_cfg_rx,
577 .dma_tx_param = &uart0_dma_cfg_tx,
578#endif
Shreshtha Kumar Sahu1a7d4362011-06-13 10:11:44 +0200579 .init = ux500_uart0_init,
580 .exit = ux500_uart0_exit,
581 .reset = ux500_uart0_reset,
Linus Walleij5d7b8462010-10-14 13:57:59 +0200582};
583
584static struct amba_pl011_data uart1_plat = {
585#ifdef CONFIG_STE_DMA40
586 .dma_filter = stedma40_filter,
587 .dma_rx_param = &uart1_dma_cfg_rx,
588 .dma_tx_param = &uart1_dma_cfg_tx,
589#endif
590};
591
592static struct amba_pl011_data uart2_plat = {
593#ifdef CONFIG_STE_DMA40
594 .dma_filter = stedma40_filter,
595 .dma_rx_param = &uart2_dma_cfg_rx,
596 .dma_tx_param = &uart2_dma_cfg_tx,
597#endif
598};
599
Lee Jones18403422012-02-06 11:22:21 -0800600static void __init mop500_uart_init(struct device *parent)
Rabin Vincentfbf1ead2010-09-29 19:46:32 +0530601{
Lee Jones18403422012-02-06 11:22:21 -0800602 db8500_add_uart0(parent, &uart0_plat);
603 db8500_add_uart1(parent, &uart1_plat);
604 db8500_add_uart2(parent, &uart2_plat);
Rabin Vincentfbf1ead2010-09-29 19:46:32 +0530605}
606
Robert Marklund350abe02011-06-20 15:55:46 +0200607static struct platform_device *snowball_platform_devs[] __initdata = {
608 &snowball_led_dev,
609 &snowball_key_dev,
610 &snowball_sbnet_dev,
611 &ab8500_device,
612};
613
Linus Walleij4b4f7572011-02-15 15:01:35 +0100614static void __init mop500_init_machine(void)
Srinidhi Kasagaraa44ef42009-11-28 08:17:18 +0100615{
Lee Jones18403422012-02-06 11:22:21 -0800616 struct device *parent = NULL;
Linus Walleijcf568c52011-03-30 14:31:42 +0200617 int i2c0_devs;
Lee Jonesb024a0c2012-02-06 11:22:25 -0800618 int i;
Linus Walleijcf568c52011-03-30 14:31:42 +0200619
Lee Jones110c2c22011-08-26 16:54:07 +0100620 mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR;
Linus Walleij4b4f7572011-02-15 15:01:35 +0100621
Linus Walleijed781d32012-05-03 00:44:52 +0200622 mop500_pinmaps_init();
Lee Jones18403422012-02-06 11:22:21 -0800623 parent = u8500_init_devices();
Rabin Vincentea05a572010-06-03 07:58:42 +0100624
Lee Jones7e0ce272012-03-15 16:46:17 +0000625 /* FIXME: parent of ab8500 should be prcmu */
Lee Jonesb024a0c2012-02-06 11:22:25 -0800626 for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++)
627 mop500_platform_devs[i]->dev.parent = parent;
628
Lee Jones110c2c22011-08-26 16:54:07 +0100629 platform_add_devices(mop500_platform_devs,
630 ARRAY_SIZE(mop500_platform_devs));
Srinidhi Kasagard48a41c2010-02-03 13:02:48 +0100631
Lee Jones18403422012-02-06 11:22:21 -0800632 mop500_i2c_init(parent);
633 mop500_sdi_init(parent);
634 mop500_spi_init(parent);
Ola Liljac0af14d2012-04-20 11:32:59 +0200635 mop500_msp_init(parent);
Lee Jones18403422012-02-06 11:22:21 -0800636 mop500_uart_init(parent);
Hanumath Prasad008f8a22010-08-19 12:06:32 +0100637
Linus Walleijcf568c52011-03-30 14:31:42 +0200638 i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
Lee Jones110c2c22011-08-26 16:54:07 +0100639
640 i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs);
641 i2c_register_board_info(2, mop500_i2c2_devices,
642 ARRAY_SIZE(mop500_i2c2_devices));
643
644 /* This board has full regulator constraints */
645 regulator_has_full_constraints();
646}
647
648static void __init snowball_init_machine(void)
649{
Lee Jones18403422012-02-06 11:22:21 -0800650 struct device *parent = NULL;
Lee Jones110c2c22011-08-26 16:54:07 +0100651 int i2c0_devs;
Lee Jonesb024a0c2012-02-06 11:22:25 -0800652 int i;
Lee Jones110c2c22011-08-26 16:54:07 +0100653
Linus Walleijed781d32012-05-03 00:44:52 +0200654 snowball_pinmaps_init();
Lee Jones18403422012-02-06 11:22:21 -0800655 parent = u8500_init_devices();
Lee Jones110c2c22011-08-26 16:54:07 +0100656
Lee Jonesb024a0c2012-02-06 11:22:25 -0800657 for (i = 0; i < ARRAY_SIZE(snowball_platform_devs); i++)
658 snowball_platform_devs[i]->dev.parent = parent;
659
Lee Jones110c2c22011-08-26 16:54:07 +0100660 platform_add_devices(snowball_platform_devs,
661 ARRAY_SIZE(snowball_platform_devs));
662
Lee Jones18403422012-02-06 11:22:21 -0800663 mop500_i2c_init(parent);
664 snowball_sdi_init(parent);
665 mop500_spi_init(parent);
Ola Liljac0af14d2012-04-20 11:32:59 +0200666 mop500_msp_init(parent);
Lee Jones18403422012-02-06 11:22:21 -0800667 mop500_uart_init(parent);
Lee Jones110c2c22011-08-26 16:54:07 +0100668
669 i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
670 i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs);
671 i2c_register_board_info(2, mop500_i2c2_devices,
672 ARRAY_SIZE(mop500_i2c2_devices));
673
674 /* This board has full regulator constraints */
675 regulator_has_full_constraints();
676}
677
678static void __init hrefv60_init_machine(void)
679{
Lee Jones18403422012-02-06 11:22:21 -0800680 struct device *parent = NULL;
Lee Jones110c2c22011-08-26 16:54:07 +0100681 int i2c0_devs;
Lee Jonesb024a0c2012-02-06 11:22:25 -0800682 int i;
Lee Jones110c2c22011-08-26 16:54:07 +0100683
684 /*
685 * The HREFv60 board removed a GPIO expander and routed
686 * all these GPIO pins to the internal GPIO controller
687 * instead.
688 */
689 mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO;
690
Linus Walleijed781d32012-05-03 00:44:52 +0200691 hrefv60_pinmaps_init();
Lee Jones18403422012-02-06 11:22:21 -0800692 parent = u8500_init_devices();
Lee Jones110c2c22011-08-26 16:54:07 +0100693
Lee Jonesb024a0c2012-02-06 11:22:25 -0800694 for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++)
695 mop500_platform_devs[i]->dev.parent = parent;
696
Lee Jones110c2c22011-08-26 16:54:07 +0100697 platform_add_devices(mop500_platform_devs,
698 ARRAY_SIZE(mop500_platform_devs));
699
Lee Jones18403422012-02-06 11:22:21 -0800700 mop500_i2c_init(parent);
701 hrefv60_sdi_init(parent);
702 mop500_spi_init(parent);
Ola Liljac0af14d2012-04-20 11:32:59 +0200703 mop500_msp_init(parent);
Lee Jones18403422012-02-06 11:22:21 -0800704 mop500_uart_init(parent);
Lee Jones110c2c22011-08-26 16:54:07 +0100705
706 i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
707
708 i2c0_devs -= NUM_PRE_V60_I2C0_DEVICES;
Linus Walleijcf568c52011-03-30 14:31:42 +0200709
710 i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs);
Philippe Langlaisdd7b2a02011-01-12 11:26:20 +0100711 i2c_register_board_info(2, mop500_i2c2_devices,
712 ARRAY_SIZE(mop500_i2c2_devices));
Linus Walleijdb245202011-04-04 10:44:51 +0200713
714 /* This board has full regulator constraints */
715 regulator_has_full_constraints();
Srinidhi Kasagaraa44ef42009-11-28 08:17:18 +0100716}
717
718MACHINE_START(U8500, "ST-Ericsson MOP500 platform")
719 /* Maintainer: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> */
Nicolas Pitrebc77b1a2011-07-05 22:38:18 -0400720 .atag_offset = 0x100,
Srinidhi Kasagaraa44ef42009-11-28 08:17:18 +0100721 .map_io = u8500_map_io,
Rabin Vincent178980f2010-05-03 07:39:02 +0100722 .init_irq = ux500_init_irq,
Srinidhi Kasagaraa44ef42009-11-28 08:17:18 +0100723 /* we re-use nomadik timer here */
Rabin Vincent41ac3292010-05-03 08:28:05 +0100724 .timer = &ux500_timer,
Marc Zyngierbbf5f382011-09-06 10:23:45 +0100725 .handle_irq = gic_handle_irq,
Linus Walleij4b4f7572011-02-15 15:01:35 +0100726 .init_machine = mop500_init_machine,
727MACHINE_END
728
729MACHINE_START(HREFV60, "ST-Ericsson U8500 Platform HREFv60+")
Nicolas Pitrebc77b1a2011-07-05 22:38:18 -0400730 .atag_offset = 0x100,
Linus Walleij4b4f7572011-02-15 15:01:35 +0100731 .map_io = u8500_map_io,
732 .init_irq = ux500_init_irq,
733 .timer = &ux500_timer,
Marc Zyngierbbf5f382011-09-06 10:23:45 +0100734 .handle_irq = gic_handle_irq,
Lee Jones110c2c22011-08-26 16:54:07 +0100735 .init_machine = hrefv60_init_machine,
Srinidhi Kasagaraa44ef42009-11-28 08:17:18 +0100736MACHINE_END
Robert Marklund350abe02011-06-20 15:55:46 +0200737
738MACHINE_START(SNOWBALL, "Calao Systems Snowball platform")
Nicolas Pitrebc77b1a2011-07-05 22:38:18 -0400739 .atag_offset = 0x100,
Robert Marklund350abe02011-06-20 15:55:46 +0200740 .map_io = u8500_map_io,
741 .init_irq = ux500_init_irq,
742 /* we re-use nomadik timer here */
743 .timer = &ux500_timer,
Marc Zyngierbbf5f382011-09-06 10:23:45 +0100744 .handle_irq = gic_handle_irq,
Lee Jones110c2c22011-08-26 16:54:07 +0100745 .init_machine = snowball_init_machine,
Robert Marklund350abe02011-06-20 15:55:46 +0200746MACHINE_END
Arnd Bergmann2d334292012-03-07 15:04:07 +0000747
748#ifdef CONFIG_MACH_UX500_DT
Lee Jones7e0ce272012-03-15 16:46:17 +0000749
750struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
Lee Jones513c27f2012-04-13 15:05:05 +0100751 /* Requires DMA and call-back bindings. */
Lee Jones4905af02012-03-07 17:35:04 +0000752 OF_DEV_AUXDATA("arm,pl011", 0x80120000, "uart0", &uart0_plat),
753 OF_DEV_AUXDATA("arm,pl011", 0x80121000, "uart1", &uart1_plat),
754 OF_DEV_AUXDATA("arm,pl011", 0x80007000, "uart2", &uart2_plat),
Lee Jones513c27f2012-04-13 15:05:05 +0100755 /* Requires DMA bindings. */
Lee Jones15daf692012-03-15 16:47:11 +0000756 OF_DEV_AUXDATA("arm,pl022", 0x80002000, "ssp0", &ssp0_plat),
Lee Jones513c27f2012-04-13 15:05:05 +0100757 /* Requires clock name bindings. */
758 OF_DEV_AUXDATA("st,nomadik-gpio", 0x8012e000, "gpio.0", NULL),
759 OF_DEV_AUXDATA("st,nomadik-gpio", 0x8012e080, "gpio.1", NULL),
760 OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e000, "gpio.2", NULL),
761 OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e080, "gpio.3", NULL),
762 OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e100, "gpio.4", NULL),
763 OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e180, "gpio.5", NULL),
764 OF_DEV_AUXDATA("st,nomadik-gpio", 0x8011e000, "gpio.6", NULL),
765 OF_DEV_AUXDATA("st,nomadik-gpio", 0x8011e080, "gpio.7", NULL),
766 OF_DEV_AUXDATA("st,nomadik-gpio", 0xa03fe000, "gpio.8", NULL),
Lee Jones7e0ce272012-03-15 16:46:17 +0000767 {},
768};
769
770static const struct of_device_id u8500_soc_node[] = {
771 /* only create devices below soc node */
772 { .compatible = "stericsson,db8500", },
773 { },
774};
775
Arnd Bergmann2d334292012-03-07 15:04:07 +0000776static void __init u8500_init_machine(void)
777{
Arnd Bergmann7734fed2012-03-02 22:25:02 +0000778 struct device *parent = NULL;
779 int i2c0_devs;
780 int i;
781
Linus Walleijed781d32012-05-03 00:44:52 +0200782 /* Pinmaps must be in place before devices register */
783 if (of_machine_is_compatible("st-ericsson,mop500"))
784 mop500_pinmaps_init();
785 else if (of_machine_is_compatible("calaosystems,snowball-a9500"))
786 snowball_pinmaps_init();
787 else if (of_machine_is_compatible("st-ericsson,hrefv60+"))
788 hrefv60_pinmaps_init();
789
Arnd Bergmann7734fed2012-03-02 22:25:02 +0000790 parent = u8500_init_devices();
791 i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
792
793 for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++)
794 mop500_platform_devs[i]->dev.parent = parent;
795 for (i = 0; i < ARRAY_SIZE(snowball_platform_devs); i++)
796 snowball_platform_devs[i]->dev.parent = parent;
797
Lee Jones7e0ce272012-03-15 16:46:17 +0000798 /* automatically probe child nodes of db8500 device */
799 of_platform_populate(NULL, u8500_soc_node, u8500_auxdata_lookup, parent);
Arnd Bergmann7734fed2012-03-02 22:25:02 +0000800
801 if (of_machine_is_compatible("st-ericsson,mop500")) {
802 mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR;
Arnd Bergmann7734fed2012-03-02 22:25:02 +0000803
804 platform_add_devices(mop500_platform_devs,
805 ARRAY_SIZE(mop500_platform_devs));
806
807 mop500_sdi_init(parent);
808 } else if (of_machine_is_compatible("calaosystems,snowball-a9500")) {
Arnd Bergmann7734fed2012-03-02 22:25:02 +0000809 platform_add_devices(snowball_platform_devs,
810 ARRAY_SIZE(snowball_platform_devs));
811
812 snowball_sdi_init(parent);
813 } else if (of_machine_is_compatible("st-ericsson,hrefv60+")) {
814 /*
815 * The HREFv60 board removed a GPIO expander and routed
816 * all these GPIO pins to the internal GPIO controller
817 * instead.
818 */
819 mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO;
820 i2c0_devs -= NUM_PRE_V60_I2C0_DEVICES;
Arnd Bergmann7734fed2012-03-02 22:25:02 +0000821 platform_add_devices(mop500_platform_devs,
822 ARRAY_SIZE(mop500_platform_devs));
823
824 hrefv60_sdi_init(parent);
825 }
826 mop500_i2c_init(parent);
Arnd Bergmann7734fed2012-03-02 22:25:02 +0000827
828 i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs);
829 i2c_register_board_info(2, mop500_i2c2_devices,
830 ARRAY_SIZE(mop500_i2c2_devices));
831
832 /* This board has full regulator constraints */
833 regulator_has_full_constraints();
Arnd Bergmann2d334292012-03-07 15:04:07 +0000834}
835
836static const char * u8500_dt_board_compat[] = {
837 "calaosystems,snowball-a9500",
838 "st-ericsson,hrefv60+",
839 "st-ericsson,u8500",
840 "st-ericsson,mop500",
841 NULL,
842};
843
844
845DT_MACHINE_START(U8500_DT, "ST-Ericsson U8500 platform (Device Tree Support)")
846 .map_io = u8500_map_io,
847 .init_irq = ux500_init_irq,
848 /* we re-use nomadik timer here */
849 .timer = &ux500_timer,
850 .handle_irq = gic_handle_irq,
851 .init_machine = u8500_init_machine,
852 .dt_compat = u8500_dt_board_compat,
853MACHINE_END
854#endif