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.h>
23#include <linux/pwm_backlight.h>
24#include <linux/gpio.h>
25#include <linux/gpio_keys.h>
26#include <linux/input.h>
27
28#include <mach/hardware.h>
29
30static struct physmap_flash_data physmap_flash_data = {
31	.width		= 1,
32};
33
34static struct resource physmap_flash_resource = {
35	.start		= 0xFFF80000,
36	.end		= 0xFFFFFFFF,
37	.flags		= IORESOURCE_MEM,
38};
39
40static struct resource puv3_i2c_resources[] = {
41	[0] = {
42		.start = io_v2p(PKUNITY_I2C_BASE),
43		.end   = io_v2p(PKUNITY_I2C_BASE) + 0xff,
44		.flags = IORESOURCE_MEM,
45	},
46	[1] = {
47		.start = IRQ_I2C,
48		.end   = IRQ_I2C,
49		.flags = IORESOURCE_IRQ,
50	}
51};
52
53static struct pwm_lookup nb0916_pwm_lookup[] = {
54	PWM_LOOKUP("PKUnity-v3-PWM", 0, "pwm-backlight", NULL, 70 * 1024,
55		   PWM_POLARITY_NORMAL),
56};
57
58static struct platform_pwm_backlight_data nb0916_backlight_data = {
59	.max_brightness	= 100,
60	.dft_brightness	= 100,
61	.enable_gpio	= -1,
62};
63
64static struct gpio_keys_button nb0916_gpio_keys[] = {
65	{
66		.type	= EV_KEY,
67		.code	= KEY_POWER,
68		.gpio	= GPI_SOFF_REQ,
69		.desc	= "Power Button",
70		.wakeup = 1,
71		.active_low = 1,
72	},
73	{
74		.type	= EV_KEY,
75		.code	= BTN_TOUCH,
76		.gpio	= GPI_BTN_TOUCH,
77		.desc	= "Touchpad Button",
78		.wakeup = 1,
79		.active_low = 1,
80	},
81};
82
83static struct gpio_keys_platform_data nb0916_gpio_button_data = {
84	.buttons	= nb0916_gpio_keys,
85	.nbuttons	= ARRAY_SIZE(nb0916_gpio_keys),
86};
87
88static irqreturn_t nb0916_lcdcaseoff_handler(int irq, void *dev_id)
89{
90	if (gpio_get_value(GPI_LCD_CASE_OFF))
91		gpio_set_value(GPO_LCD_EN, 1);
92	else
93		gpio_set_value(GPO_LCD_EN, 0);
94
95	return IRQ_HANDLED;
96}
97
98static irqreturn_t nb0916_overheat_handler(int irq, void *dev_id)
99{
100	machine_halt();
101	/* SYSTEM HALT, NO RETURN */
102	return IRQ_HANDLED;
103}
104
105static struct i2c_board_info __initdata puv3_i2c_devices[] = {
106	{	I2C_BOARD_INFO("lm75",		I2C_TAR_THERMAL),	},
107	{	I2C_BOARD_INFO("bq27200",	I2C_TAR_PWIC),		},
108	{	I2C_BOARD_INFO("24c02",		I2C_TAR_EEPROM),	},
109};
110
111int __init mach_nb0916_init(void)
112{
113	i2c_register_board_info(0, puv3_i2c_devices,
114			ARRAY_SIZE(puv3_i2c_devices));
115
116	platform_device_register_simple("PKUnity-v3-I2C", -1,
117			puv3_i2c_resources, ARRAY_SIZE(puv3_i2c_resources));
118
119	pwm_add_table(nb0916_pwm_lookup, ARRAY_SIZE(nb0916_pwm_lookup));
120
121	platform_device_register_data(NULL, "pwm-backlight", -1,
122			&nb0916_backlight_data, sizeof(nb0916_backlight_data));
123
124	platform_device_register_data(NULL, "gpio-keys", -1,
125			&nb0916_gpio_button_data, sizeof(nb0916_gpio_button_data));
126
127	platform_device_register_resndata(NULL, "physmap-flash", -1,
128			&physmap_flash_resource, 1,
129			&physmap_flash_data, sizeof(physmap_flash_data));
130
131	if (request_irq(gpio_to_irq(GPI_LCD_CASE_OFF),
132		&nb0916_lcdcaseoff_handler,
133		IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
134		"NB0916 lcd case off", NULL) < 0) {
135
136		printk(KERN_DEBUG "LCD-Case-OFF IRQ %d not available\n",
137			gpio_to_irq(GPI_LCD_CASE_OFF));
138	}
139
140	if (request_irq(gpio_to_irq(GPI_OTP_INT), &nb0916_overheat_handler,
141		IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
142		"NB0916 overheating protection", NULL) < 0) {
143
144		printk(KERN_DEBUG "Overheating Protection IRQ %d not available\n",
145			gpio_to_irq(GPI_OTP_INT));
146	}
147
148	return 0;
149}
150
151subsys_initcall_sync(mach_nb0916_init);
152