firmware: rockchip: update sip interface
[firefly-linux-kernel-4.4.55.git] / drivers / cir / bu92747guw_cir.c
old mode 100755 (executable)
new mode 100644 (file)
index 2ffffc7..5362add
@@ -34,7 +34,7 @@
 
 #include "bu92747guw_cir.h"
 
-#if 0
+#if 1
 #define BU92747_DBG(x...) printk(x)
 #else
 #define BU92747_DBG(x...)
@@ -52,9 +52,6 @@ struct bu92747_data_info {
        int base_clock;
        int sys_clock;
        struct delayed_work      dwork;
-       u8 inv;
-       u16 head_space_time;
-       u16 head_burst_time;
 };
 
 static struct miscdevice bu92747guw_device;
@@ -62,19 +59,19 @@ static struct miscdevice bu92747guw_device;
 int repeat_flag=-1;
 int start_flag = 0;
 //mutex lock between remote and irda
-static DEFINE_MUTEX(bu92747_mutex);
-void bu92747_lock(void)
-{
-       mutex_lock(&bu92747_mutex);
-}
-void bu92747_unlock(void)
-{
-       mutex_unlock(&bu92747_mutex);
-}
 
 
 
 
+#ifdef CONFIG_RK_IRDA_UART
+extern int bu92747_try_lock(void);
+extern void bu92747_unlock(void);
+#else
+int bu92747_try_lock(void) {return 1;}
+void bu92747_unlock(void) {return;}
+#endif
+
+
 
 static int bu92747_cir_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf, int len)
 {
@@ -103,7 +100,7 @@ static int bu92747_stop(struct i2c_client *client)
        reg_value[0] = reg_value[0]&0xfe;
        reg_value[1] = reg_value[1]&0xf1;
        bu92747_cir_i2c_set_regs(client, REG_SETTING0, reg_value, 2);
-       
+       start_flag = 0;
        repeat_flag = -1;
        BU92747_DBG("line %d: exit %s\n", __LINE__, __FUNCTION__);
 
@@ -117,13 +114,12 @@ static void bu92747_dwork_handler(struct work_struct *work)
        
        BU92747_DBG("------- sss  enter %s\n", __func__);
 
-       if ( !start_flag && (repeat_flag <= -1)){
+       if  ((repeat_flag != -10) && (repeat_flag <= -1)){
                bu92747_stop(bu92747->client);
                BU92747_DBG("----------exit %s\n", __func__);
                return ;
        }
 
-       start_flag = 0;
        //set repeat=0
        bu92747_cir_i2c_read_regs(bu92747->client, REG_SETTING1, reg_value, 1);
        reg_value[0] &= 0xf0;
@@ -143,6 +139,7 @@ static void bu92747_dwork_handler(struct work_struct *work)
        return;
 }
 
+
 static irqreturn_t bu92747_cir_irq(int irq, void *dev_id)
 {
 //     u8 reg_value[2];
@@ -150,12 +147,18 @@ static irqreturn_t bu92747_cir_irq(int irq, void *dev_id)
        struct bu92747_data_info *bu92747 = (struct bu92747_data_info *)i2c_get_clientdata(client);
 
        BU92747_DBG("----------enter %s  repeat_flag = %d\n", __func__, repeat_flag);
-       
 
-       if (((--repeat_flag%16) == 0) || (repeat_flag < 0)){
-               schedule_delayed_work(&bu92747->dwork, msecs_to_jiffies(0));
-       }
 
+       if (start_flag == 1){
+               if (repeat_flag == -10){
+                       if ((bu92747->state++)%10 == 0){
+                               schedule_delayed_work(&bu92747->dwork, msecs_to_jiffies(0));
+                               bu92747->state = 0;
+                       } 
+               }else if (((--repeat_flag%16) == 0) || (repeat_flag < 0)){
+                       schedule_delayed_work(&bu92747->dwork, msecs_to_jiffies(0));
+               }
+       }
        return IRQ_HANDLED;
 }
 
@@ -277,7 +280,10 @@ static int bu92747_set_format(struct i2c_client *client, struct rk29_cir_struct_
        repeat_flag = cir->repeat;
        printk("repeat 11111 =%d\n", repeat_flag);
        
-       if (repeat_flag > 16){
+       if (repeat_flag == -1){
+               repeat_flag = -10;
+               repeat = 0;             
+       }else if (repeat_flag > 16){
                repeat = 16; 
        }else{
                repeat = repeat_flag;
@@ -307,8 +313,7 @@ static int bu92747_set_format(struct i2c_client *client, struct rk29_cir_struct_
        reg_value[9] = hhi>>8;
        reg_value[10] = hhi&0xff;
        BU92747_DBG("hlo = 0x%x, hhi = 0x%x\n", hlo, hhi);
-       bu92747->head_space_time = cir->head_space_time;
-       bu92747->head_burst_time = cir->head_burst_time;
+
 
        //data0
        d0lo = (cir->logic_low_space_time*sys_clock)/1000;
@@ -357,7 +362,7 @@ static int bu92747_set_format(struct i2c_client *client, struct rk29_cir_struct_
                BU92747_DBG("reg_value[%d] = %d\n", 24+i, reg_value[24+i]);
        }
 
-       bu92747_cir_i2c_set_regs(client, REG_SETTING0, reg_value, 23+i);
+       bu92747_cir_i2c_set_regs(client, REG_SETTING0, reg_value, 24+i);
        
 
        BU92747_DBG("line %d: exit %s\n", __LINE__, __FUNCTION__);
@@ -375,8 +380,7 @@ static int bu92747_start(struct i2c_client *client)
 
 
        start_flag = 1;
-       //enable_irq(bu92747->irq);
-       //enable clk
+       bu92747->state = 0;
        bu92747_cir_i2c_read_regs(client, REG_SETTING0, reg_value, 1);
        reg_value[0] = reg_value[0]|0x01;
        bu92747_cir_i2c_set_regs(client, REG_SETTING0, reg_value, 1);
@@ -496,7 +500,7 @@ static int bu92747_set_pulse(struct i2c_client *client, struct rk29_cir_struct_i
        reg_value[0] = reg_value[0] | (inv0<<1) | (inv1<<2);
        bu92747_cir_i2c_set_regs(client, REG_SETTING0, reg_value, 1);
        BU92747_DBG("inv0 = %d, inv1 = %d\n", inv0, inv1);
-       bu92747->inv = cir->inv;
+
 
 
        //data0
@@ -548,8 +552,6 @@ static int bu92747_set_parameter(struct i2c_client *client, struct rk29_cir_stru
        reg_value[2] = hhi>>8;
        reg_value[3] = hhi&0xff;
        BU92747_DBG("hlo = 0x%x, hhi = 0x%x\n", hlo, hhi);
-       bu92747->head_space_time = cir->head_space_time;
-       bu92747->head_burst_time = cir->head_burst_time;
        bu92747_cir_i2c_set_regs(client, REG_HLO1, reg_value, 4);
 
        //end
@@ -575,15 +577,20 @@ static int bu92747_set_repeat(struct i2c_client *client, struct rk29_cir_struct_
 
        BU92747_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
 
-       repeat_flag = cir->repeat;
+
+    repeat_flag = cir->repeat;
        printk("repeat 11111 =%d\n", repeat_flag);
        
-       if (repeat_flag > 16){
+       if (repeat_flag == -1){
+               repeat_flag = -10;
+               repeat = 0;             
+       }else if (repeat_flag > 16){
                repeat = 16; 
        }else{
                repeat = repeat_flag;
        }
 
+
        repeat = repeat % 16;
        
        bu92747_cir_i2c_read_regs(client, REG_SETTING1, reg_value, 1);
@@ -746,10 +753,21 @@ static int bu92747_open(struct inode *inode, struct file *file)
        struct i2c_client *client = container_of(bu92747guw_device.parent, struct i2c_client, dev);
        struct bu92747_data_info *bu92747 = (struct bu92747_data_info *)i2c_get_clientdata(client);
        struct bu92747guw_platform_data *pdata = bu92747->platdata;
-
+       int ret = 0;
        BU92747_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
 
        printk("bu92747_open\n");
+
+
+       ret = bu92747_try_lock();
+       if (ret == 0){
+               printk("cannot get lock. Please close irda!\n");
+               return -2;
+       }
+       
+       bu92747->state = 0;
+       start_flag = 0;
+       repeat_flag = -1;
 //     if (BU92747_OPEN == bu92747->state) 
 //             return -EBUSY;
 //     bu92747->state = BU92747_OPEN;
@@ -780,6 +798,8 @@ static int bu92747_release(struct inode *inode, struct file *file)
        struct bu92747guw_platform_data *pdata = bu92747->platdata;
 
        BU92747_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
+       smc0_write(REG_TRCR_ADDR, smc0_read(REG_TRCR_ADDR)|0x0040);
+       start_flag = -1;
 
        //power down
        if (pdata && pdata->cir_pwr_ctl) {
@@ -787,11 +807,76 @@ static int bu92747_release(struct inode *inode, struct file *file)
        }
        
 //     bu92747->state = BU92747_CLOSE;
+       bu92747_unlock();
+
+       BU92747_DBG("line %d: exit %s\n", __LINE__, __FUNCTION__);
+       
+       return 0;
+}
 
+#if  CONFIG_PM
+static int bu92747_suspend(struct i2c_client *i, pm_message_t mesg)
+{
+       struct i2c_client *client = container_of(bu92747guw_device.parent, struct i2c_client, dev);
+       struct bu92747_data_info *bu92747 = (struct bu92747_data_info *)i2c_get_clientdata(client);
+       struct bu92747guw_platform_data *pdata = bu92747->platdata;
+
+       BU92747_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
+
+       if (start_flag == 0){
+               BU92747_DBG("realy suspend!\n");
+               disable_irq(bu92747->irq);
+               smc0_write(REG_TRCR_ADDR, smc0_read(REG_TRCR_ADDR)|0x0040);
+               start_flag = 0;
+               repeat_flag = -1;
+               
+               if (pdata && pdata->cir_pwr_ctl) {
+                       pdata->cir_pwr_ctl(0);
+               }
+       }
        BU92747_DBG("line %d: exit %s\n", __LINE__, __FUNCTION__);
+
+       return 0;
+}
+
+static int bu92747_resume(struct i2c_client *i)
+{
+       struct i2c_client *client = container_of(bu92747guw_device.parent, struct i2c_client, dev);
+       struct bu92747_data_info *bu92747 = (struct bu92747_data_info *)i2c_get_clientdata(client);
+       struct bu92747guw_platform_data *pdata = bu92747->platdata;
+       
+       BU92747_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
+
+       if (start_flag == 0){
+               BU92747_DBG("realy resume!\n");
+               enable_irq(bu92747->irq);
+               bu92747->state = 0;
+
+               //power on
+               if (pdata && pdata->cir_pwr_ctl) {
+                       pdata->cir_pwr_ctl(1);
+               }
+                       
+               //switch to remote control, mcr, ec_en=1,rc_mode=1
+               smc0_write(REG_MCR_ADDR, smc0_read(REG_MCR_ADDR)|(3<<10));
+               //set irda pwdownpin = 0
+               smc0_write(REG_TRCR_ADDR, smc0_read(REG_TRCR_ADDR)&0xffbf);
+               BU92747_DBG("irda power down pin = %d\n", gpio_get_value(RK29_PIN5_PA7));
+
+               //register init
+               bu92747_cir_init_device(client, bu92747);
+       }
        
+       printk("line %d: exit %s\n", __LINE__, __FUNCTION__);
+
+
        return 0;
+       
 }
+#else
+#define bu92747_suspend NULL
+#define bu92747_resume NULL
+#endif
 
 static struct file_operations bu92747_fops = {
        .owner = THIS_MODULE,
@@ -832,7 +917,8 @@ static int __devinit bu92747_cir_probe(struct i2c_client *client, const struct i
        bu92747->platdata = pdata;
        bu92747->client = client;
        i2c_set_clientdata(client, bu92747);
-       bu92747->state = BU92747_CLOSE;
+       bu92747->state = 0;
+       start_flag = -1;
 
        //register device
        bu92747guw_device.parent = &client->dev;
@@ -900,7 +986,7 @@ static int __devexit bu92747_cir_remove(struct i2c_client *client)
        struct bu92747guw_platform_data *pdata = bu92747->platdata;
 
        printk(" cir_remove \n");
-       start_flag = 0;
+       start_flag = -1;
        free_irq(bu92747->irq, bu92747);
        gpio_free(pdata->intr_pin);
     misc_deregister(&bu92747guw_device);
@@ -924,6 +1010,10 @@ static struct i2c_driver bu92747_cir_driver = {
        .probe          = bu92747_cir_probe,
        .remove         = __devexit_p(bu92747_cir_remove),
        .id_table       = bu92747_cir_id,
+#ifdef CONFIG_PM
+       .suspend = bu92747_suspend,
+       .resume = bu92747_resume,
+#endif
 };
 
 static int __init bu92747_cir_init(void)