1/*
2 * linux/arch/unicore32/kernel/puv3-nb0916.c
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 *	Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
7 *	Copyright (C) 2001-2010 Guan Xuetao
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/init.h>
15#include <linux/device.h>
16#include <linux/platform_device.h>
17#include <linux/mtd/physmap.h>
18#include <linux/io.h>
19#include <linux/reboot.h>
20#include <linux/interrupt.h>
21#include <linux/i2c.h>
22#include <linux/pwm_backlight.h>
23#include <linux/gpio.h>
24#include <linux/gpio_keys.h>
25#include <linux/input.h>
26
27#include <mach/hardware.h>
28
29static struct physmap_flash_data physmap_flash_data = {
30	.width		= 1,
31};
32
33static struct resource physmap_flash_resource = {
34	.start		= 0xFFF80000,
35	.end		= 0xFFFFFFFF,
36	.flags		= IORESOURCE_MEM,
37};
38
39static struct resource puv3_i2c_resources[] = {
40	[0] = {
41		.start = io_v2p(PKUNITY_I2C_BASE),
42		.end   = io_v2p(PKUNITY_I2C_BASE) + 0xff,
43		.flags = IORESOURCE_MEM,
44	},
45	[1] = {
46		.start = IRQ_I2C,
47		.end   = IRQ_I2C,
48		.flags = IORESOURCE_IRQ,
49	}
50};
51
52static struct platform_pwm_backlight_data nb0916_backlight_data = {
53	.pwm_id		= 0,
54	.max_brightness	= 100,
55	.dft_brightness	= 100,
56	.pwm_period_ns	= 70 * 1024,
57	.enable_gpio	= -1,
58};
59
60static struct gpio_keys_button nb0916_gpio_keys[] = {
61	{
62		.type	= EV_KEY,
63		.code	= KEY_POWER,
64		.gpio	= GPI_SOFF_REQ,
65		.desc	= "Power Button",
66		.wakeup = 1,
67		.active_low = 1,
68	},
69	{
70		.type	= EV_KEY,
71		.code	= BTN_TOUCH,
72		.gpio	= GPI_BTN_TOUCH,
73		.desc	= "Touchpad Button",
74		.wakeup = 1,
75		.active_low = 1,
76	},
77};
78
79static struct gpio_keys_platform_data nb0916_gpio_button_data = {
80	.buttons	= nb0916_gpio_keys,
81	.nbuttons	= ARRAY_SIZE(nb0916_gpio_keys),
82};
83
84static irqreturn_t nb0916_lcdcaseoff_handler(int irq, void *dev_id)
85{
86	if (gpio_get_value(GPI_LCD_CASE_OFF))
87		gpio_set_value(GPO_LCD_EN, 1);
88	else
89		gpio_set_value(GPO_LCD_EN, 0);
90
91	return IRQ_HANDLED;
92}
93
94static irqreturn_t nb0916_overheat_handler(int irq, void *dev_id)
95{
96	machine_halt();
97	/* SYSTEM HALT, NO RETURN */
98	return IRQ_HANDLED;
99}
100
101static struct i2c_board_info __initdata puv3_i2c_devices[] = {
102	{	I2C_BOARD_INFO("lm75",		I2C_TAR_THERMAL),	},
103	{	I2C_BOARD_INFO("bq27200",	I2C_TAR_PWIC),		},
104	{	I2C_BOARD_INFO("24c02",		I2C_TAR_EEPROM),	},
105};
106
107int __init mach_nb0916_init(void)
108{
109	i2c_register_board_info(0, puv3_i2c_devices,
110			ARRAY_SIZE(puv3_i2c_devices));
111
112	platform_device_register_simple("PKUnity-v3-I2C", -1,
113			puv3_i2c_resources, ARRAY_SIZE(puv3_i2c_resources));
114
115	platform_device_register_data(NULL, "pwm-backlight", -1,
116			&nb0916_backlight_data, sizeof(nb0916_backlight_data));
117
118	platform_device_register_data(NULL, "gpio-keys", -1,
119			&nb0916_gpio_button_data, sizeof(nb0916_gpio_button_data));
120
121	platform_device_register_resndata(NULL, "physmap-flash", -1,
122			&physmap_flash_resource, 1,
123			&physmap_flash_data, sizeof(physmap_flash_data));
124
125	if (request_irq(gpio_to_irq(GPI_LCD_CASE_OFF),
126		&nb0916_lcdcaseoff_handler,
127		IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
128		"NB0916 lcd case off", NULL) < 0) {
129
130		printk(KERN_DEBUG "LCD-Case-OFF IRQ %d not available\n",
131			gpio_to_irq(GPI_LCD_CASE_OFF));
132	}
133
134	if (request_irq(gpio_to_irq(GPI_OTP_INT), &nb0916_overheat_handler,
135		IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
136		"NB0916 overheating protection", NULL) < 0) {
137
138		printk(KERN_DEBUG "Overheating Protection IRQ %d not available\n",
139			gpio_to_irq(GPI_OTP_INT));
140	}
141
142	return 0;
143}
144
145subsys_initcall_sync(mach_nb0916_init);
146