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