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