Merge branch 'develop' of 10.10.10.29:/home/rockchip/kernel into develop
[firefly-linux-kernel-4.4.55.git] / drivers / cir / bu92747guw_cir.c
1 /*drivers/cir/bu92747guw_cir.c - driver for bu92747guw
2  *
3  * Copyright (C) 2010 ROCKCHIP, Inc.
4  *
5  * This software is licensed under the terms of the GNU General Public
6  * License version 2, as published by the Free Software Foundation, and
7  * may be copied, distributed, and modified under those terms.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14 #include <linux/interrupt.h>
15 #include <linux/slab.h>
16 #include <linux/irq.h>
17 #include <linux/gpio.h>
18 #include <asm/uaccess.h>
19 #include <linux/workqueue.h>
20 #include <linux/module.h>
21 #include <linux/i2c.h>
22 #include <linux/platform_device.h>
23 #include <linux/types.h>
24 #include <linux/bcd.h>
25 #include <linux/spinlock.h>
26 #include <linux/fs.h>
27 #include <linux/delay.h>
28 #include <linux/wakelock.h>
29 #include <linux/miscdevice.h>
30 #include <linux/freezer.h>
31 #include <mach/gpio.h>
32 #include <mach/iomux.h>
33 #include <mach/rk29_smc.h>
34
35 #include "bu92747guw_cir.h"
36
37 #if 0
38 #define BU92747_DBG(x...) printk(x)
39 #else
40 #define BU92747_DBG(x...)
41 #endif
42
43 #define CIR_IIC_SPEED   100 * 1000
44
45 #define XIN_INPUT_FREQ 48*1000 //KHz
46
47 struct bu92747_data_info {
48         struct bu92747guw_platform_data *platdata;
49         struct i2c_client *client;
50         char state;
51         int irq;
52         int base_clock;
53         int sys_clock;
54         struct delayed_work      dwork;
55 };
56
57 static struct miscdevice bu92747guw_device;
58
59 int repeat_flag=-1;
60 int start_flag = 0;
61 //mutex lock between remote and irda
62 static DEFINE_MUTEX(bu92747_mutex);
63 void bu92747_lock(void)
64 {
65         mutex_lock(&bu92747_mutex);
66 }
67 void bu92747_unlock(void)
68 {
69         mutex_unlock(&bu92747_mutex);
70 }
71
72
73
74
75
76 static int bu92747_cir_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf, int len)
77 {
78         int ret; 
79         ret = i2c_master_reg8_recv(client, reg, buf, len, CIR_IIC_SPEED);
80         return ret; 
81 }
82
83 static int bu92747_cir_i2c_set_regs(struct i2c_client *client, u8 reg, u8 *buf, int len)
84 {
85         int ret; 
86         ret = i2c_master_reg8_send(client, reg, buf, len, CIR_IIC_SPEED);
87         return ret;
88 }
89
90
91 static int bu92747_stop(struct i2c_client *client) 
92 {
93         u8 reg_value[2];
94         struct bu92747_data_info *bu92747 = (struct bu92747_data_info *)i2c_get_clientdata(client);
95         //BU92747_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
96         printk("line %d: enter %s\n", __LINE__, __FUNCTION__);
97 //      disable_irq(bu92747->irq);
98         //diable clk, repeat=1
99         bu92747_cir_i2c_read_regs(client, REG_SETTING0, reg_value, 2);
100         reg_value[0] = reg_value[0]&0xfe;
101         reg_value[1] = reg_value[1]&0xf1;
102         bu92747_cir_i2c_set_regs(client, REG_SETTING0, reg_value, 2);
103         start_flag = 0;
104         repeat_flag = -1;
105         BU92747_DBG("line %d: exit %s\n", __LINE__, __FUNCTION__);
106
107         return 0;
108 }
109 static void bu92747_dwork_handler(struct work_struct *work)
110 {
111         struct bu92747_data_info *bu92747 = 
112                 (struct bu92747_data_info *)container_of(work, struct bu92747_data_info, dwork.work);
113         u8 reg_value[2];
114         
115         BU92747_DBG("------- sss  enter %s\n", __func__);
116
117         if  ((repeat_flag != -10) && (repeat_flag <= -1)){
118                 bu92747_stop(bu92747->client);
119                 BU92747_DBG("----------exit %s\n", __func__);
120                 return ;
121         }
122
123         //set repeat=0
124         bu92747_cir_i2c_read_regs(bu92747->client, REG_SETTING1, reg_value, 1);
125         reg_value[0] &= 0xf0;
126         bu92747_cir_i2c_set_regs(bu92747->client, REG_SETTING1, reg_value, 1);
127         //printk("----------exit %s  reg_value = %d\n", __func__, reg_value[1]);
128
129
130         reg_value[0] = 1;
131         
132         bu92747_cir_i2c_set_regs(bu92747->client, REG_SEND, reg_value, 1);
133 //      bu92747_cir_i2c_read_regs(bu92747->client, REG_FRMLEN1, reg_value, 2);
134
135 //      printk("frame_interval = 0x%x\n", reg_value[1], reg_value[2]);
136         //power down
137
138         BU92747_DBG("----------exit %s\n", __func__);
139         return;
140 }
141
142
143 static irqreturn_t bu92747_cir_irq(int irq, void *dev_id)
144 {
145 //      u8 reg_value[2];
146         struct i2c_client *client = container_of(bu92747guw_device.parent, struct i2c_client, dev);
147         struct bu92747_data_info *bu92747 = (struct bu92747_data_info *)i2c_get_clientdata(client);
148
149         BU92747_DBG("----------enter %s  repeat_flag = %d\n", __func__, repeat_flag);
150
151
152         if (start_flag == 1){
153                 if (repeat_flag == -10){
154                         if ((bu92747->state++)%10 == 0){
155                                 schedule_delayed_work(&bu92747->dwork, msecs_to_jiffies(0));
156                                 bu92747->state = 0;
157                         } 
158                 }else if (((--repeat_flag%16) == 0) || (repeat_flag < 0)){
159                         schedule_delayed_work(&bu92747->dwork, msecs_to_jiffies(0));
160                 }
161         }
162         return IRQ_HANDLED;
163 }
164
165
166
167 #if 0
168 static int bu92747_send_data(struct i2c_client *client, struct rk29_cir_struct_info *cir) 
169 {
170         u8 inv0,inv1;
171         unsigned int hlo, hhi;
172         u8 reg_value[16];
173         int i, nByte;
174         struct bu92747_data_info *bu92747 = (struct bu92747_data_info *)i2c_get_clientdata(client);
175         struct bu92747guw_platform_data *pdata = bu92747->platdata;
176         int sys_clock = bu92747->sys_clock;
177         unsigned long flags;
178
179         BU92747_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
180         //if (bu92747->state == BU92747_BUSY) {
181         //      printk("line %d, func: %s, dev is busy now\n", __LINE__, __func__);
182         //      return -EBUSY;
183         //}
184
185         //bu92747->state = BU92747_BUSY;
186
187         repeat_flag = cir->repeat%16;
188
189         bu92747_cir_i2c_read_regs(client, REG_SETTING0, reg_value, 2);
190         
191         inv0 = cir->inv & 0x01;
192         inv1 = (cir->inv>>1) & 0x01;
193         reg_value[0] = reg_value[0] | (inv0<<1) | (inv1<<2);
194         reg_value[1] = (reg_value[1]&0xf0) | (repeat_flag&0x0f);
195         bu92747_cir_i2c_set_regs(client, REG_SETTING0, reg_value, 2);
196         BU92747_DBG("inv0 = %d, inv1 = %d, repeat=%d\n", inv0, inv1, repeat_flag);
197         
198         //head maybe different while repeat
199         if ((bu92747->head_burst_time!=cir->head_burst_time) 
200                 || (bu92747->head_space_time!=cir->head_space_time)) {
201                 hlo = (cir->head_space_time*sys_clock)/1000;
202                 hhi = (cir->head_burst_time*sys_clock)/1000;
203                 reg_value[0] = hlo>>8;
204                 reg_value[1] = hlo&0xff;
205                 reg_value[2] = hhi>>8;
206                 reg_value[3] = hhi&0xff;        
207                 bu92747_cir_i2c_set_regs(client, REG_HLO1, reg_value, 4);
208                 BU92747_DBG("hlo = 0x%x, hhi = 0x%x\n", hlo, hhi);
209         }
210
211         //switch to remote control
212         //bu92747_lock();
213         
214         //data bit length
215         reg_value[0] = cir->frame_bit_len;
216         bu92747_cir_i2c_set_regs(client, REG_BITLEN, reg_value, 1);
217         BU92747_DBG("frame_bit_len = 0x%x\n", cir->frame_bit_len);
218         
219         //data
220         nByte = (cir->frame_bit_len+7)/8;
221         for (i=0; i<nByte; i++) {
222                 reg_value[i] = ((cir->frame)>>(8*i))&0xff;
223                 BU92747_DBG("reg_value[%d] = %d\n", i, reg_value[i]);
224         }
225         bu92747_cir_i2c_set_regs(client, REG_OUT0, reg_value, nByte);
226         BU92747_DBG("nByte = %d\n", nByte);
227         
228         //clear irq, start send
229         //reg_value[0] = 1;
230         //reg_value[1] = 1;
231         //bu92747_cir_i2c_set_regs(client, REG_IRQC, reg_value, 2);
232         
233         //send ok?
234 //      while (gpio_get_value(pdata->intr_pin)) {
235 //              BU92747_DBG("line %d: data register is not null\n", __LINE__);
236 //      }
237
238         //switch to irda control        
239         //smc0_write(3, smc0_read(3) & 0xfbff);
240         //bu92747_unlock();
241
242         //enable_irq(bu92747->irq);
243         
244         BU92747_DBG("line %d: exit %s\n", __LINE__, __FUNCTION__);
245         
246         return 0;
247 }
248 #endif
249
250
251
252 static int bu92747_set_format(struct i2c_client *client, struct rk29_cir_struct_info *cir) 
253 {
254         u8 inv0, inv1;
255         unsigned int clo, chi, clo_org, chi_org;
256         unsigned int d0lo, d0hi, d1lo, d1hi;
257         unsigned int end;
258         unsigned int hlo = cir->carry_low , hhi = cir->carry_high;      
259         int repeat;
260         u32 frame_interval;
261         int i, nByte;
262         u8 reg_value[32];
263         struct bu92747_data_info *bu92747 = (struct bu92747_data_info *)i2c_get_clientdata(client);
264         int sys_clock = bu92747->sys_clock;
265
266         BU92747_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
267
268         if (!cir)
269                 return -1;
270
271         //set inv0, inv1
272         inv0 = cir->inv & 0x01;
273         inv1 = (cir->inv>>1) & 0x01;
274         bu92747_cir_i2c_read_regs(client, REG_SETTING0, reg_value, 3);
275         reg_value[0] = reg_value[0] | (inv0<<1) | (inv1<<2);
276         //bu92747_cir_i2c_set_regs(client, REG_SETTING0, reg_value, 1);
277         BU92747_DBG("inv0 = %d, inv1 = %d\n", inv0, inv1);
278
279
280         repeat_flag = cir->repeat;
281         printk("repeat 11111 =%d\n", repeat_flag);
282         
283         if (repeat_flag == -1){
284                 repeat_flag = -10;
285                 repeat = 0;             
286         }else if (repeat_flag > 16){
287                 repeat = 16; 
288         }else{
289                 repeat = repeat_flag;
290         }
291
292         repeat = repeat % 16;
293         reg_value[1] = ((reg_value[1]&0xf0) | (repeat&0x0f));
294
295
296         //carry
297         clo = XIN_INPUT_FREQ / 3000 * hlo;
298         chi = XIN_INPUT_FREQ / 3000 * hhi;
299         reg_value[3] = clo>>8;
300         reg_value[4] = clo&0xff;
301         reg_value[5] = chi>>8;
302         reg_value[6] = chi&0xff;
303         BU92747_DBG("clo = 0x%x, chi = 0x%x\n", clo, chi);
304         //bu92747_cir_i2c_set_regs(client, REG_CLO1, reg_value, 4);
305
306         
307
308         //head
309         hlo = (cir->head_space_time*sys_clock)/1000;
310         hhi = (cir->head_burst_time*sys_clock)/1000;
311         reg_value[7] = hlo>>8;
312         reg_value[8] = hlo&0xff;
313         reg_value[9] = hhi>>8;
314         reg_value[10] = hhi&0xff;
315         BU92747_DBG("hlo = 0x%x, hhi = 0x%x\n", hlo, hhi);
316
317
318         //data0
319         d0lo = (cir->logic_low_space_time*sys_clock)/1000;
320         d0hi = (cir->logic_low_burst_time*sys_clock)/1000;
321         reg_value[11] = d0lo>>8;
322         reg_value[12] = d0lo&0xff;
323         reg_value[13] = d0hi>>8;
324         reg_value[14] = d0hi&0xff;
325         BU92747_DBG("d0lo = 0x%x, d0hi = 0x%x\n", d0lo, d0hi);
326
327
328         //data1
329         d1lo = (cir->logic_high_space_time*sys_clock)/1000;
330         d1hi = (cir->logic_high_burst_time*sys_clock)/1000;
331         reg_value[15] = d1lo>>8;
332         reg_value[16] = d1lo&0xff;
333         reg_value[17] = d1hi>>8;
334         reg_value[18] = d1hi&0xff;
335         BU92747_DBG("d1lo = 0x%x, d1hi = 0x%x\n", d1lo, d1hi);
336
337         //end
338         end = (cir->stop_bit_interval*sys_clock)/1000;
339         reg_value[19] = end>>8;
340         reg_value[20] = end&0xff;
341         //bu92747_cir_i2c_set_regs(client, REG_CLO1, reg_value, 18);
342
343         BU92747_DBG("end = 0x%x\n", end);
344
345         
346         //data bit length
347         reg_value[21] = cir->frame_bit_len;
348         BU92747_DBG("frame_bit_len = 0x%x\n", cir->frame_bit_len);
349
350         //frame interval
351         frame_interval = (cir->frame_interval*sys_clock)/1000;
352         reg_value[22] = frame_interval>>8;
353         reg_value[23] = frame_interval&0xff;
354         //bu92747_cir_i2c_set_regs(client, REG_FRMLEN1, reg_value, 2);  
355         BU92747_DBG("cir->frame_interval =%d frame_interval = %d\n\n", cir->frame_interval,frame_interval);
356
357         
358         //data
359         nByte = (cir->frame_bit_len+7)/8;
360         for (i=0; i<nByte; i++) {
361                 reg_value[24+i] = ((cir->frame)>>(8*i))&0xff;
362                 BU92747_DBG("reg_value[%d] = %d\n", 24+i, reg_value[24+i]);
363         }
364
365         bu92747_cir_i2c_set_regs(client, REG_SETTING0, reg_value, 24+i);
366         
367
368         BU92747_DBG("line %d: exit %s\n", __LINE__, __FUNCTION__);
369
370         return 0;
371         
372 }
373
374
375 static int bu92747_start(struct i2c_client *client) 
376 {
377         u8 reg_value[2];
378         struct bu92747_data_info *bu92747 = (struct bu92747_data_info *)i2c_get_clientdata(client);
379         printk("line %d: enter %s\n", __LINE__, __FUNCTION__);
380
381
382         start_flag = 1;
383         //enable_irq(bu92747->irq);
384         //enable clk
385         bu92747_cir_i2c_read_regs(client, REG_SETTING0, reg_value, 1);
386         reg_value[0] = reg_value[0]|0x01;
387         bu92747_cir_i2c_set_regs(client, REG_SETTING0, reg_value, 1);
388
389         //clear irq, start send
390         reg_value[0] = 1;
391         reg_value[1] = 1;
392         bu92747_cir_i2c_set_regs(client, REG_IRQC, reg_value, 2);
393
394         
395         printk("line %d: exit %s\n", __LINE__, __FUNCTION__);
396         return 0;
397 }
398
399
400 static void bu92747_printk_cir(struct rk29_cir_struct_info *cir)
401 {
402         BU92747_DBG("\ncir struct:\n");
403         BU92747_DBG("carry_high                  = %d\n", cir->carry_high);
404         BU92747_DBG("carry_low       = %d\n", cir->carry_low);
405         BU92747_DBG("repeat            = %d\n", cir->repeat);
406         BU92747_DBG("inv                    = %d\n", cir->inv);
407         BU92747_DBG("frame_bit_len          = %d\n", cir->frame_bit_len);
408         BU92747_DBG("stop_bit_interval      = %d\n", cir->stop_bit_interval);
409         BU92747_DBG("frame                  = %lld\n", cir->frame);
410         BU92747_DBG("frame_interval         = %d\n", cir->frame_interval);
411         BU92747_DBG("head_burst_time        = %d\n", cir->head_burst_time);
412         BU92747_DBG("head_space_time        = %d\n", cir->head_space_time);
413         BU92747_DBG("logic_high_burst_time  = %d\n", cir->logic_high_burst_time);
414         BU92747_DBG("logic_high_space_time  = %d\n", cir->logic_high_space_time);
415         BU92747_DBG("logic_low_burst_time   = %d\n", cir->logic_low_burst_time);
416         BU92747_DBG("logic_low_space_time   = %d\n", cir->logic_low_space_time);
417         BU92747_DBG("\n");
418 }
419
420
421 static int bu92747_set_duration(struct i2c_client *client, struct rk29_cir_struct_info *cir) 
422 {
423         u32 frame_interval;
424
425         u8 reg_value[20];
426         struct bu92747_data_info *bu92747 = (struct bu92747_data_info *)i2c_get_clientdata(client);
427         int sys_clock = bu92747->sys_clock;
428
429         BU92747_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
430
431         if (!cir)
432                 return -1;
433
434         BU92747_DBG("sys_clock = %d,  frame_interval = 0x%x\n", sys_clock,cir->frame_interval);
435         //frame interval
436         frame_interval = (cir->frame_interval*sys_clock)/1000;
437         
438         reg_value[0] = frame_interval>>8;
439         reg_value[1] = frame_interval&0xff;
440         bu92747_cir_i2c_set_regs(client, REG_FRMLEN1, reg_value, 2);
441
442         BU92747_DBG("frame_interval = 0x%x\n", frame_interval);
443
444         BU92747_DBG("line %d: exit %s\n", __LINE__, __FUNCTION__);
445
446         return 0;
447         
448 }
449
450 static int bu92747_set_data(struct i2c_client *client, struct rk29_cir_struct_info *cir) 
451 {
452
453         u8 reg_value[16];
454         int i, nByte;
455         
456
457
458         BU92747_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
459         
460         //data bit length
461         reg_value[0] = cir->frame_bit_len;
462         bu92747_cir_i2c_set_regs(client, REG_BITLEN, reg_value, 1);
463         BU92747_DBG("frame_bit_len = 0x%x\n", cir->frame_bit_len);
464         
465         //data
466         nByte = (cir->frame_bit_len+7)/8;
467         for (i=0; i<nByte; i++) {
468                 reg_value[i] = ((cir->frame)>>(8*i))&0xff;
469                 BU92747_DBG("reg_value[%d] = %d\n", i, reg_value[i]);
470         }
471         bu92747_cir_i2c_set_regs(client, REG_OUT0, reg_value, nByte);
472         BU92747_DBG("nByte = %d\n", nByte);
473         
474         
475         BU92747_DBG("line %d: exit %s\n", __LINE__, __FUNCTION__);
476         
477         return 0;
478 }
479
480 static int bu92747_set_pulse(struct i2c_client *client, struct rk29_cir_struct_info *cir) 
481 {
482         u8 inv0, inv1;
483
484
485         unsigned int d0lo, d0hi, d1lo, d1hi;
486
487
488         u8 reg_value[8] = {0};
489         struct bu92747_data_info *bu92747 = (struct bu92747_data_info *)i2c_get_clientdata(client);
490         int sys_clock = bu92747->sys_clock;
491
492         BU92747_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
493
494         if (!cir)
495                 return -1;
496
497         //set inv0, inv1
498         inv0 = cir->inv & 0x01;
499         inv1 = (cir->inv>>1) & 0x01;
500         bu92747_cir_i2c_read_regs(client, REG_SETTING0, reg_value, 1);
501         reg_value[0] = reg_value[0] | (inv0<<1) | (inv1<<2);
502         bu92747_cir_i2c_set_regs(client, REG_SETTING0, reg_value, 1);
503         BU92747_DBG("inv0 = %d, inv1 = %d\n", inv0, inv1);
504
505
506
507         //data0
508         d0lo = (cir->logic_low_space_time*sys_clock)/1000;
509         d0hi = (cir->logic_low_burst_time*sys_clock)/1000;
510         reg_value[0] = d0lo>>8;
511         reg_value[1] = d0lo&0xff;
512         reg_value[2] = d0hi>>8;
513         reg_value[3] = d0hi&0xff;
514         BU92747_DBG("d0lo = 0x%x, d0hi = 0x%x\n", d0lo, d0hi);
515
516         //data1
517         d1lo = (cir->logic_high_space_time*sys_clock)/1000;
518         d1hi = (cir->logic_high_burst_time*sys_clock)/1000;
519         reg_value[4] = d1lo>>8;
520         reg_value[5] = d1lo&0xff;
521         reg_value[6] = d1hi>>8;
522         reg_value[7] = d1hi&0xff;
523         BU92747_DBG("d1lo = 0x%x, d1hi = 0x%x\n", d1lo, d1hi);
524         bu92747_cir_i2c_set_regs(client, REG_D0LO1, reg_value, 8);
525
526         BU92747_DBG("line %d: exit %s\n", __LINE__, __FUNCTION__);
527
528         return 0;
529         
530 }
531
532
533
534 static int bu92747_set_parameter(struct i2c_client *client, struct rk29_cir_struct_info *cir) 
535 {
536         unsigned int hlo, hhi;
537         unsigned int end;
538
539         u8 reg_value[4];
540         struct bu92747_data_info *bu92747 = (struct bu92747_data_info *)i2c_get_clientdata(client);
541         int sys_clock = bu92747->sys_clock;
542
543         BU92747_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
544
545         if (!cir)
546                 return -1;
547
548         //head
549         hlo = (cir->head_space_time*sys_clock)/1000;
550         hhi = (cir->head_burst_time*sys_clock)/1000;
551         reg_value[0] = hlo>>8;
552         reg_value[1] = hlo&0xff;
553         reg_value[2] = hhi>>8;
554         reg_value[3] = hhi&0xff;
555         BU92747_DBG("hlo = 0x%x, hhi = 0x%x\n", hlo, hhi);
556         bu92747_cir_i2c_set_regs(client, REG_HLO1, reg_value, 4);
557
558         //end
559         end = (cir->stop_bit_interval*sys_clock)/1000;
560         reg_value[0] = end>>8;
561         reg_value[1] = end&0xff;
562         bu92747_cir_i2c_set_regs(client, REG_ENDLEN1, reg_value, 2);
563
564         BU92747_DBG("end = 0x%x\n", end);
565
566         BU92747_DBG("line %d: exit %s\n", __LINE__, __FUNCTION__);
567
568         return 0;
569         
570 }
571
572
573 static int bu92747_set_repeat(struct i2c_client *client, struct rk29_cir_struct_info *cir) 
574 {
575
576         u8 reg_value[2];
577         int repeat;
578
579         BU92747_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
580
581
582     repeat_flag = cir->repeat;
583         printk("repeat 11111 =%d\n", repeat_flag);
584         
585         if (repeat_flag == -1){
586                 repeat_flag = -10;
587                 repeat = 0;             
588         }else if (repeat_flag > 16){
589                 repeat = 16; 
590         }else{
591                 repeat = repeat_flag;
592         }
593
594
595         repeat = repeat % 16;
596         
597         bu92747_cir_i2c_read_regs(client, REG_SETTING1, reg_value, 1);
598         
599         reg_value[0] = (reg_value[0]&0xf0) | (repeat&0x0f);
600         bu92747_cir_i2c_set_regs(client, REG_SETTING1, reg_value, 1);
601         printk("repeat  2222  =%d  reg_value = %d\n", repeat, reg_value[0]);
602          
603         BU92747_DBG("line %d: exit %s\n", __LINE__, __FUNCTION__);
604         
605         return 0;
606 }
607
608 static int bu92747_set_carrier(struct i2c_client *client, struct rk29_cir_struct_info *cir) 
609 {
610         u8 reg_value[4];
611         u16 clo = 0, chi = 0;  
612         unsigned int hlo = cir->carry_low , hhi = cir->carry_high;      
613
614         BU92747_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
615
616         if (!cir)
617                 return -1;
618
619         //carry
620
621         clo = XIN_INPUT_FREQ / 3000 * hlo;
622         chi = XIN_INPUT_FREQ / 3000 * hhi;
623         reg_value[0] = clo>>8;
624         reg_value[1] = clo&0xff;
625         reg_value[2] = chi>>8;
626         reg_value[3] = chi&0xff;
627         BU92747_DBG("clo = 0x%x, chi = 0x%x\n", clo, chi);
628         bu92747_cir_i2c_set_regs(client, REG_CLO1, reg_value, 4);
629
630         BU92747_DBG("line %d: exit %s\n", __LINE__, __FUNCTION__);
631
632         return 0;
633         
634 }
635
636
637 static int bu92747_cir_init_device(struct i2c_client *client, struct bu92747_data_info *bu92747)        
638 {
639         u8 reg_value[3];
640         
641         BU92747_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
642         
643         //transmission buff null intertupt, base clock div, irq enable, clock power up
644         //reg_value[0] = /*REG0_OPM | */REG0_DIVS | REG0_PWR | REG0_IRQE;
645         reg_value[0] = /*REG0_OPM | */REG0_DIVS | REG0_IRQE;
646         reg_value[1] = REG1_FRME | REG1_RPT;  //enable frame interval, repeat = 1
647         reg_value[2] = 80;   //base clock = 100KHz
648         BU92747_DBG("line %d: reg0=0x%x, reg1=0x%x, reg2=0x%x\n", __LINE__, reg_value[0], reg_value[1], reg_value[2]);
649         bu92747_cir_i2c_set_regs(client, REG_SETTING0, reg_value, 3);
650         bu92747_cir_i2c_read_regs(client, REG_SETTING0, reg_value, 3);
651         BU92747_DBG("line %d: reg0=0x%x, reg1=0x%x, reg2=0x%x\n", __LINE__, reg_value[0], reg_value[1], reg_value[2]);
652
653         bu92747->base_clock = 100; //KHz
654         bu92747->sys_clock = bu92747->base_clock;
655
656         BU92747_DBG("line %d: exit %s\n", __LINE__, __FUNCTION__);
657
658         return 0;
659 }
660
661 static int bu92747_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
662 {
663         void __user *argp = (void __user *)arg;
664         char msg[CIR_FRAME_SIZE];
665         int ret;
666         struct i2c_client *client = container_of(bu92747guw_device.parent, struct i2c_client, dev);
667
668         BU92747_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
669
670
671         switch (cmd) {
672         
673         case BU92747_IOCTL_START:
674                 ret = bu92747_start(client);
675                 if (ret < 0)
676                         return ret;
677                 break;
678                 
679         case BU92747_IOCTL_STOP:
680                 ret = bu92747_stop(client);
681                 if (ret < 0)
682                         return ret;
683                 break;
684                 
685         case BU92747_IOCTL_PULSE:
686                 if (copy_from_user(&msg, argp, sizeof(msg)))
687                         return -EFAULT;
688                         
689                 //bu92747_printk_cir((struct rk29_cir_struct_info *)msg);
690                 ret = bu92747_set_pulse(client, (struct rk29_cir_struct_info *)msg);
691                 if (ret < 0)
692                         return ret;
693                 break;
694     
695         case BU92747_IOCTL_DATA:
696                 if (copy_from_user(&msg, argp, sizeof(msg)))
697                         return -EFAULT;
698                 ret = bu92747_set_data(client, (struct rk29_cir_struct_info *)msg);
699                 if (ret < 0)
700                         return ret;
701                 break;
702
703         case BU92747_IOCTL_CARRIER:
704                 if (copy_from_user(&msg, argp, sizeof(msg)))
705                         return -EFAULT;
706                 ret = bu92747_set_carrier(client, (struct rk29_cir_struct_info *)msg);
707                 if (ret < 0)
708                         return ret;
709                 break;  
710         case BU92747_IOCTL_REPEAT:
711                 if (copy_from_user(&msg, argp, sizeof(msg)))
712                         return -EFAULT;
713                 ret = bu92747_set_repeat(client, (struct rk29_cir_struct_info *)msg);
714                 if (ret < 0)
715                         return ret;     
716                 break;
717                 
718         case BU92747_IOCTL_DURATION:
719                 if (copy_from_user(&msg, argp, sizeof(msg)))
720                         return -EFAULT;
721                 ret = bu92747_set_duration(client, (struct rk29_cir_struct_info *)msg);
722                 if (ret < 0)
723                         return ret;     
724                 break;  
725         case BU92747_IOCTL_PARAMETER:
726                 if (copy_from_user(&msg, argp, sizeof(msg)))
727                         return -EFAULT;
728                         
729                 ret = bu92747_set_parameter(client, (struct rk29_cir_struct_info *)msg);
730                 if (ret < 0)
731                         return ret;             
732                 break;  
733         case BU92747_IOCTL_FORMATE:
734                         if (copy_from_user(&msg, argp, sizeof(msg)))
735                                 return -EFAULT;
736                                 
737                         ret = bu92747_set_format(client, (struct rk29_cir_struct_info *)msg);
738                         if (ret < 0)
739                                 return ret;     
740                         break;  
741
742                 
743         default:
744                 return -ENOTTY;
745         }
746         
747         BU92747_DBG("line %d: exit %s\n", __LINE__, __FUNCTION__);
748
749         return 0;
750 }
751
752 static int bu92747_open(struct inode *inode, struct file *file)
753 {
754         struct i2c_client *client = container_of(bu92747guw_device.parent, struct i2c_client, dev);
755         struct bu92747_data_info *bu92747 = (struct bu92747_data_info *)i2c_get_clientdata(client);
756         struct bu92747guw_platform_data *pdata = bu92747->platdata;
757
758         BU92747_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
759
760         printk("bu92747_open\n");
761         bu92747->state = 0;
762 //      if (BU92747_OPEN == bu92747->state) 
763 //              return -EBUSY;
764 //      bu92747->state = BU92747_OPEN;
765         
766         //power on
767         if (pdata && pdata->cir_pwr_ctl) {
768                 pdata->cir_pwr_ctl(1);
769         }
770                 
771         //switch to remote control, mcr, ec_en=1,rc_mode=1
772         smc0_write(REG_MCR_ADDR, smc0_read(REG_MCR_ADDR)|(3<<10));
773         //set irda pwdownpin = 0
774         smc0_write(REG_TRCR_ADDR, smc0_read(REG_TRCR_ADDR)&0xffbf);
775         BU92747_DBG("irda power down pin = %d\n", gpio_get_value(RK29_PIN5_PA7));
776
777         //register init
778         bu92747_cir_init_device(client, bu92747);
779         start_flag = -1;
780         BU92747_DBG("line %d: exit %s\n", __LINE__, __FUNCTION__);
781
782         return 0;
783 }
784
785 static int bu92747_release(struct inode *inode, struct file *file)
786 {
787         struct i2c_client *client = container_of(bu92747guw_device.parent, struct i2c_client, dev);
788         struct bu92747_data_info *bu92747 = (struct bu92747_data_info *)i2c_get_clientdata(client);
789         struct bu92747guw_platform_data *pdata = bu92747->platdata;
790
791         BU92747_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
792
793         //power down
794         if (pdata && pdata->cir_pwr_ctl) {
795                 pdata->cir_pwr_ctl(0);
796         }
797         
798 //      bu92747->state = BU92747_CLOSE;
799
800         BU92747_DBG("line %d: exit %s\n", __LINE__, __FUNCTION__);
801         
802         return 0;
803 }
804
805 static struct file_operations bu92747_fops = {
806         .owner = THIS_MODULE,
807         .open = bu92747_open,
808         .release = bu92747_release,
809         .ioctl = bu92747_ioctl,
810 };
811
812 static struct miscdevice bu92747guw_device = {
813         .minor = MISC_DYNAMIC_MINOR,
814         .name = "rk29_cir",
815         .fops = &bu92747_fops,
816 };
817
818 static int __devinit bu92747_cir_probe(struct i2c_client *client, const struct i2c_device_id *id)
819 {
820         struct bu92747_data_info *bu92747;
821         struct bu92747guw_platform_data *pdata;
822         int err;
823         
824         BU92747_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
825
826     if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
827                 return -ENODEV;
828         
829         bu92747 = kzalloc(sizeof(struct bu92747_data_info), GFP_KERNEL);
830         if (!bu92747) {
831                 printk("line %d: bu92747 alloc data failed.\n", __LINE__);
832                 err = -ENOMEM;
833                 goto MEM_ERR;
834         }
835         //ioinit
836         pdata = client->dev.platform_data;
837         if (pdata && pdata->iomux_init) {
838                 pdata->iomux_init();
839         }
840         
841         bu92747->platdata = pdata;
842         bu92747->client = client;
843         i2c_set_clientdata(client, bu92747);
844         bu92747->state = BU92747_CLOSE;
845
846         //register device
847         bu92747guw_device.parent = &client->dev;
848         err = misc_register(&bu92747guw_device);
849         if (err) {
850                 printk("line %d: bu92747 misc_register failed.\n", __LINE__);
851                 goto REGISTER_ERR;
852         }
853
854         //request irq
855         if (pdata && gpio_is_valid(pdata->intr_pin)) {
856                 printk("-------request irq\n");
857                 err = gpio_request(pdata->intr_pin, "rk29 cir irq");
858                 if (err) {
859                         printk("line %d: bu92747 request gpio failed.\n", __LINE__);
860                         goto GPIO_ERR;
861                 }
862                 gpio_direction_input(pdata->intr_pin);
863                 gpio_request(RK29_PIN5_PA7, NULL);
864                 if (err) {
865                         printk("line %d: bu92747 request gpio failed.\n", __LINE__);
866                 }
867                 gpio_direction_input(RK29_PIN5_PA7);
868                 bu92747->irq = gpio_to_irq(pdata->intr_pin);
869                 err = request_irq(bu92747->irq, bu92747_cir_irq, IRQF_TRIGGER_FALLING, client->dev.driver->name, bu92747);
870                 if (err) {
871                         BU92747_DBG("line %d: bu92747 request gpio failed.\n", __LINE__);
872                         goto IRQ_ERR;
873                 }
874                 //disable_irq(bu92747->irq);
875         }
876         
877         //INIT_DELAYED_WORK(&bu92747->dwork, bu92747_dwork_handler);
878         INIT_DELAYED_WORK(&bu92747->dwork, bu92747_dwork_handler);
879         
880
881 #if 0
882         //bu92747_start(client);
883         //while (1) {
884                 //bu92747_send_data_test(client);
885                 //BU92747_DBG("line %d: test %s\n", __LINE__, __FUNCTION__);
886                 //mdelay(500);
887         //}
888 #endif
889
890         BU92747_DBG("line %d: exit %s\n", __LINE__, __FUNCTION__);
891         return 0;
892
893 IRQ_ERR:
894         gpio_free(pdata->intr_pin);
895 GPIO_ERR:
896     misc_deregister(&bu92747guw_device);
897 REGISTER_ERR:
898         if (pdata && pdata->iomux_deinit)
899                 pdata->iomux_deinit();
900         kfree(bu92747);
901 MEM_ERR:
902         return err;
903 }
904
905 static int __devexit bu92747_cir_remove(struct i2c_client *client)
906 {
907         
908         struct bu92747_data_info *bu92747 = i2c_get_clientdata(client);
909         struct bu92747guw_platform_data *pdata = bu92747->platdata;
910
911         printk(" cir_remove \n");
912         start_flag = 0;
913         free_irq(bu92747->irq, bu92747);
914         gpio_free(pdata->intr_pin);
915     misc_deregister(&bu92747guw_device);
916         if (pdata && pdata->iomux_deinit)
917                 pdata->iomux_deinit();
918         kfree(bu92747);
919         return 0;
920 }
921
922 static const struct i2c_device_id bu92747_cir_id[] = {
923         { "bu92747_cir", 0 },
924         { }
925 };
926 MODULE_DEVICE_TABLE(i2c, bu92747_cir_id);
927
928 static struct i2c_driver bu92747_cir_driver = {
929         .driver         = {
930                 .name   = "bu92747_cir",
931                 .owner  = THIS_MODULE,
932         },
933         .probe          = bu92747_cir_probe,
934         .remove         = __devexit_p(bu92747_cir_remove),
935         .id_table       = bu92747_cir_id,
936 };
937
938 static int __init bu92747_cir_init(void)
939 {
940         return i2c_add_driver(&bu92747_cir_driver);
941 }
942
943 static void __exit bu92747_cir_exit(void)
944 {
945         i2c_del_driver(&bu92747_cir_driver);
946 }
947
948 MODULE_AUTHOR("zyw zyw@rock-chips.com");
949 MODULE_DESCRIPTION("bu92747 cir driver");
950 MODULE_LICENSE("GPL");
951
952 module_init(bu92747_cir_init);
953 module_exit(bu92747_cir_exit);
954