| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 | /** linux/arch/arm/mach-omap1/board-sx1.c** Modified from board-generic.c** Support for the Siemens SX1 mobile phone.** Original version : Vladimir Ananiev (Vovan888-at-gmail com)** Maintainters : Vladimir Ananiev (aka Vovan888), Sergge*		oslik.ru** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License version 2 as* published by the Free Software Foundation.*/#include <linux/gpio.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/input.h>#include <linux/platform_device.h>#include <linux/notifier.h>#include <linux/mtd/mtd.h>#include <linux/mtd/partitions.h>#include <linux/mtd/physmap.h>#include <linux/types.h>#include <linux/i2c.h>#include <linux/errno.h>#include <linux/export.h>#include <linux/omapfb.h>#include <linux/platform_data/keypad-omap.h>#include <asm/mach-types.h>#include <asm/mach/arch.h>#include <asm/mach/map.h>#include <mach/flash.h>#include <mach/mux.h>#include <linux/omap-dma.h>#include <mach/irda.h>#include <mach/tc.h>#include <mach/board-sx1.h>#include <mach/hardware.h>#include <mach/usb.h>#include "common.h"#include "dma.h"/* Write to I2C device */int sx1_i2c_write_byte(u8 devaddr, u8 regoffset, u8 value){	struct i2c_adapter *adap;	int err;	struct i2c_msg msg[1];	unsigned char data[2];	adap = i2c_get_adapter(0);	if (!adap)		return -ENODEV;	msg->addr = devaddr;	/* I2C address of chip */	msg->flags = 0;	msg->len = 2;	msg->buf = data;	data[0] = regoffset;	/* register num */	data[1] = value;		/* register data */	err = i2c_transfer(adap, msg, 1);	i2c_put_adapter(adap);	if (err >= 0)		return 0;	return err;}/* Read from I2C device */int sx1_i2c_read_byte(u8 devaddr, u8 regoffset, u8 *value){	struct i2c_adapter *adap;	int err;	struct i2c_msg msg[1];	unsigned char data[2];	adap = i2c_get_adapter(0);	if (!adap)		return -ENODEV;	msg->addr = devaddr;	/* I2C address of chip */	msg->flags = 0;	msg->len = 1;	msg->buf = data;	data[0] = regoffset;	/* register num */	err = i2c_transfer(adap, msg, 1);	msg->addr = devaddr;	/* I2C address */	msg->flags = I2C_M_RD;	msg->len = 1;	msg->buf = data;	err = i2c_transfer(adap, msg, 1);	*value = data[0];	i2c_put_adapter(adap);	if (err >= 0)		return 0;	return err;}/* set keyboard backlight intensity */int sx1_setkeylight(u8 keylight){	if (keylight > SOFIA_MAX_LIGHT_VAL)		keylight = SOFIA_MAX_LIGHT_VAL;	return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_KEYLIGHT_REG, keylight);}/* get current keylight intensity */int sx1_getkeylight(u8 * keylight){	return sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_KEYLIGHT_REG, keylight);}/* set LCD backlight intensity */int sx1_setbacklight(u8 backlight){	if (backlight > SOFIA_MAX_LIGHT_VAL)		backlight = SOFIA_MAX_LIGHT_VAL;	return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_BACKLIGHT_REG,				  backlight);}/* get current LCD backlight intensity */int sx1_getbacklight (u8 * backlight){	return sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_BACKLIGHT_REG,				 backlight);}/* set LCD backlight power on/off */int sx1_setmmipower(u8 onoff){	int err;	u8 dat = 0;	err = sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat);	if (err < 0)		return err;	if (onoff)		dat |= SOFIA_MMILIGHT_POWER;	else		dat &= ~SOFIA_MMILIGHT_POWER;	return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat);}/* set USB power on/off */int sx1_setusbpower(u8 onoff){	int err;	u8 dat = 0;	err = sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat);	if (err < 0)		return err;	if (onoff)		dat |= SOFIA_USB_POWER;	else		dat &= ~SOFIA_USB_POWER;	return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat);}EXPORT_SYMBOL(sx1_setkeylight);EXPORT_SYMBOL(sx1_getkeylight);EXPORT_SYMBOL(sx1_setbacklight);EXPORT_SYMBOL(sx1_getbacklight);EXPORT_SYMBOL(sx1_setmmipower);EXPORT_SYMBOL(sx1_setusbpower);/*----------- Keypad -------------------------*/static const unsigned int sx1_keymap[] = {	KEY(3, 5, GROUP_0 | 117), /* camera Qt::Key_F17 */	KEY(4, 0, GROUP_0 | 114), /* voice memo Qt::Key_F14 */	KEY(4, 1, GROUP_2 | 114), /* voice memo */	KEY(4, 2, GROUP_3 | 114), /* voice memo */	KEY(0, 0, GROUP_1 | KEY_F12),	/* red button Qt::Key_Hangup */	KEY(3, 4, GROUP_1 | KEY_LEFT),	KEY(3, 2, GROUP_1 | KEY_DOWN),	KEY(3, 1, GROUP_1 | KEY_RIGHT),	KEY(3, 0, GROUP_1 | KEY_UP),	KEY(3, 3, GROUP_1 | KEY_POWER), /* joystick press or Qt::Key_Select */	KEY(0, 5, GROUP_1 | KEY_1),	KEY(0, 4, GROUP_1 | KEY_2),	KEY(0, 3, GROUP_1 | KEY_3),	KEY(4, 3, GROUP_1 | KEY_4),	KEY(4, 4, GROUP_1 | KEY_5),	KEY(4, 5, GROUP_1 | KEY_KPASTERISK),/* "*" */	KEY(1, 4, GROUP_1 | KEY_6),	KEY(1, 5, GROUP_1 | KEY_7),	KEY(1, 3, GROUP_1 | KEY_8),	KEY(2, 3, GROUP_1 | KEY_9),	KEY(2, 5, GROUP_1 | KEY_0),	KEY(2, 4, GROUP_1 | 113), /* # F13 Toggle input method Qt::Key_F13 */	KEY(1, 0, GROUP_1 | KEY_F11),	/* green button Qt::Key_Call */	KEY(2, 1, GROUP_1 | KEY_YEN),	/* left soft Qt::Key_Context1 */	KEY(2, 2, GROUP_1 | KEY_F8),	/* right soft Qt::Key_Back */	KEY(1, 2, GROUP_1 | KEY_LEFTSHIFT), /* shift */	KEY(1, 1, GROUP_1 | KEY_BACKSPACE), /* C (clear) */	KEY(2, 0, GROUP_1 | KEY_F7),	/* menu Qt::Key_Menu */};static struct resource sx1_kp_resources[] = {	[0] = {		.start	= INT_KEYBOARD,		.end	= INT_KEYBOARD,		.flags	= IORESOURCE_IRQ,	},};static const struct matrix_keymap_data sx1_keymap_data = {	.keymap		= sx1_keymap,	.keymap_size	= ARRAY_SIZE(sx1_keymap),};static struct omap_kp_platform_data sx1_kp_data = {	.rows		= 6,	.cols		= 6,	.keymap_data	= &sx1_keymap_data,	.delay	= 80,};static struct platform_device sx1_kp_device = {	.name		= "omap-keypad",	.id		= -1,	.dev		= {		.platform_data = &sx1_kp_data,	},	.num_resources	= ARRAY_SIZE(sx1_kp_resources),	.resource	= sx1_kp_resources,};/*----------- IRDA -------------------------*/static struct omap_irda_config sx1_irda_data = {	.transceiver_cap	= IR_SIRMODE,	.rx_channel		= OMAP_DMA_UART3_RX,	.tx_channel		= OMAP_DMA_UART3_TX,	.dest_start		= UART3_THR,	.src_start		= UART3_RHR,	.tx_trigger		= 0,	.rx_trigger		= 0,};static struct resource sx1_irda_resources[] = {	[0] = {		.start	= INT_UART3,		.end	= INT_UART3,		.flags	= IORESOURCE_IRQ,	},};static u64 irda_dmamask = 0xffffffff;static struct platform_device sx1_irda_device = {	.name		= "omapirda",	.id		= 0,	.dev		= {		.platform_data	= &sx1_irda_data,		.dma_mask	= &irda_dmamask,	},	.num_resources	= ARRAY_SIZE(sx1_irda_resources),	.resource	= sx1_irda_resources,};/*----------- MTD -------------------------*/static struct mtd_partition sx1_partitions[] = {	/* bootloader (U-Boot, etc) in first sector */	{		.name		= "bootloader",		.offset		= 0x01800000,		.size		= SZ_128K,
 |