aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap1/board-sx1.c
diff options
context:
space:
mode:
authorVladimir Ananiev <vovan888@gmail.com>2006-12-06 20:14:08 -0500
committerTony Lindgren <tony@atomide.com>2007-09-20 21:34:50 -0400
commitc79ed1940ca9a4af5e9c182ac51f28dadd32956d (patch)
treebe2d567fb8dbdb34d4b1f1988d22ed902868278e /arch/arm/mach-omap1/board-sx1.c
parentdc563b4f2de0dd57a8febe26158cdf59bc15534f (diff)
ARM: OMAP: Basic support for siemens sx1
This adds basic support for Siemens SX1. More patches are available, with video driver, mixer, and serial ports working. That is enough to do gsm calls with right userland. Signed-off-by: Pavel Machek <pavel@suse.cz> Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/mach-omap1/board-sx1.c')
-rw-r--r--arch/arm/mach-omap1/board-sx1.c494
1 files changed, 494 insertions, 0 deletions
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
new file mode 100644
index 000000000000..2743d639aa05
--- /dev/null
+++ b/arch/arm/mach-omap1/board-sx1.c
@@ -0,0 +1,494 @@
1/*
2* linux/arch/arm/mach-omap1/board-sx1.c
3*
4* Modified from board-generic.c
5*
6* Support for the Siemens SX1 mobile phone.
7*
8* Original version : Vladimir Ananiev (Vovan888-at-gmail com)
9*
10* Maintainters : Vladimir Ananiev (aka Vovan888), Sergge
11* oslik.ru
12*
13* This program is free software; you can redistribute it and/or modify
14* it under the terms of the GNU General Public License version 2 as
15* published by the Free Software Foundation.
16*/
17
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/input.h>
21#include <linux/platform_device.h>
22#include <linux/notifier.h>
23#include <linux/mtd/mtd.h>
24#include <linux/mtd/partitions.h>
25#include <linux/types.h>
26#include <linux/i2c.h>
27#include <linux/errno.h>
28
29#include <asm/hardware.h>
30#include <asm/mach-types.h>
31#include <asm/mach/arch.h>
32#include <asm/mach/flash.h>
33#include <asm/mach/map.h>
34
35#include <asm/arch/gpio.h>
36#include <asm/arch/mux.h>
37#include <asm/arch/irda.h>
38#include <asm/arch/usb.h>
39#include <asm/arch/tc.h>
40#include <asm/arch/board.h>
41#include <asm/arch/common.h>
42#include <asm/arch/mcbsp.h>
43#include <asm/arch/omap-alsa.h>
44#include <asm/arch/keypad.h>
45
46/* Write to I2C device */
47int i2c_write_byte(u8 devaddr, u8 regoffset, u8 value)
48{
49 struct i2c_adapter *adap;
50 int err;
51 struct i2c_msg msg[1];
52 unsigned char data[2];
53
54 adap = i2c_get_adapter(0);
55 if (!adap)
56 return -ENODEV;
57 msg->addr = devaddr; /* I2C address of chip */
58 msg->flags = 0;
59 msg->len = 2;
60 msg->buf = data;
61 data[0] = regoffset; /* register num */
62 data[1] = value; /* register data */
63 err = i2c_transfer(adap, msg, 1);
64 if (err >= 0)
65 return 0;
66 return err;
67}
68
69/* Read from I2C device */
70int i2c_read_byte(u8 devaddr, u8 regoffset, u8 * value)
71{
72 struct i2c_adapter *adap;
73 int err;
74 struct i2c_msg msg[1];
75 unsigned char data[2];
76
77 adap = i2c_get_adapter(0);
78 if (!adap)
79 return -ENODEV;
80
81 msg->addr = devaddr; /* I2C address of chip */
82 msg->flags = 0;
83 msg->len = 1;
84 msg->buf = data;
85 data[0] = regoffset; /* register num */
86 err = i2c_transfer(adap, msg, 1);
87
88 msg->addr = devaddr; /* I2C address */
89 msg->flags = I2C_M_RD;
90 msg->len = 1;
91 msg->buf = data;
92 err = i2c_transfer(adap, msg, 1);
93 *value = data[0];
94
95 if (err >= 0)
96 return 0;
97 return err;
98}
99/* set keyboard backlight intensity */
100int sx1_setkeylight(u8 keylight)
101{
102 if (keylight > SOFIA_MAX_LIGHT_VAL)
103 keylight = SOFIA_MAX_LIGHT_VAL;
104 return i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_KEYLIGHT_REG, keylight);
105}
106/* get current keylight intensity */
107int sx1_getkeylight(u8 * keylight)
108{
109 return i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_KEYLIGHT_REG, keylight);
110}
111/* set LCD backlight intensity */
112int sx1_setbacklight(u8 backlight)
113{
114 if (backlight > SOFIA_MAX_LIGHT_VAL)
115 backlight = SOFIA_MAX_LIGHT_VAL;
116 return i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_BACKLIGHT_REG, backlight);
117}
118/* get current LCD backlight intensity */
119int sx1_getbacklight (u8 * backlight)
120{
121 return i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_BACKLIGHT_REG, backlight);
122}
123/* set LCD backlight power on/off */
124int sx1_setmmipower(u8 onoff)
125{
126 int err;
127 u8 dat = 0;
128 err = i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat);
129 if (err < 0)
130 return err;
131 if (onoff)
132 dat |= SOFIA_MMILIGHT_POWER;
133 else
134 dat &= ~SOFIA_MMILIGHT_POWER;
135 return i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat);
136}
137/* set MMC power on/off */
138int sx1_setmmcpower(u8 onoff)
139{
140 int err;
141 u8 dat = 0;
142 err = i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat);
143 if (err < 0)
144 return err;
145 if (onoff)
146 dat |= SOFIA_MMC_POWER;
147 else
148 dat &= ~SOFIA_MMC_POWER;
149 return i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat);
150}
151/* set USB power on/off */
152int sx1_setusbpower(u8 onoff)
153{
154 int err;
155 u8 dat = 0;
156 err = i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat);
157 if (err < 0)
158 return err;
159 if (onoff)
160 dat |= SOFIA_USB_POWER;
161 else
162 dat &= ~SOFIA_USB_POWER;
163 return i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat);
164}
165
166EXPORT_SYMBOL(sx1_setkeylight);
167EXPORT_SYMBOL(sx1_getkeylight);
168EXPORT_SYMBOL(sx1_setbacklight);
169EXPORT_SYMBOL(sx1_getbacklight);
170EXPORT_SYMBOL(sx1_setmmipower);
171EXPORT_SYMBOL(sx1_setmmcpower);
172EXPORT_SYMBOL(sx1_setusbpower);
173
174/*----------- Keypad -------------------------*/
175
176static int sx1_keymap[] = {
177 KEY(5, 3, GROUP_0 | 117), /* camera Qt::Key_F17 */
178 KEY(0, 4, GROUP_0 | 114), /* voice memo Qt::Key_F14 */
179 KEY(1, 4, GROUP_2 | 114), /* voice memo */
180 KEY(2, 4, GROUP_3 | 114), /* voice memo */
181 KEY(0, 0, GROUP_1 | KEY_F12), /* red button Qt::Key_Hangup */
182 KEY(4, 3, GROUP_1 | KEY_LEFT),
183 KEY(2, 3, GROUP_1 | KEY_DOWN),
184 KEY(1, 3, GROUP_1 | KEY_RIGHT),
185 KEY(0, 3, GROUP_1 | KEY_UP),
186 KEY(3, 3, GROUP_1 | KEY_POWER), /* joystick press or Qt::Key_Select */
187 KEY(5, 0, GROUP_1 | KEY_1),
188 KEY(4, 0, GROUP_1 | KEY_2),
189 KEY(3, 0, GROUP_1 | KEY_3),
190 KEY(3, 4, GROUP_1 | KEY_4),
191 KEY(4, 4, GROUP_1 | KEY_5),
192 KEY(5, 4, GROUP_1 | KEY_KPASTERISK),/* "*" */
193 KEY(4, 1, GROUP_1 | KEY_6),
194 KEY(5, 1, GROUP_1 | KEY_7),
195 KEY(3, 1, GROUP_1 | KEY_8),
196 KEY(3, 2, GROUP_1 | KEY_9),
197 KEY(5, 2, GROUP_1 | KEY_0),
198 KEY(4, 2, GROUP_1 | 113), /* # F13 Toggle input method Qt::Key_F13 */
199 KEY(0, 1, GROUP_1 | KEY_F11), /* green button Qt::Key_Call */
200 KEY(1, 2, GROUP_1 | KEY_YEN), /* left soft Qt::Key_Context1 */
201 KEY(2, 2, GROUP_1 | KEY_F8), /* right soft Qt::Key_Back */
202 KEY(2, 1, GROUP_1 | KEY_LEFTSHIFT), /* shift */
203 KEY(1, 1, GROUP_1 | KEY_BACKSPACE), /* C (clear) */
204 KEY(0, 2, GROUP_1 | KEY_F7), /* menu Qt::Key_Menu */
205 0
206};
207
208static struct resource sx1_kp_resources[] = {
209 [0] = {
210 .start = INT_KEYBOARD,
211 .end = INT_KEYBOARD,
212 .flags = IORESOURCE_IRQ,
213 },
214};
215
216static struct omap_kp_platform_data sx1_kp_data = {
217 .rows = 6,
218 .cols = 6,
219 .keymap = sx1_keymap,
220 .keymapsize = ARRAY_SIZE(sx1_keymap),
221 .delay = 80,
222};
223
224static struct platform_device sx1_kp_device = {
225 .name = "omap-keypad",
226 .id = -1,
227 .dev = {
228 .platform_data = &sx1_kp_data,
229 },
230 .num_resources = ARRAY_SIZE(sx1_kp_resources),
231 .resource = sx1_kp_resources,
232};
233
234/*----------- IRDA -------------------------*/
235
236static struct omap_irda_config sx1_irda_data = {
237 .transceiver_cap = IR_SIRMODE,
238 .rx_channel = OMAP_DMA_UART3_RX,
239 .tx_channel = OMAP_DMA_UART3_TX,
240 .dest_start = UART3_THR,
241 .src_start = UART3_RHR,
242 .tx_trigger = 0,
243 .rx_trigger = 0,
244};
245
246static struct resource sx1_irda_resources[] = {
247 [0] = {
248 .start = INT_UART3,
249 .end = INT_UART3,
250 .flags = IORESOURCE_IRQ,
251 },
252};
253
254static u64 irda_dmamask = 0xffffffff;
255
256static struct platform_device sx1_irda_device = {
257 .name = "omapirda",
258 .id = 0,
259 .dev = {
260 .platform_data = &sx1_irda_data,
261 .dma_mask = &irda_dmamask,
262 },
263 .num_resources = ARRAY_SIZE(sx1_irda_resources),
264 .resource = sx1_irda_resources,
265};
266
267/*----------- McBSP & Sound -------------------------*/
268
269/* Playback interface - McBSP1 */
270static struct omap_mcbsp_reg_cfg mcbsp1_regs = {
271 .spcr2 = XINTM(3), /* SPCR2=30 */
272 .spcr1 = RINTM(3), /* SPCR1=30 */
273 .rcr2 = 0, /* RCR2 =00 */
274 .rcr1 = RFRLEN1(1) | RWDLEN1(OMAP_MCBSP_WORD_16), /* RCR1=140 */
275 .xcr2 = 0, /* XCR2 = 0 */
276 .xcr1 = XFRLEN1(1) | XWDLEN1(OMAP_MCBSP_WORD_16), /* XCR1 = 140 */
277 .srgr1 = FWID(15) | CLKGDV(12), /* SRGR1=0f0c */
278 .srgr2 = FSGM | FPER(31), /* SRGR2=101f */
279 .pcr0 = FSXM | FSRM | CLKXM | CLKRM | FSXP | FSRP | CLKXP | CLKRP,
280 /* PCR0 =0f0f */
281};
282
283/* TODO: PCM interface - McBSP2 */
284static struct omap_mcbsp_reg_cfg mcbsp2_regs = {
285 .spcr2 = FRST | GRST | XRST | XINTM(3), /* SPCR2=F1 */
286 .spcr1 = RINTM(3) | RRST, /* SPCR1=30 */
287 .rcr2 = 0, /* RCR2 =00 */
288 .rcr1 = RFRLEN1(1) | RWDLEN1(OMAP_MCBSP_WORD_16), /* RCR1 = 140 */
289 .xcr2 = 0, /* XCR2 = 0 */
290 .xcr1 = XFRLEN1(1) | XWDLEN1(OMAP_MCBSP_WORD_16), /* XCR1 = 140 */
291 .srgr1 = FWID(15) | CLKGDV(12), /* SRGR1=0f0c */
292 .srgr2 = FSGM | FPER(31), /* SRGR2=101f */
293 .pcr0 = FSXM | FSRM | CLKXM | CLKRM | FSXP | FSRP | CLKXP | CLKRP,
294 /* PCR0=0f0f */
295 /* mcbsp: slave */
296};
297
298static struct omap_alsa_codec_config sx1_alsa_config = {
299 .name = "SX1 EGold",
300 .mcbsp_regs_alsa = &mcbsp1_regs,
301};
302
303static struct platform_device sx1_mcbsp1_device = {
304 .name = "omap_alsa_mcbsp",
305 .id = 1,
306 .dev = {
307 .platform_data = &sx1_alsa_config,
308 },
309};
310
311/*----------- MTD -------------------------*/
312
313static struct mtd_partition sx1_partitions[] = {
314 /* bootloader (U-Boot, etc) in first sector */
315 {
316 .name = "bootloader",
317 .offset = 0x01800000,
318 .size = SZ_128K,
319 .mask_flags = MTD_WRITEABLE, /* force read-only */
320 },
321 /* bootloader params in the next sector */
322 {
323 .name = "params",
324 .offset = MTDPART_OFS_APPEND,
325 .size = SZ_128K,
326 .mask_flags = 0,
327 },
328 /* kernel */
329 {
330 .name = "kernel",
331 .offset = MTDPART_OFS_APPEND,
332 .size = SZ_2M - 2 * SZ_128K,
333 .mask_flags = 0
334 },
335 /* file system */
336 {
337 .name = "filesystem",
338 .offset = MTDPART_OFS_APPEND,
339 .size = MTDPART_SIZ_FULL,
340 .mask_flags = 0
341 }
342};
343
344static struct flash_platform_data sx1_flash_data = {
345 .map_name = "cfi_probe",
346 .width = 2,
347 .parts = sx1_partitions,
348 .nr_parts = ARRAY_SIZE(sx1_partitions),
349};
350
351#ifdef CONFIG_SX1_OLD_FLASH
352/* MTD Intel StrataFlash - old flashes */
353static struct resource sx1_old_flash_resource[] = {
354 [0] = {
355 .start = OMAP_CS0_PHYS, /* Physical */
356 .end = OMAP_CS0_PHYS + SZ_16M - 1,,
357 .flags = IORESOURCE_MEM,
358 },
359 [1] = {
360 .start = OMAP_CS1_PHYS,
361 .end = OMAP_CS1_PHYS + SZ_8M - 1,
362 .flags = IORESOURCE_MEM,
363 },
364};
365
366static struct platform_device sx1_flash_device = {
367 .name = "omapflash",
368 .id = 0,
369 .dev = {
370 .platform_data = &sx1_flash_data,
371 },
372 .num_resources = 2,
373 .resource = &sx1_old_flash_resource,
374};
375#else
376/* MTD Intel 4000 flash - new flashes */
377static struct resource sx1_new_flash_resource = {
378 .start = OMAP_CS0_PHYS,
379 .end = OMAP_CS0_PHYS + SZ_32M - 1,
380 .flags = IORESOURCE_MEM,
381};
382
383static struct platform_device sx1_flash_device = {
384 .name = "omapflash",
385 .id = 0,
386 .dev = {
387 .platform_data = &sx1_flash_data,
388 },
389 .num_resources = 1,
390 .resource = &sx1_new_flash_resource,
391};
392#endif
393
394/*----------- USB -------------------------*/
395
396static struct omap_usb_config sx1_usb_config __initdata = {
397 .otg = 0,
398 .register_dev = 1,
399 .register_host = 0,
400 .hmc_mode = 0,
401 .pins[0] = 2,
402 .pins[1] = 0,
403 .pins[2] = 0,
404};
405
406/*----------- MMC -------------------------*/
407
408static struct omap_mmc_config sx1_mmc_config __initdata = {
409 .mmc [0] = {
410 .enabled = 1,
411 .wire4 = 0,
412 .wp_pin = -1,
413 .power_pin = -1, /* power is in Sofia */
414 .switch_pin = OMAP_MPUIO(3),
415 },
416};
417
418/*----------- LCD -------------------------*/
419
420static struct platform_device sx1_lcd_device = {
421 .name = "lcd_sx1",
422 .id = -1,
423};
424
425static struct omap_lcd_config sx1_lcd_config __initdata = {
426 .ctrl_name = "internal",
427};
428
429/*-----------------------------------------*/
430static struct platform_device *sx1_devices[] __initdata = {
431 &sx1_flash_device,
432 &sx1_kp_device,
433 &sx1_lcd_device,
434 &sx1_mcbsp1_device,
435 &sx1_irda_device,
436};
437/*-----------------------------------------*/
438
439static struct omap_uart_config sx1_uart_config __initdata = {
440 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
441};
442
443static struct omap_board_config_kernel sx1_config[] = {
444 { OMAP_TAG_USB, &sx1_usb_config },
445 { OMAP_TAG_MMC, &sx1_mmc_config },
446 { OMAP_TAG_LCD, &sx1_lcd_config },
447 { OMAP_TAG_UART, &sx1_uart_config },
448};
449/*-----------------------------------------*/
450static void __init omap_sx1_init(void)
451{
452 platform_add_devices(sx1_devices, ARRAY_SIZE(sx1_devices));
453
454 omap_board_config = sx1_config;
455 omap_board_config_size = ARRAY_SIZE(sx1_config);
456 omap_serial_init();
457
458 /* turn on USB power */
459 /* sx1_setusbpower(1); cant do it here because i2c is not ready */
460 omap_request_gpio(1); /* A_IRDA_OFF */
461 omap_request_gpio(11); /* A_SWITCH */
462 omap_request_gpio(15); /* A_USB_ON */
463 omap_set_gpio_direction(1, 0);/* gpio1 -> output */
464 omap_set_gpio_direction(11, 0);/* gpio11 -> output */
465 omap_set_gpio_direction(15, 0);/* gpio15 -> output */
466 /* set GPIO data */
467 omap_set_gpio_dataout(1, 1);/*A_IRDA_OFF = 1 */
468 omap_set_gpio_dataout(11, 0);/*A_SWITCH = 0 */
469 omap_set_gpio_dataout(15, 0);/*A_USB_ON = 0 */
470
471}
472/*----------------------------------------*/
473static void __init omap_sx1_init_irq(void)
474{
475 omap1_init_common_hw();
476 omap_init_irq();
477 omap_gpio_init();
478}
479/*----------------------------------------*/
480
481static void __init omap_sx1_map_io(void)
482{
483 omap1_map_common_io();
484}
485
486MACHINE_START(SX1, "OMAP310 based Siemens SX1")
487 .phys_io = 0xfff00000,
488 .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
489 .boot_params = 0x10000100,
490 .map_io = omap_sx1_map_io,
491 .init_irq = omap_sx1_init_irq,
492 .init_machine = omap_sx1_init,
493 .timer = &omap_timer,
494MACHINE_END