Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394...
[pandora-kernel.git] / arch / arm / mach-pxa / magician.c
index d70be75..01b2fa7 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/mtd/map.h>
 #include <linux/mtd/physmap.h>
 #include <linux/pda_power.h>
+#include <linux/pwm_backlight.h>
 
 #include <asm/gpio.h>
 #include <asm/hardware.h>
 #include <asm/arch/magician.h>
 #include <asm/arch/mfp-pxa27x.h>
 #include <asm/arch/pxa-regs.h>
+#include <asm/arch/pxa2xx-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 "devices.h"
 #include "generic.h"
 
 static unsigned long magician_pin_config[] = {
@@ -114,6 +117,14 @@ static unsigned long magician_pin_config[] = {
        GPIO82_CIF_DD_5,
        GPIO84_CIF_FV,
        GPIO85_CIF_LV,
+
+       /* Magician specific input GPIOs */
+       GPIO9_GPIO,     /* unknown */
+       GPIO10_GPIO,    /* GSM_IRQ */
+       GPIO13_GPIO,    /* CPLD_IRQ */
+       GPIO107_GPIO,   /* DS1WM_IRQ */
+       GPIO108_GPIO,   /* GSM_READY */
+       GPIO115_GPIO,   /* nPEN_IRQ */
 };
 
 /*
@@ -340,40 +351,58 @@ 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(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",
        .dev  = {
-               .platform_data = &backlight_info,
+               .parent        = &pxa27x_device_pwm0.dev,
+               .platform_data = &backlight_data,
        },
-       .id   = -1,
 };
 
 /*
@@ -438,7 +467,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,
@@ -543,9 +572,28 @@ static struct platform_device power_supply = {
 static int magician_mci_init(struct device *dev,
                                irq_handler_t detect_irq, void *data)
 {
-       return request_irq(IRQ_MAGICIAN_SD, detect_irq,
+       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;
+
+       return 0;
+
+err_request_readonly:
+       gpio_free(EGPIO_MAGICIAN_SD_POWER);
+err_request_power:
+       free_irq(IRQ_MAGICIAN_SD, data);
+err_request_irq:
+       return err;
 }
 
 static void magician_mci_setpower(struct device *dev, unsigned int vdd)
@@ -562,6 +610,8 @@ static int magician_mci_get_ro(struct device *dev)
 
 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);
 }
 
@@ -643,28 +693,42 @@ static void __init magician_init(void)
 {
        void __iomem *cpld;
        int lcd_select;
+       int err;
+
+       gpio_request(GPIO13_MAGICIAN_CPLD_IRQ, "CPLD_IRQ");
+       gpio_request(GPIO107_MAGICIAN_DS1WM_IRQ, "DS1WM_IRQ");
 
        pxa2xx_mfp_config(ARRAY_AND_SIZE(magician_pin_config));
 
        platform_add_devices(devices, ARRAY_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);
        pxa_set_mci_info(&magician_mci_info);
        pxa_set_ohci_info(&magician_ohci_info);
-       pxa_set_ficp_info(&magician_ficp_info);
 
        /* Check LCD type we have */
        cpld = ioremap_nocache(PXA_CS3_PHYS, 0x1000);
        if (cpld) {
                u8 board_id = __raw_readb(cpld+0x14);
+               iounmap(cpld);
                system_rev = board_id & 0x7;
                lcd_select = board_id & 0x8;
-               iounmap(cpld);
                pr_info("LCD type: %s\n", lcd_select ? "Samsung" : "Toppoly");
-               if (lcd_select && (system_rev < 3))
-                       pxa_gpio_mode(GPIO75_MAGICIAN_SAMSUNG_POWER_MD);
-               pxa_gpio_mode(GPIO104_MAGICIAN_LCD_POWER_1_MD);
-               pxa_gpio_mode(GPIO105_MAGICIAN_LCD_POWER_2_MD);
-               pxa_gpio_mode(GPIO106_MAGICIAN_LCD_POWER_3_MD);
+               if (lcd_select && (system_rev < 3)) {
+                       gpio_request(GPIO75_MAGICIAN_SAMSUNG_POWER, "SAMSUNG_POWER");
+                       gpio_direction_output(GPIO75_MAGICIAN_SAMSUNG_POWER, 0);
+               }
+               gpio_request(GPIO104_MAGICIAN_LCD_POWER_1, "LCD_POWER_1");
+               gpio_request(GPIO105_MAGICIAN_LCD_POWER_2, "LCD_POWER_2");
+               gpio_request(GPIO106_MAGICIAN_LCD_POWER_3, "LCD_POWER_3");
+               gpio_direction_output(GPIO104_MAGICIAN_LCD_POWER_1, 0);
+               gpio_direction_output(GPIO105_MAGICIAN_LCD_POWER_2, 0);
+               gpio_direction_output(GPIO106_MAGICIAN_LCD_POWER_3, 0);
                set_pxa_fb_info(lcd_select ? &samsung_info : &toppoly_info);
        } else
                pr_err("LCD detection: CPLD mapping failed\n");