Merge branch 'misc' into release
[safe/jmp/linux-2.6] / arch / arm / mach-pxa / magician.c
index 1fa80c0..189f330 100644 (file)
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
+#include <linux/gpio.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <linux/mfd/htc-egpio.h>
 #include <linux/mfd/htc-pasic3.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
 #include <linux/mtd/physmap.h>
 #include <linux/pda_power.h>
+#include <linux/pwm_backlight.h>
+#include <linux/regulator/bq24022.h>
+#include <linux/regulator/machine.h>
+#include <linux/usb/gpio_vbus.h>
 
-#include <asm/gpio.h>
-#include <asm/hardware.h>
+#include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/arch/magician.h>
-#include <asm/arch/mfp-pxa27x.h>
-#include <asm/arch/pxa-regs.h>
-#include <asm/arch/pxafb.h>
-#include <asm/arch/i2c.h>
-#include <asm/arch/mmc.h>
-#include <asm/arch/irda.h>
-#include <asm/arch/ohci.h>
 
+#include <mach/pxa27x.h>
+#include <mach/magician.h>
+#include <mach/pxafb.h>
+#include <plat/i2c.h>
+#include <mach/mmc.h>
+#include <mach/irda.h>
+#include <mach/ohci.h>
+
+#include "devices.h"
 #include "generic.h"
 
-static unsigned long magician_pin_config[] = {
+static unsigned long magician_pin_config[] __initdata = {
 
        /* SDRAM and Static Memory I/O Signals */
        GPIO20_nSDCS_2,
@@ -65,6 +68,11 @@ static unsigned long magician_pin_config[] = {
        GPIO31_I2S_SYNC,
        GPIO113_I2S_SYSCLK,
 
+       /* SSP 1 */
+       GPIO23_SSP1_SCLK,
+       GPIO24_SSP1_SFRM,
+       GPIO25_SSP1_TXD,
+
        /* SSP 2 */
        GPIO19_SSP2_SCLK,
        GPIO14_SSP2_SFRM,
@@ -122,42 +130,50 @@ static unsigned long magician_pin_config[] = {
        GPIO107_GPIO,   /* DS1WM_IRQ */
        GPIO108_GPIO,   /* GSM_READY */
        GPIO115_GPIO,   /* nPEN_IRQ */
+
+       /* I2C */
+       GPIO117_I2C_SCL,
+       GPIO118_I2C_SDA,
 };
 
 /*
  * IRDA
  */
 
-static void magician_irda_transceiver_mode(struct device *dev, int mode)
-{
-       gpio_set_value(GPIO83_MAGICIAN_nIR_EN, mode & IR_OFF);
-}
-
 static struct pxaficp_platform_data magician_ficp_info = {
-       .transceiver_cap  = IR_SIRMODE | IR_OFF,
-       .transceiver_mode = magician_irda_transceiver_mode,
+       .gpio_pwdown            = GPIO83_MAGICIAN_nIR_EN,
+       .transceiver_cap        = IR_SIRMODE | IR_OFF,
 };
 
 /*
  * GPIO Keys
  */
 
+#define INIT_KEY(_code, _gpio, _desc)  \
+       {                               \
+               .code   = KEY_##_code,  \
+               .gpio   = _gpio,        \
+               .desc   = _desc,        \
+               .type   = EV_KEY,       \
+               .wakeup = 1,            \
+       }
+
 static struct gpio_keys_button magician_button_table[] = {
-       {KEY_POWER,      GPIO0_MAGICIAN_KEY_POWER,      0, "Power button"},
-       {KEY_ESC,        GPIO37_MAGICIAN_KEY_HANGUP,    0, "Hangup button"},
-       {KEY_F10,        GPIO38_MAGICIAN_KEY_CONTACTS,  0, "Contacts button"},
-       {KEY_CALENDAR,   GPIO90_MAGICIAN_KEY_CALENDAR,  0, "Calendar button"},
-       {KEY_CAMERA,     GPIO91_MAGICIAN_KEY_CAMERA,    0, "Camera button"},
-       {KEY_UP,         GPIO93_MAGICIAN_KEY_UP,        0, "Up button"},
-       {KEY_DOWN,       GPIO94_MAGICIAN_KEY_DOWN,      0, "Down button"},
-       {KEY_LEFT,       GPIO95_MAGICIAN_KEY_LEFT,      0, "Left button"},
-       {KEY_RIGHT,      GPIO96_MAGICIAN_KEY_RIGHT,     0, "Right button"},
-       {KEY_KPENTER,    GPIO97_MAGICIAN_KEY_ENTER,     0, "Action button"},
-       {KEY_RECORD,     GPIO98_MAGICIAN_KEY_RECORD,    0, "Record button"},
-       {KEY_VOLUMEUP,   GPIO100_MAGICIAN_KEY_VOL_UP,   0, "Volume up"},
-       {KEY_VOLUMEDOWN, GPIO101_MAGICIAN_KEY_VOL_DOWN, 0, "Volume down"},
-       {KEY_PHONE,      GPIO102_MAGICIAN_KEY_PHONE,    0, "Phone button"},
-       {KEY_PLAY,       GPIO99_MAGICIAN_HEADPHONE_IN,  0, "Headset button"},
+       INIT_KEY(POWER,      GPIO0_MAGICIAN_KEY_POWER,      "Power button"),
+       INIT_KEY(ESC,        GPIO37_MAGICIAN_KEY_HANGUP,    "Hangup button"),
+       INIT_KEY(F10,        GPIO38_MAGICIAN_KEY_CONTACTS,  "Contacts button"),
+       INIT_KEY(CALENDAR,   GPIO90_MAGICIAN_KEY_CALENDAR,  "Calendar button"),
+       INIT_KEY(CAMERA,     GPIO91_MAGICIAN_KEY_CAMERA,    "Camera button"),
+       INIT_KEY(UP,         GPIO93_MAGICIAN_KEY_UP,        "Up button"),
+       INIT_KEY(DOWN,       GPIO94_MAGICIAN_KEY_DOWN,      "Down button"),
+       INIT_KEY(LEFT,       GPIO95_MAGICIAN_KEY_LEFT,      "Left button"),
+       INIT_KEY(RIGHT,      GPIO96_MAGICIAN_KEY_RIGHT,     "Right button"),
+       INIT_KEY(KPENTER,    GPIO97_MAGICIAN_KEY_ENTER,     "Action button"),
+       INIT_KEY(RECORD,     GPIO98_MAGICIAN_KEY_RECORD,    "Record button"),
+       INIT_KEY(VOLUMEUP,   GPIO100_MAGICIAN_KEY_VOL_UP,   "Volume up"),
+       INIT_KEY(VOLUMEDOWN, GPIO101_MAGICIAN_KEY_VOL_DOWN, "Volume down"),
+       INIT_KEY(PHONE,      GPIO102_MAGICIAN_KEY_PHONE,    "Phone button"),
+       INIT_KEY(PLAY,       GPIO99_MAGICIAN_HEADPHONE_IN,  "Headset button"),
 };
 
 static struct gpio_keys_platform_data gpio_keys_data = {
@@ -183,7 +199,7 @@ static struct platform_device gpio_keys = {
 static struct resource egpio_resources[] = {
        [0] = {
                .start = PXA_CS3_PHYS,
-               .end   = PXA_CS3_PHYS + 0x20,
+               .end   = PXA_CS3_PHYS + 0x20 - 1,
                .flags = IORESOURCE_MEM,
        },
        [1] = {
@@ -330,8 +346,7 @@ static struct pxafb_mach_info toppoly_info = {
        .modes           = toppoly_modes,
        .num_modes       = 1,
        .fixed_modes     = 1,
-       .lccr0           = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-       .lccr3           = LCCR3_PixRsEdg,
+       .lcd_conn       = LCD_COLOR_TFT_16BPP,
        .pxafb_lcd_power = toppoly_lcd_power,
 };
 
@@ -339,8 +354,8 @@ static struct pxafb_mach_info samsung_info = {
        .modes           = samsung_modes,
        .num_modes       = 1,
        .fixed_modes     = 1,
-       .lccr0           = LCCR0_LDDALT | LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-       .lccr3           = LCCR3_PixFlEdg,
+       .lcd_conn        = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |\
+                          LCD_ALTERNATE_MAPPING,
        .pxafb_lcd_power = samsung_lcd_power,
 };
 
@@ -348,47 +363,66 @@ static struct pxafb_mach_info samsung_info = {
  * Backlight
  */
 
-static void magician_set_bl_intensity(int intensity)
+static int magician_backlight_init(struct device *dev)
 {
-       if (intensity) {
-               PWM_CTRL0 = 1;
-               PWM_PERVAL0 = 0xc8;
-               if (intensity > 0xc7) {
-                       PWM_PWDUTY0 = intensity - 0x48;
-                       gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 1);
-               } else {
-                       PWM_PWDUTY0 = intensity;
-                       gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 0);
-               }
-               gpio_set_value(EGPIO_MAGICIAN_BL_POWER, 1);
-               pxa_set_cken(CKEN_PWM0, 1);
+       int ret;
+
+       ret = gpio_request(EGPIO_MAGICIAN_BL_POWER, "BL_POWER");
+       if (ret)
+               goto err;
+       ret = gpio_request(EGPIO_MAGICIAN_BL_POWER2, "BL_POWER2");
+       if (ret)
+               goto err2;
+       return 0;
+
+err2:
+       gpio_free(EGPIO_MAGICIAN_BL_POWER);
+err:
+       return ret;
+}
+
+static int magician_backlight_notify(struct device *dev, int brightness)
+{
+       gpio_set_value(EGPIO_MAGICIAN_BL_POWER, brightness);
+       if (brightness >= 200) {
+               gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 1);
+               return brightness - 72;
        } else {
-               /* PWM_PWDUTY0 = intensity; */
-               gpio_set_value(EGPIO_MAGICIAN_BL_POWER, 0);
-               pxa_set_cken(CKEN_PWM0, 0);
+               gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 0);
+               return brightness;
        }
 }
 
-static struct generic_bl_info backlight_info = {
-       .default_intensity = 0x64,
-       .limit_mask        = 0x0b,
-       .max_intensity     = 0xc7+0x48,
-       .set_bl_intensity  = magician_set_bl_intensity,
+static void magician_backlight_exit(struct device *dev)
+{
+       gpio_free(EGPIO_MAGICIAN_BL_POWER);
+       gpio_free(EGPIO_MAGICIAN_BL_POWER2);
+}
+
+static struct platform_pwm_backlight_data backlight_data = {
+       .pwm_id         = 0,
+       .max_brightness = 272,
+       .dft_brightness = 100,
+       .pwm_period_ns  = 30923,
+       .init           = magician_backlight_init,
+       .notify         = magician_backlight_notify,
+       .exit           = magician_backlight_exit,
 };
 
 static struct platform_device backlight = {
-       .name = "generic-bl",
+       .name = "pwm-backlight",
+       .id   = -1,
        .dev  = {
-               .platform_data = &backlight_info,
+               .parent        = &pxa27x_device_pwm0.dev,
+               .platform_data = &backlight_data,
        },
-       .id   = -1,
 };
 
 /*
  * LEDs
  */
 
-struct gpio_led gpio_leds[] = {
+static struct gpio_led gpio_leds[] = {
        {
                .name = "magician::vibra",
                .default_trigger = "none",
@@ -396,7 +430,7 @@ struct gpio_led gpio_leds[] = {
        },
        {
                .name = "magician::phone_bl",
-               .default_trigger = "none",
+               .default_trigger = "backlight",
                .gpio = GPIO103_MAGICIAN_LED_KP,
        },
 };
@@ -444,9 +478,7 @@ static struct pasic3_led pasic3_leds[] = {
        },
 };
 
-static struct platform_device pasic3;
-
-static struct pasic3_leds_machinfo __devinit pasic3_leds_info = {
+static struct pasic3_leds_machinfo pasic3_leds_info = {
        .num_leds   = ARRAY_SIZE(pasic3_leds),
        .power_gpio = EGPIO_MAGICIAN_LED_POWER,
        .leds       = pasic3_leds,
@@ -471,7 +503,6 @@ static struct resource pasic3_resources[] = {
 };
 
 static struct pasic3_platform_data pasic3_platform_data = {
-       .bus_shift  = 2,
        .led_pdata  = &pasic3_leds_info,
        .clock_rate = 4000000,
 };
@@ -487,23 +518,47 @@ static struct platform_device pasic3 = {
 };
 
 /*
+ * USB "Transceiver"
+ */
+
+static struct resource gpio_vbus_resource = {
+       .flags = IORESOURCE_IRQ,
+       .start = IRQ_MAGICIAN_VBUS,
+       .end   = IRQ_MAGICIAN_VBUS,
+};
+
+static struct gpio_vbus_mach_info gpio_vbus_info = {
+       .gpio_pullup = GPIO27_MAGICIAN_USBC_PUEN,
+       .gpio_vbus   = EGPIO_MAGICIAN_CABLE_STATE_USB,
+};
+
+static struct platform_device gpio_vbus = {
+       .name          = "gpio-vbus",
+       .id            = -1,
+       .num_resources = 1,
+       .resource      = &gpio_vbus_resource,
+       .dev = {
+               .platform_data = &gpio_vbus_info,
+       },
+};
+
+/*
  * External power
  */
 
-static int magician_is_ac_online(void)
+static int power_supply_init(struct device *dev)
 {
-       return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_AC);
+       return gpio_request(EGPIO_MAGICIAN_CABLE_STATE_AC, "CABLE_STATE_AC");
 }
 
-static int magician_is_usb_online(void)
+static int magician_is_ac_online(void)
 {
-       return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_USB);
+       return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_AC);
 }
 
-static void magician_set_charge(int flags)
+static void power_supply_exit(struct device *dev)
 {
-       gpio_set_value(GPIO30_MAGICIAN_nCHARGE_EN, !flags);
-       gpio_set_value(EGPIO_MAGICIAN_CHARGE_EN, flags);
+       gpio_free(EGPIO_MAGICIAN_CABLE_STATE_AC);
 }
 
 static char *magician_supplicants[] = {
@@ -511,9 +566,9 @@ static char *magician_supplicants[] = {
 };
 
 static struct pda_power_pdata power_supply_info = {
+       .init            = power_supply_init,
        .is_ac_online    = magician_is_ac_online,
-       .is_usb_online   = magician_is_usb_online,
-       .set_charge      = magician_set_charge,
+       .exit            = power_supply_exit,
        .supplied_to     = magician_supplicants,
        .num_supplicants = ARRAY_SIZE(magician_supplicants),
 };
@@ -521,15 +576,17 @@ static struct pda_power_pdata power_supply_info = {
 static struct resource power_supply_resources[] = {
        [0] = {
                .name  = "ac",
-               .flags = IORESOURCE_IRQ,
-               .start = IRQ_MAGICIAN_AC,
-               .end   = IRQ_MAGICIAN_AC,
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
+                        IORESOURCE_IRQ_LOWEDGE,
+               .start = IRQ_MAGICIAN_VBUS,
+               .end   = IRQ_MAGICIAN_VBUS,
        },
        [1] = {
                .name  = "usb",
-               .flags = IORESOURCE_IRQ,
-               .start = IRQ_MAGICIAN_AC,
-               .end   = IRQ_MAGICIAN_AC,
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
+                        IORESOURCE_IRQ_LOWEDGE,
+               .start = IRQ_MAGICIAN_VBUS,
+               .end   = IRQ_MAGICIAN_VBUS,
        },
 };
 
@@ -543,63 +600,69 @@ static struct platform_device power_supply = {
        .num_resources = ARRAY_SIZE(power_supply_resources),
 };
 
-
 /*
- * MMC/SD
+ * Battery charger
  */
 
-static int magician_mci_init(struct device *dev,
-                               irq_handler_t detect_irq, void *data)
-{
-       int err;
-
-       err = request_irq(IRQ_MAGICIAN_SD, detect_irq,
-                               IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
-                               "MMC card detect", data);
-       if (err)
-               goto err_request_irq;
-       err = gpio_request(EGPIO_MAGICIAN_SD_POWER, "SD_POWER");
-       if (err)
-               goto err_request_power;
-       err = gpio_request(EGPIO_MAGICIAN_nSD_READONLY, "nSD_READONLY");
-       if (err)
-               goto err_request_readonly;
+static struct regulator_consumer_supply bq24022_consumers[] = {
+       {
+               .dev = &gpio_vbus.dev,
+               .supply = "vbus_draw",
+       },
+       {
+               .dev = &power_supply.dev,
+               .supply = "ac_draw",
+       },
+};
 
-       return 0;
+static struct regulator_init_data bq24022_init_data = {
+       .constraints = {
+               .max_uA         = 500000,
+               .valid_ops_mask = REGULATOR_CHANGE_CURRENT,
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(bq24022_consumers),
+       .consumer_supplies      = bq24022_consumers,
+};
 
-err_request_readonly:
-       gpio_free(EGPIO_MAGICIAN_SD_POWER);
-err_request_power:
-       free_irq(IRQ_MAGICIAN_SD, data);
-err_request_irq:
-       return err;
-}
+static struct bq24022_mach_info bq24022_info = {
+       .gpio_nce   = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,
+       .gpio_iset2 = EGPIO_MAGICIAN_BQ24022_ISET2,
+       .init_data  = &bq24022_init_data,
+};
 
-static void magician_mci_setpower(struct device *dev, unsigned int vdd)
-{
-       struct pxamci_platform_data *pdata = dev->platform_data;
+static struct platform_device bq24022 = {
+       .name = "bq24022",
+       .id   = -1,
+       .dev  = {
+               .platform_data = &bq24022_info,
+       },
+};
 
-       gpio_set_value(EGPIO_MAGICIAN_SD_POWER, (1 << vdd) & pdata->ocr_mask);
-}
+/*
+ * MMC/SD
+ */
 
-static int magician_mci_get_ro(struct device *dev)
+static int magician_mci_init(struct device *dev,
+                               irq_handler_t detect_irq, void *data)
 {
-       return (!gpio_get_value(EGPIO_MAGICIAN_nSD_READONLY));
+       return request_irq(IRQ_MAGICIAN_SD, detect_irq,
+                               IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
+                               "mmc card detect", data);
 }
 
 static void magician_mci_exit(struct device *dev, void *data)
 {
-       gpio_free(EGPIO_MAGICIAN_nSD_READONLY);
-       gpio_free(EGPIO_MAGICIAN_SD_POWER);
        free_irq(IRQ_MAGICIAN_SD, data);
 }
 
 static struct pxamci_platform_data magician_mci_info = {
-       .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
-       .init     = magician_mci_init,
-       .get_ro   = magician_mci_get_ro,
-       .setpower = magician_mci_setpower,
-       .exit     = magician_mci_exit,
+       .ocr_mask               = MMC_VDD_32_33|MMC_VDD_33_34,
+       .init                   = magician_mci_init,
+       .exit                   = magician_mci_exit,
+       .gpio_card_detect       = -1,
+       .gpio_card_ro           = EGPIO_MAGICIAN_nSD_READONLY,
+       .gpio_card_ro_invert    = 1,
+       .gpio_power             = EGPIO_MAGICIAN_SD_POWER,
 };
 
 
@@ -607,18 +670,10 @@ static struct pxamci_platform_data magician_mci_info = {
  * USB OHCI
  */
 
-static int magician_ohci_init(struct device *dev)
-{
-       UHCHR = (UHCHR | UHCHR_SSEP2 | UHCHR_PCPL | UHCHR_CGR) &
-           ~(UHCHR_SSEP1 | UHCHR_SSEP3 | UHCHR_SSE);
-
-       return 0;
-}
-
 static struct pxaohci_platform_data magician_ohci_info = {
-       .port_mode    = PMM_PERPORT_MODE,
-       .init         = magician_ohci_init,
-       .power_budget = 0,
+       .port_mode      = PMM_PERPORT_MODE,
+       .flags          = ENABLE_PORT1 | ENABLE_PORT3 | POWER_CONTROL_LOW,
+       .power_budget   = 0,
 };
 
 
@@ -631,11 +686,9 @@ static void magician_set_vpp(struct map_info *map, int vpp)
        gpio_set_value(EGPIO_MAGICIAN_FLASH_VPP, vpp);
 }
 
-#define PXA_CS_SIZE            0x04000000
-
 static struct resource strataflash_resource = {
        .start = PXA_CS0_PHYS,
-       .end   = PXA_CS0_PHYS + PXA_CS_SIZE - 1,
+       .end   = PXA_CS0_PHYS + SZ_64M - 1,
        .flags = IORESOURCE_MEM,
 };
 
@@ -655,6 +708,14 @@ static struct platform_device strataflash = {
 };
 
 /*
+ * I2C
+ */
+
+static struct i2c_pxa_platform_data i2c_info = {
+       .fast_mode = 1,
+};
+
+/*
  * Platform devices
  */
 
@@ -663,6 +724,8 @@ static struct platform_device *devices[] __initdata = {
        &egpio,
        &backlight,
        &pasic3,
+       &bq24022,
+       &gpio_vbus,
        &power_supply,
        &strataflash,
        &leds_gpio,
@@ -679,14 +742,19 @@ static void __init magician_init(void)
 
        pxa2xx_mfp_config(ARRAY_AND_SIZE(magician_pin_config));
 
-       platform_add_devices(devices, ARRAY_SIZE(devices));
+       pxa_set_ffuart_info(NULL);
+       pxa_set_btuart_info(NULL);
+       pxa_set_stuart_info(NULL);
+
+       platform_add_devices(ARRAY_AND_SIZE(devices));
 
        err = gpio_request(GPIO83_MAGICIAN_nIR_EN, "nIR_EN");
        if (!err) {
                gpio_direction_output(GPIO83_MAGICIAN_nIR_EN, 1);
                pxa_set_ficp_info(&magician_ficp_info);
        }
-       pxa_set_i2c_info(NULL);
+       pxa27x_set_i2c_power_info(NULL);
+       pxa_set_i2c_info(&i2c_info);
        pxa_set_mci_info(&magician_mci_info);
        pxa_set_ohci_info(&magician_ohci_info);