linux/arch/unicore32/kernel/puv3-nb0916.c
<<
>>
Prefs
   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