add timed gpio support for A22
authorluowei <lw@rock-chips.com>
Tue, 19 Apr 2011 06:04:03 +0000 (14:04 +0800)
committerluowei <lw@rock-chips.com>
Tue, 19 Apr 2011 06:04:03 +0000 (14:04 +0800)
arch/arm/mach-rk29/board-rk29-a22.c
drivers/staging/android/timed_gpio.c [changed mode: 0644->0755]
drivers/staging/android/timed_gpio.h

index 6c15a30e7e156b362a8dc4d23c156536b98013e2..449a103e24e6912011801f3c84a3883e2bb5b0fe 100755 (executable)
@@ -62,6 +62,7 @@
 #endif
 
 #include "../../../drivers/headset_observe/rk_headset.h"
+#include "../../../drivers/staging/android/timed_gpio.h"
 /*set touchscreen different type header*/
 #if defined(CONFIG_TOUCHSCREEN_XPT2046_NORMAL_SPI)
 #include "../../../drivers/input/touchscreen/xpt2046_ts.h"
@@ -2487,8 +2488,37 @@ static struct platform_device rk29_device_keys = {
 };
 #endif
 
+#if CONFIG_ANDROID_TIMED_GPIO
+static struct timed_gpio timed_gpios[] = {
+       {
+               .name = "vibrator",
+               .gpio = RK29_PIN1_PB5,
+               .max_timeout = 1000,
+               .active_low = 0,
+               .adjust_time =20,      //adjust for diff product
+       },
+};
+
+struct timed_gpio_platform_data rk29_vibrator_info = {
+       .num_gpios = 1,
+       .gpios = timed_gpios,
+};
+
+struct platform_device rk29_device_vibrator ={
+       .name = "timed-gpio",
+       .id = -1,
+       .dev = {
+               .platform_data = &rk29_vibrator_info,
+               },
+
+};
+#endif 
+
 static void __init rk29_board_iomux_init(void)
 {
+       #if CONFIG_ANDROID_TIMED_GPIO
+       rk29_mux_api_set(GPIO1B5_PWM0_NAME, GPIO1L_GPIO1B5);//for timed gpio
+       #endif
        #ifdef CONFIG_RK29_PWM_REGULATOR
        rk29_mux_api_set(REGULATOR_PWM_MUX_NAME,REGULATOR_PWM_MUX_MODE);
        #endif
@@ -2618,6 +2648,9 @@ static struct platform_device *devices[] __initdata = {
 #ifdef CONFIG_RK29_GPS
        &rk29_device_gps,
 #endif
+#ifdef CONFIG_ANDROID_TIMED_GPIO
+       &rk29_device_vibrator,
+#endif
 };
 
 #ifdef CONFIG_RK29_VMAC
old mode 100644 (file)
new mode 100755 (executable)
index 15aee91..bb6c212
 #include <linux/hrtimer.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
-
+#include <linux/wakelock.h>
+#include <linux/delay.h>
 #include "timed_output.h"
 #include "timed_gpio.h"
 
-#if defined(CONFIG_MACH_RAHO)||defined(CONFIG_MACH_RAHOSDK)
-#define GPIO_TYPE   1       //ʹÓÃFPGAÀ©Õ¹µÄIO²»ÄÜʹÓÃÖжÏÄÚ²¿Ö±½Ó²Ù×÷IO
-#else
-#define GPIO_TYPE   0
-#endif
+#define GPIO_TYPE   0 
 
 struct timed_gpio_data {
        struct timed_output_dev dev;
@@ -36,17 +33,27 @@ struct timed_gpio_data {
        unsigned        gpio;
        int             max_timeout;
        u8              active_low;
+       int             adjust_time;
 #if (GPIO_TYPE == 1)
        struct work_struct      timed_gpio_work;        
 #endif
+       struct wake_lock        irq_wake;
 };
 
 #if (GPIO_TYPE == 1)
 static void timed_gpio_work_handler(struct work_struct *work)
 {
-    struct timed_gpio_data *data =
+       struct timed_gpio_data *data =
                container_of(work, struct timed_gpio_data, timed_gpio_work);
-    gpio_direction_output(data->gpio, data->active_low ? 1 : 0);
+       int ret = 0,i = 0;
+       //set gpio several times once error happened
+       for(i=0; i<3; i++)
+       {
+               ret = gpio_direction_output(data->gpio, data->active_low ? 1 : 0);
+               if(!ret)                
+                       break;
+               printk("%s:ret=%d,fail to set gpio and set again,i=%d\n",__FUNCTION__,ret,i);
+       }
 }
 #endif
 
@@ -80,23 +87,26 @@ static void gpio_enable(struct timed_output_dev *dev, int value)
 {
        struct timed_gpio_data  *data =
                container_of(dev, struct timed_gpio_data, dev);
-       //unsigned long flags;
-       //spin_lock_irqsave(&data->lock, flags);
+       int ret = 0,i = 0;
 
        /* cancel previous timer and set GPIO according to value */
        hrtimer_cancel(&data->timer);
-       gpio_direction_output(data->gpio, data->active_low ? !value : !!value);
-
+       //set gpio several times once error happened
+       for(i=0; i<3; i++)
+       {
+               ret = gpio_direction_output(data->gpio, data->active_low ? !value : !!value);
+               if(!ret)                
+                       break;
+               printk("%s:ret=%d,fail to set gpio and set again,i=%d\n",__FUNCTION__,ret,i);
+       }
        if (value > 0) {
+               value += data->adjust_time;
                if (value > data->max_timeout)
                        value = data->max_timeout;
-
                hrtimer_start(&data->timer,
                        ktime_set(value / 1000, (value % 1000) * 1000000),
                        HRTIMER_MODE_REL);
        }
-
-       //spin_unlock_irqrestore(&data->lock, flags);
 }
 
 static int timed_gpio_probe(struct platform_device *pdev)
@@ -144,12 +154,17 @@ static int timed_gpio_probe(struct platform_device *pdev)
                gpio_dat->gpio = cur_gpio->gpio;
                gpio_dat->max_timeout = cur_gpio->max_timeout;
                gpio_dat->active_low = cur_gpio->active_low;
+               gpio_dat->adjust_time = cur_gpio->adjust_time;
                gpio_direction_output(gpio_dat->gpio, gpio_dat->active_low);
        }
 #if (GPIO_TYPE == 1)
     INIT_WORK(&gpio_dat->timed_gpio_work, timed_gpio_work_handler);
 #endif    
        platform_set_drvdata(pdev, gpio_data);
+       wake_lock_init(&gpio_data->irq_wake, WAKE_LOCK_SUSPEND, "timed_gpio_wake");
+
+       gpio_enable(&gpio_data ->dev, 100);
+       printk("%s\n",__FUNCTION__);
 
        return 0;
 }
@@ -189,7 +204,7 @@ static void __exit timed_gpio_exit(void)
        platform_driver_unregister(&timed_gpio_driver);
 }
 
-module_init(timed_gpio_init);
+subsys_initcall(timed_gpio_init);
 module_exit(timed_gpio_exit);
 
 MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>");
index a0e15f8be3f717e5aa8c6bb462ef3710b75bbba3..c8487df9a109142f7a9052c123b3243776814ded 100644 (file)
@@ -23,6 +23,7 @@ struct timed_gpio {
        unsigned        gpio;
        int             max_timeout;
        u8              active_low;
+       int         adjust_time;
 };
 
 struct timed_gpio_platform_data {