#include "bu92747guw_cir.h"
-#if 0
+#if 1
#define BU92747_DBG(x...) printk(x)
#else
#define BU92747_DBG(x...)
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;
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)
{
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__);
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;
return;
}
+
static irqreturn_t bu92747_cir_irq(int irq, void *dev_id)
{
// u8 reg_value[2];
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;
}
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;
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;
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__);
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);
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
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
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);
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;
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) {
}
// 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,
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;
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);
.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)