cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mach-rx1950.c (21052B)


      1// SPDX-License-Identifier: GPL-2.0
      2//
      3// Copyright (c) 2006-2009 Victor Chukhantsev, Denis Grigoriev,
      4// Copyright (c) 2007-2010 Vasily Khoruzhick
      5//
      6// based on smdk2440 written by Ben Dooks
      7
      8#include <linux/kernel.h>
      9#include <linux/types.h>
     10#include <linux/interrupt.h>
     11#include <linux/list.h>
     12#include <linux/memblock.h>
     13#include <linux/delay.h>
     14#include <linux/timer.h>
     15#include <linux/init.h>
     16#include <linux/gpio.h>
     17#include <linux/gpio/machine.h>
     18#include <linux/platform_device.h>
     19#include <linux/serial_core.h>
     20#include <linux/serial_s3c.h>
     21#include <linux/input.h>
     22#include <linux/gpio_keys.h>
     23#include <linux/device.h>
     24#include <linux/pda_power.h>
     25#include <linux/pwm_backlight.h>
     26#include <linux/pwm.h>
     27#include <linux/s3c_adc_battery.h>
     28#include <linux/leds.h>
     29#include <linux/i2c.h>
     30
     31#include <linux/mtd/mtd.h>
     32#include <linux/mtd/partitions.h>
     33
     34#include <linux/mmc/host.h>
     35
     36#include <asm/mach-types.h>
     37#include <asm/mach/arch.h>
     38#include <asm/mach/map.h>
     39
     40#include <linux/platform_data/i2c-s3c2410.h>
     41#include <linux/platform_data/mmc-s3cmci.h>
     42#include <linux/platform_data/mtd-nand-s3c2410.h>
     43#include <linux/platform_data/touchscreen-s3c2410.h>
     44#include <linux/platform_data/usb-s3c2410_udc.h>
     45#include <linux/platform_data/fb-s3c2410.h>
     46
     47#include <sound/uda1380.h>
     48
     49#include "hardware-s3c24xx.h"
     50#include "regs-gpio.h"
     51#include "gpio-samsung.h"
     52
     53#include "cpu.h"
     54#include "devs.h"
     55#include "pm.h"
     56#include "gpio-cfg.h"
     57
     58#include "s3c24xx.h"
     59#include "h1940.h"
     60
     61#define LCD_PWM_PERIOD 192960
     62#define LCD_PWM_DUTY 127353
     63
     64static struct map_desc rx1950_iodesc[] __initdata = {
     65};
     66
     67static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
     68	[0] = {
     69	       .hwport = 0,
     70	       .flags = 0,
     71	       .ucon = 0x3c5,
     72	       .ulcon = 0x03,
     73	       .ufcon = 0x51,
     74		.clk_sel = S3C2410_UCON_CLKSEL3,
     75	},
     76	[1] = {
     77	       .hwport = 1,
     78	       .flags = 0,
     79	       .ucon = 0x3c5,
     80	       .ulcon = 0x03,
     81	       .ufcon = 0x51,
     82		.clk_sel = S3C2410_UCON_CLKSEL3,
     83	},
     84	/* IR port */
     85	[2] = {
     86	       .hwport = 2,
     87	       .flags = 0,
     88	       .ucon = 0x3c5,
     89	       .ulcon = 0x43,
     90	       .ufcon = 0xf1,
     91		.clk_sel = S3C2410_UCON_CLKSEL3,
     92	},
     93};
     94
     95static struct s3c2410fb_display rx1950_display = {
     96	.type = S3C2410_LCDCON1_TFT,
     97	.width = 240,
     98	.height = 320,
     99	.xres = 240,
    100	.yres = 320,
    101	.bpp = 16,
    102
    103	.pixclock = 260000,
    104	.left_margin = 10,
    105	.right_margin = 20,
    106	.hsync_len = 10,
    107	.upper_margin = 2,
    108	.lower_margin = 2,
    109	.vsync_len = 2,
    110
    111	.lcdcon5 = S3C2410_LCDCON5_FRM565 |
    112			   S3C2410_LCDCON5_INVVCLK |
    113			   S3C2410_LCDCON5_INVVLINE |
    114			   S3C2410_LCDCON5_INVVFRAME |
    115			   S3C2410_LCDCON5_HWSWP |
    116			   (0x02 << 13) |
    117			   (0x02 << 15),
    118
    119};
    120
    121static int power_supply_init(struct device *dev)
    122{
    123	return gpio_request(S3C2410_GPF(2), "cable plugged");
    124}
    125
    126static int rx1950_is_ac_online(void)
    127{
    128	return !gpio_get_value(S3C2410_GPF(2));
    129}
    130
    131static void power_supply_exit(struct device *dev)
    132{
    133	gpio_free(S3C2410_GPF(2));
    134}
    135
    136static char *rx1950_supplicants[] = {
    137	"main-battery"
    138};
    139
    140static struct pda_power_pdata power_supply_info = {
    141	.init			= power_supply_init,
    142	.is_ac_online		= rx1950_is_ac_online,
    143	.exit			= power_supply_exit,
    144	.supplied_to		= rx1950_supplicants,
    145	.num_supplicants	= ARRAY_SIZE(rx1950_supplicants),
    146};
    147
    148static struct resource power_supply_resources[] = {
    149	[0] = DEFINE_RES_NAMED(IRQ_EINT2, 1, "ac", IORESOURCE_IRQ \
    150			| IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE),
    151};
    152
    153static struct platform_device power_supply = {
    154	.name			= "pda-power",
    155	.id			= -1,
    156	.dev			= {
    157					.platform_data =
    158						&power_supply_info,
    159	},
    160	.resource		= power_supply_resources,
    161	.num_resources		= ARRAY_SIZE(power_supply_resources),
    162};
    163
    164static const struct s3c_adc_bat_thresh bat_lut_noac[] = {
    165	{ .volt = 4100, .cur = 156, .level = 100},
    166	{ .volt = 4050, .cur = 156, .level = 95},
    167	{ .volt = 4025, .cur = 141, .level = 90},
    168	{ .volt = 3995, .cur = 144, .level = 85},
    169	{ .volt = 3957, .cur = 162, .level = 80},
    170	{ .volt = 3931, .cur = 147, .level = 75},
    171	{ .volt = 3902, .cur = 147, .level = 70},
    172	{ .volt = 3863, .cur = 153, .level = 65},
    173	{ .volt = 3838, .cur = 150, .level = 60},
    174	{ .volt = 3800, .cur = 153, .level = 55},
    175	{ .volt = 3765, .cur = 153, .level = 50},
    176	{ .volt = 3748, .cur = 172, .level = 45},
    177	{ .volt = 3740, .cur = 153, .level = 40},
    178	{ .volt = 3714, .cur = 175, .level = 35},
    179	{ .volt = 3710, .cur = 156, .level = 30},
    180	{ .volt = 3963, .cur = 156, .level = 25},
    181	{ .volt = 3672, .cur = 178, .level = 20},
    182	{ .volt = 3651, .cur = 178, .level = 15},
    183	{ .volt = 3629, .cur = 178, .level = 10},
    184	{ .volt = 3612, .cur = 162, .level = 5},
    185	{ .volt = 3605, .cur = 162, .level = 0},
    186};
    187
    188static const struct s3c_adc_bat_thresh bat_lut_acin[] = {
    189	{ .volt = 4200, .cur = 0, .level = 100},
    190	{ .volt = 4190, .cur = 0, .level = 99},
    191	{ .volt = 4178, .cur = 0, .level = 95},
    192	{ .volt = 4110, .cur = 0, .level = 70},
    193	{ .volt = 4076, .cur = 0, .level = 65},
    194	{ .volt = 4046, .cur = 0, .level = 60},
    195	{ .volt = 4021, .cur = 0, .level = 55},
    196	{ .volt = 3999, .cur = 0, .level = 50},
    197	{ .volt = 3982, .cur = 0, .level = 45},
    198	{ .volt = 3965, .cur = 0, .level = 40},
    199	{ .volt = 3957, .cur = 0, .level = 35},
    200	{ .volt = 3948, .cur = 0, .level = 30},
    201	{ .volt = 3936, .cur = 0, .level = 25},
    202	{ .volt = 3927, .cur = 0, .level = 20},
    203	{ .volt = 3906, .cur = 0, .level = 15},
    204	{ .volt = 3880, .cur = 0, .level = 10},
    205	{ .volt = 3829, .cur = 0, .level = 5},
    206	{ .volt = 3820, .cur = 0, .level = 0},
    207};
    208
    209static struct gpiod_lookup_table rx1950_bat_gpio_table = {
    210	.dev_id = "s3c-adc-battery",
    211	.table = {
    212		/* Charge status S3C2410_GPF(3) */
    213		GPIO_LOOKUP("GPIOF", 3, "charge-status", GPIO_ACTIVE_HIGH),
    214		{ },
    215	},
    216};
    217
    218static int rx1950_bat_init(void)
    219{
    220	int ret;
    221
    222	ret = gpio_request(S3C2410_GPJ(2), "rx1950-charger-enable-1");
    223	if (ret)
    224		goto err_gpio1;
    225	ret = gpio_request(S3C2410_GPJ(3), "rx1950-charger-enable-2");
    226	if (ret)
    227		goto err_gpio2;
    228
    229	return 0;
    230
    231err_gpio2:
    232	gpio_free(S3C2410_GPJ(2));
    233err_gpio1:
    234	return ret;
    235}
    236
    237static void rx1950_bat_exit(void)
    238{
    239	gpio_free(S3C2410_GPJ(2));
    240	gpio_free(S3C2410_GPJ(3));
    241}
    242
    243static void rx1950_enable_charger(void)
    244{
    245	gpio_direction_output(S3C2410_GPJ(2), 1);
    246	gpio_direction_output(S3C2410_GPJ(3), 1);
    247}
    248
    249static void rx1950_disable_charger(void)
    250{
    251	gpio_direction_output(S3C2410_GPJ(2), 0);
    252	gpio_direction_output(S3C2410_GPJ(3), 0);
    253}
    254
    255static DEFINE_SPINLOCK(rx1950_blink_spin);
    256
    257static int rx1950_led_blink_set(struct gpio_desc *desc, int state,
    258	unsigned long *delay_on, unsigned long *delay_off)
    259{
    260	int gpio = desc_to_gpio(desc);
    261	int blink_gpio, check_gpio;
    262
    263	switch (gpio) {
    264	case S3C2410_GPA(6):
    265		blink_gpio = S3C2410_GPA(4);
    266		check_gpio = S3C2410_GPA(3);
    267		break;
    268	case S3C2410_GPA(7):
    269		blink_gpio = S3C2410_GPA(3);
    270		check_gpio = S3C2410_GPA(4);
    271		break;
    272	default:
    273		return -EINVAL;
    274	}
    275
    276	if (delay_on && delay_off && !*delay_on && !*delay_off)
    277		*delay_on = *delay_off = 500;
    278
    279	spin_lock(&rx1950_blink_spin);
    280
    281	switch (state) {
    282	case GPIO_LED_NO_BLINK_LOW:
    283	case GPIO_LED_NO_BLINK_HIGH:
    284		if (!gpio_get_value(check_gpio))
    285			gpio_set_value(S3C2410_GPJ(6), 0);
    286		gpio_set_value(blink_gpio, 0);
    287		gpio_set_value(gpio, state);
    288		break;
    289	case GPIO_LED_BLINK:
    290		gpio_set_value(gpio, 0);
    291		gpio_set_value(S3C2410_GPJ(6), 1);
    292		gpio_set_value(blink_gpio, 1);
    293		break;
    294	}
    295
    296	spin_unlock(&rx1950_blink_spin);
    297
    298	return 0;
    299}
    300
    301static struct gpio_led rx1950_leds_desc[] = {
    302	{
    303		.name			= "Green",
    304		.default_trigger	= "main-battery-full",
    305		.gpio			= S3C2410_GPA(6),
    306		.retain_state_suspended	= 1,
    307	},
    308	{
    309		.name			= "Red",
    310		.default_trigger
    311			= "main-battery-charging-blink-full-solid",
    312		.gpio			= S3C2410_GPA(7),
    313		.retain_state_suspended	= 1,
    314	},
    315	{
    316		.name			= "Blue",
    317		.default_trigger	= "rx1950-acx-mem",
    318		.gpio			= S3C2410_GPA(11),
    319		.retain_state_suspended	= 1,
    320	},
    321};
    322
    323static struct gpio_led_platform_data rx1950_leds_pdata = {
    324	.num_leds	= ARRAY_SIZE(rx1950_leds_desc),
    325	.leds		= rx1950_leds_desc,
    326	.gpio_blink_set	= rx1950_led_blink_set,
    327};
    328
    329static struct platform_device rx1950_leds = {
    330	.name	= "leds-gpio",
    331	.id		= -1,
    332	.dev	= {
    333				.platform_data = &rx1950_leds_pdata,
    334	},
    335};
    336
    337static struct s3c_adc_bat_pdata rx1950_bat_cfg = {
    338	.init = rx1950_bat_init,
    339	.exit = rx1950_bat_exit,
    340	.enable_charger = rx1950_enable_charger,
    341	.disable_charger = rx1950_disable_charger,
    342	.lut_noac = bat_lut_noac,
    343	.lut_noac_cnt = ARRAY_SIZE(bat_lut_noac),
    344	.lut_acin = bat_lut_acin,
    345	.lut_acin_cnt = ARRAY_SIZE(bat_lut_acin),
    346	.volt_channel = 0,
    347	.current_channel = 1,
    348	.volt_mult = 4235,
    349	.current_mult = 2900,
    350	.internal_impedance = 200,
    351};
    352
    353static struct platform_device rx1950_battery = {
    354	.name             = "s3c-adc-battery",
    355	.id               = -1,
    356	.dev = {
    357		.parent = &s3c_device_adc.dev,
    358		.platform_data = &rx1950_bat_cfg,
    359	},
    360};
    361
    362static struct s3c2410fb_mach_info rx1950_lcd_cfg = {
    363	.displays = &rx1950_display,
    364	.num_displays = 1,
    365	.default_display = 0,
    366
    367	.lpcsel = 0x02,
    368	.gpccon = 0xaa9556a9,
    369	.gpccon_mask = 0xffc003fc,
    370	.gpccon_reg = S3C2410_GPCCON,
    371	.gpcup = 0x0000ffff,
    372	.gpcup_mask = 0xffffffff,
    373	.gpcup_reg = S3C2410_GPCUP,
    374
    375	.gpdcon = 0xaa90aaa1,
    376	.gpdcon_mask = 0xffc0fff0,
    377	.gpdcon_reg = S3C2410_GPDCON,
    378	.gpdup = 0x0000fcfd,
    379	.gpdup_mask = 0xffffffff,
    380	.gpdup_reg = S3C2410_GPDUP,
    381};
    382
    383static struct pwm_lookup rx1950_pwm_lookup[] = {
    384	PWM_LOOKUP("samsung-pwm", 0, "pwm-backlight.0", NULL, 48000,
    385		   PWM_POLARITY_NORMAL),
    386	PWM_LOOKUP("samsung-pwm", 1, "pwm-backlight.0", "RX1950 LCD", LCD_PWM_PERIOD,
    387		   PWM_POLARITY_NORMAL),
    388};
    389
    390static struct pwm_device *lcd_pwm;
    391static struct pwm_state lcd_pwm_state;
    392
    393static void rx1950_lcd_power(int enable)
    394{
    395	int i;
    396	static int enabled;
    397	if (enabled == enable)
    398		return;
    399	if (!enable) {
    400
    401		/* GPC11-GPC15->OUTPUT */
    402		for (i = 11; i < 16; i++)
    403			gpio_direction_output(S3C2410_GPC(i), 1);
    404
    405		/* Wait a bit here... */
    406		mdelay(100);
    407
    408		/* GPD2-GPD7->OUTPUT */
    409		/* GPD11-GPD15->OUTPUT */
    410		/* GPD2-GPD7->1, GPD11-GPD15->1 */
    411		for (i = 2; i < 8; i++)
    412			gpio_direction_output(S3C2410_GPD(i), 1);
    413		for (i = 11; i < 16; i++)
    414			gpio_direction_output(S3C2410_GPD(i), 1);
    415
    416		/* Wait a bit here...*/
    417		mdelay(100);
    418
    419		/* GPB0->OUTPUT, GPB0->0 */
    420		gpio_direction_output(S3C2410_GPB(0), 0);
    421
    422		/* GPC1-GPC4->OUTPUT, GPC1-4->0 */
    423		for (i = 1; i < 5; i++)
    424			gpio_direction_output(S3C2410_GPC(i), 0);
    425
    426		/* GPC15-GPC11->0 */
    427		for (i = 11; i < 16; i++)
    428			gpio_direction_output(S3C2410_GPC(i), 0);
    429
    430		/* GPD15-GPD11->0, GPD2->GPD7->0 */
    431		for (i = 11; i < 16; i++)
    432			gpio_direction_output(S3C2410_GPD(i), 0);
    433
    434		for (i = 2; i < 8; i++)
    435			gpio_direction_output(S3C2410_GPD(i), 0);
    436
    437		/* GPC6->0, GPC7->0, GPC5->0 */
    438		gpio_direction_output(S3C2410_GPC(6), 0);
    439		gpio_direction_output(S3C2410_GPC(7), 0);
    440		gpio_direction_output(S3C2410_GPC(5), 0);
    441
    442		/* GPB1->OUTPUT, GPB1->0 */
    443		gpio_direction_output(S3C2410_GPB(1), 0);
    444
    445		lcd_pwm_state.enabled = false;
    446		pwm_apply_state(lcd_pwm, &lcd_pwm_state);
    447
    448		/* GPC0->0, GPC10->0 */
    449		gpio_direction_output(S3C2410_GPC(0), 0);
    450		gpio_direction_output(S3C2410_GPC(10), 0);
    451	} else {
    452		lcd_pwm_state.enabled = true;
    453		pwm_apply_state(lcd_pwm, &lcd_pwm_state);
    454
    455		gpio_direction_output(S3C2410_GPC(0), 1);
    456		gpio_direction_output(S3C2410_GPC(5), 1);
    457
    458		s3c_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPB1_TOUT1);
    459		gpio_direction_output(S3C2410_GPC(7), 1);
    460
    461		for (i = 1; i < 5; i++)
    462			s3c_gpio_cfgpin(S3C2410_GPC(i), S3C_GPIO_SFN(2));
    463
    464		for (i = 11; i < 16; i++)
    465			s3c_gpio_cfgpin(S3C2410_GPC(i), S3C_GPIO_SFN(2));
    466
    467		for (i = 2; i < 8; i++)
    468			s3c_gpio_cfgpin(S3C2410_GPD(i), S3C_GPIO_SFN(2));
    469
    470		for (i = 11; i < 16; i++)
    471			s3c_gpio_cfgpin(S3C2410_GPD(i), S3C_GPIO_SFN(2));
    472
    473		gpio_direction_output(S3C2410_GPC(10), 1);
    474		gpio_direction_output(S3C2410_GPC(6), 1);
    475	}
    476	enabled = enable;
    477}
    478
    479static void rx1950_bl_power(int enable)
    480{
    481	static int enabled;
    482	if (enabled == enable)
    483		return;
    484	if (!enable) {
    485			gpio_direction_output(S3C2410_GPB(0), 0);
    486	} else {
    487			/* LED driver need a "push" to power on */
    488			gpio_direction_output(S3C2410_GPB(0), 1);
    489			/* Warm up backlight for one period of PWM.
    490			 * Without this trick its almost impossible to
    491			 * enable backlight with low brightness value
    492			 */
    493			ndelay(48000);
    494			s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
    495	}
    496	enabled = enable;
    497}
    498
    499static int rx1950_backlight_init(struct device *dev)
    500{
    501	WARN_ON(gpio_request(S3C2410_GPB(0), "Backlight"));
    502	lcd_pwm = pwm_get(dev, "RX1950 LCD");
    503	if (IS_ERR(lcd_pwm)) {
    504		dev_err(dev, "Unable to request PWM for LCD power!\n");
    505		return PTR_ERR(lcd_pwm);
    506	}
    507
    508	/*
    509	 * Call pwm_init_state to initialize .polarity and .period. The other
    510	 * values are fixed in this driver.
    511	 */
    512	pwm_init_state(lcd_pwm, &lcd_pwm_state);
    513
    514	lcd_pwm_state.duty_cycle = LCD_PWM_DUTY;
    515
    516	rx1950_lcd_power(1);
    517	rx1950_bl_power(1);
    518
    519	return 0;
    520}
    521
    522static void rx1950_backlight_exit(struct device *dev)
    523{
    524	rx1950_bl_power(0);
    525	rx1950_lcd_power(0);
    526
    527	pwm_put(lcd_pwm);
    528	gpio_free(S3C2410_GPB(0));
    529}
    530
    531
    532static int rx1950_backlight_notify(struct device *dev, int brightness)
    533{
    534	if (!brightness) {
    535		rx1950_bl_power(0);
    536		rx1950_lcd_power(0);
    537	} else {
    538		rx1950_lcd_power(1);
    539		rx1950_bl_power(1);
    540	}
    541	return brightness;
    542}
    543
    544static struct platform_pwm_backlight_data rx1950_backlight_data = {
    545	.max_brightness = 24,
    546	.dft_brightness = 4,
    547	.init = rx1950_backlight_init,
    548	.notify = rx1950_backlight_notify,
    549	.exit = rx1950_backlight_exit,
    550};
    551
    552static struct platform_device rx1950_backlight = {
    553	.name = "pwm-backlight",
    554	.dev = {
    555		.parent = &samsung_device_pwm.dev,
    556		.platform_data = &rx1950_backlight_data,
    557	},
    558};
    559
    560static void rx1950_set_mmc_power(unsigned char power_mode, unsigned short vdd)
    561{
    562	s3c24xx_mci_def_set_power(power_mode, vdd);
    563
    564	switch (power_mode) {
    565	case MMC_POWER_OFF:
    566		gpio_direction_output(S3C2410_GPJ(1), 0);
    567		break;
    568	case MMC_POWER_UP:
    569	case MMC_POWER_ON:
    570		gpio_direction_output(S3C2410_GPJ(1), 1);
    571		break;
    572	default:
    573		break;
    574	}
    575}
    576
    577static struct s3c24xx_mci_pdata rx1950_mmc_cfg __initdata = {
    578	.set_power = rx1950_set_mmc_power,
    579	.ocr_avail = MMC_VDD_32_33,
    580};
    581
    582static struct gpiod_lookup_table rx1950_mmc_gpio_table = {
    583	.dev_id = "s3c2410-sdi",
    584	.table = {
    585		/* Card detect S3C2410_GPF(5) */
    586		GPIO_LOOKUP("GPIOF", 5, "cd", GPIO_ACTIVE_LOW),
    587		/* Write protect S3C2410_GPH(8) */
    588		GPIO_LOOKUP("GPIOH", 8, "wp", GPIO_ACTIVE_LOW),
    589		/* bus pins */
    590		GPIO_LOOKUP_IDX("GPIOE",  5, "bus", 0, GPIO_ACTIVE_HIGH),
    591		GPIO_LOOKUP_IDX("GPIOE",  6, "bus", 1, GPIO_ACTIVE_HIGH),
    592		GPIO_LOOKUP_IDX("GPIOE",  7, "bus", 2, GPIO_ACTIVE_HIGH),
    593		GPIO_LOOKUP_IDX("GPIOE",  8, "bus", 3, GPIO_ACTIVE_HIGH),
    594		GPIO_LOOKUP_IDX("GPIOE",  9, "bus", 4, GPIO_ACTIVE_HIGH),
    595		GPIO_LOOKUP_IDX("GPIOE", 10, "bus", 5, GPIO_ACTIVE_HIGH),
    596		{ },
    597	},
    598};
    599
    600static struct mtd_partition rx1950_nand_part[] = {
    601	[0] = {
    602			.name = "Boot0",
    603			.offset = 0,
    604			.size = 0x4000,
    605			.mask_flags = MTD_WRITEABLE,
    606	},
    607	[1] = {
    608			.name = "Boot1",
    609			.offset = MTDPART_OFS_APPEND,
    610			.size = 0x40000,
    611			.mask_flags = MTD_WRITEABLE,
    612	},
    613	[2] = {
    614			.name = "Kernel",
    615			.offset = MTDPART_OFS_APPEND,
    616			.size = 0x300000,
    617			.mask_flags = 0,
    618	},
    619	[3] = {
    620			.name = "Filesystem",
    621			.offset = MTDPART_OFS_APPEND,
    622			.size = MTDPART_SIZ_FULL,
    623			.mask_flags = 0,
    624	},
    625};
    626
    627static struct s3c2410_nand_set rx1950_nand_sets[] = {
    628	[0] = {
    629			.name = "Internal",
    630			.nr_chips = 1,
    631			.nr_partitions = ARRAY_SIZE(rx1950_nand_part),
    632			.partitions = rx1950_nand_part,
    633	},
    634};
    635
    636static struct s3c2410_platform_nand rx1950_nand_info = {
    637	.tacls = 25,
    638	.twrph0 = 50,
    639	.twrph1 = 15,
    640	.nr_sets = ARRAY_SIZE(rx1950_nand_sets),
    641	.sets = rx1950_nand_sets,
    642	.engine_type = NAND_ECC_ENGINE_TYPE_SOFT,
    643};
    644
    645static struct s3c2410_udc_mach_info rx1950_udc_cfg __initdata = {
    646	.vbus_pin = S3C2410_GPG(5),
    647	.vbus_pin_inverted = 1,
    648	.pullup_pin = S3C2410_GPJ(5),
    649};
    650
    651static struct s3c2410_ts_mach_info rx1950_ts_cfg __initdata = {
    652	.delay = 10000,
    653	.presc = 49,
    654	.oversampling_shift = 3,
    655};
    656
    657static struct gpio_keys_button rx1950_gpio_keys_table[] = {
    658	{
    659		.code		= KEY_POWER,
    660		.gpio		= S3C2410_GPF(0),
    661		.active_low	= 1,
    662		.desc		= "Power button",
    663		.wakeup		= 1,
    664	},
    665	{
    666		.code		= KEY_F5,
    667		.gpio		= S3C2410_GPF(7),
    668		.active_low	= 1,
    669		.desc		= "Record button",
    670	},
    671	{
    672		.code		= KEY_F1,
    673		.gpio		= S3C2410_GPG(0),
    674		.active_low	= 1,
    675		.desc		= "Calendar button",
    676	},
    677	{
    678		.code		= KEY_F2,
    679		.gpio		= S3C2410_GPG(2),
    680		.active_low	= 1,
    681		.desc		= "Contacts button",
    682	},
    683	{
    684		.code		= KEY_F3,
    685		.gpio		= S3C2410_GPG(3),
    686		.active_low	= 1,
    687		.desc		= "Mail button",
    688	},
    689	{
    690		.code		= KEY_F4,
    691		.gpio		= S3C2410_GPG(7),
    692		.active_low	= 1,
    693		.desc		= "WLAN button",
    694	},
    695	{
    696		.code		= KEY_LEFT,
    697		.gpio		= S3C2410_GPG(10),
    698		.active_low	= 1,
    699		.desc		= "Left button",
    700	},
    701	{
    702		.code		= KEY_RIGHT,
    703		.gpio		= S3C2410_GPG(11),
    704		.active_low	= 1,
    705		.desc		= "Right button",
    706	},
    707	{
    708		.code		= KEY_UP,
    709		.gpio		= S3C2410_GPG(4),
    710		.active_low	= 1,
    711		.desc		= "Up button",
    712	},
    713	{
    714		.code		= KEY_DOWN,
    715		.gpio		= S3C2410_GPG(6),
    716		.active_low	= 1,
    717		.desc		= "Down button",
    718	},
    719	{
    720		.code		= KEY_ENTER,
    721		.gpio		= S3C2410_GPG(9),
    722		.active_low	= 1,
    723		.desc		= "Ok button"
    724	},
    725};
    726
    727static struct gpio_keys_platform_data rx1950_gpio_keys_data = {
    728	.buttons = rx1950_gpio_keys_table,
    729	.nbuttons = ARRAY_SIZE(rx1950_gpio_keys_table),
    730};
    731
    732static struct platform_device rx1950_device_gpiokeys = {
    733	.name = "gpio-keys",
    734	.dev.platform_data = &rx1950_gpio_keys_data,
    735};
    736
    737static struct uda1380_platform_data uda1380_info = {
    738	.gpio_power	= S3C2410_GPJ(0),
    739	.gpio_reset	= S3C2410_GPD(0),
    740	.dac_clk	= UDA1380_DAC_CLK_SYSCLK,
    741};
    742
    743static struct i2c_board_info rx1950_i2c_devices[] = {
    744	{
    745		I2C_BOARD_INFO("uda1380", 0x1a),
    746		.platform_data = &uda1380_info,
    747	},
    748};
    749
    750static struct gpiod_lookup_table rx1950_audio_gpio_table = {
    751	.dev_id = "rx1950-audio",
    752	.table = {
    753		GPIO_LOOKUP("GPIOG", 12, "hp-gpio", GPIO_ACTIVE_HIGH),
    754		GPIO_LOOKUP("GPIOA", 1, "speaker-power", GPIO_ACTIVE_HIGH),
    755		{ },
    756	},
    757};
    758
    759static struct platform_device rx1950_audio = {
    760	.name = "rx1950-audio",
    761	.id = -1,
    762};
    763
    764static struct platform_device *rx1950_devices[] __initdata = {
    765	&s3c2410_device_dclk,
    766	&s3c_device_lcd,
    767	&s3c_device_wdt,
    768	&s3c_device_i2c0,
    769	&s3c_device_iis,
    770	&s3c_device_usbgadget,
    771	&s3c_device_rtc,
    772	&s3c_device_nand,
    773	&s3c_device_sdi,
    774	&s3c_device_adc,
    775	&s3c_device_ts,
    776	&samsung_device_pwm,
    777	&rx1950_backlight,
    778	&rx1950_device_gpiokeys,
    779	&power_supply,
    780	&rx1950_battery,
    781	&rx1950_leds,
    782	&rx1950_audio,
    783};
    784
    785static void __init rx1950_map_io(void)
    786{
    787	s3c24xx_init_io(rx1950_iodesc, ARRAY_SIZE(rx1950_iodesc));
    788	s3c24xx_init_uarts(rx1950_uartcfgs, ARRAY_SIZE(rx1950_uartcfgs));
    789	s3c24xx_set_timer_source(S3C24XX_PWM3, S3C24XX_PWM4);
    790
    791	/* setup PM */
    792
    793#ifdef CONFIG_PM_H1940
    794	memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 8);
    795#endif
    796
    797	s3c_pm_init();
    798}
    799
    800static void __init rx1950_init_time(void)
    801{
    802	s3c2442_init_clocks(16934000);
    803	s3c24xx_timer_init();
    804}
    805
    806static void __init rx1950_init_machine(void)
    807{
    808	int i;
    809
    810	s3c24xx_fb_set_platdata(&rx1950_lcd_cfg);
    811	s3c24xx_udc_set_platdata(&rx1950_udc_cfg);
    812	s3c24xx_ts_set_platdata(&rx1950_ts_cfg);
    813	gpiod_add_lookup_table(&rx1950_mmc_gpio_table);
    814	s3c24xx_mci_set_platdata(&rx1950_mmc_cfg);
    815	s3c_i2c0_set_platdata(NULL);
    816	s3c_nand_set_platdata(&rx1950_nand_info);
    817
    818	/* Turn off suspend on both USB ports, and switch the
    819	 * selectable USB port to USB device mode. */
    820	s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
    821						S3C2410_MISCCR_USBSUSPND0 |
    822						S3C2410_MISCCR_USBSUSPND1, 0x0);
    823
    824	/* mmc power is disabled by default */
    825	WARN_ON(gpio_request(S3C2410_GPJ(1), "MMC power"));
    826	gpio_direction_output(S3C2410_GPJ(1), 0);
    827
    828	for (i = 0; i < 8; i++)
    829		WARN_ON(gpio_request(S3C2410_GPC(i), "LCD power"));
    830
    831	for (i = 10; i < 16; i++)
    832		WARN_ON(gpio_request(S3C2410_GPC(i), "LCD power"));
    833
    834	for (i = 2; i < 8; i++)
    835		WARN_ON(gpio_request(S3C2410_GPD(i), "LCD power"));
    836
    837	for (i = 11; i < 16; i++)
    838		WARN_ON(gpio_request(S3C2410_GPD(i), "LCD power"));
    839
    840	WARN_ON(gpio_request(S3C2410_GPB(1), "LCD power"));
    841
    842	WARN_ON(gpio_request(S3C2410_GPA(3), "Red blink"));
    843	WARN_ON(gpio_request(S3C2410_GPA(4), "Green blink"));
    844	WARN_ON(gpio_request(S3C2410_GPJ(6), "LED blink"));
    845	gpio_direction_output(S3C2410_GPA(3), 0);
    846	gpio_direction_output(S3C2410_GPA(4), 0);
    847	gpio_direction_output(S3C2410_GPJ(6), 0);
    848
    849	pwm_add_table(rx1950_pwm_lookup, ARRAY_SIZE(rx1950_pwm_lookup));
    850	gpiod_add_lookup_table(&rx1950_audio_gpio_table);
    851	gpiod_add_lookup_table(&rx1950_bat_gpio_table);
    852	/* Configure the I2S pins (GPE0...GPE4) in correct mode */
    853	s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2),
    854			      S3C_GPIO_PULL_NONE);
    855	platform_add_devices(rx1950_devices, ARRAY_SIZE(rx1950_devices));
    856
    857	i2c_register_board_info(0, rx1950_i2c_devices,
    858		ARRAY_SIZE(rx1950_i2c_devices));
    859}
    860
    861/* H1940 and RX3715 need to reserve this for suspend */
    862static void __init rx1950_reserve(void)
    863{
    864	memblock_reserve(0x30003000, 0x1000);
    865	memblock_reserve(0x30081000, 0x1000);
    866}
    867
    868MACHINE_START(RX1950, "HP iPAQ RX1950")
    869    /* Maintainers: Vasily Khoruzhick */
    870	.atag_offset = 0x100,
    871	.nr_irqs	= NR_IRQS_S3C2442,
    872	.map_io = rx1950_map_io,
    873	.reserve	= rx1950_reserve,
    874	.init_irq	= s3c2442_init_irq,
    875	.init_machine = rx1950_init_machine,
    876	.init_time	= rx1950_init_time,
    877MACHINE_END