1 #include "bflb_ir.h"
2 #include "bflb_clock.h"
3 #include "hardware/ir_reg.h"
4 
5 #define DIVIDE_ROUND(a, b) ((2 * a + b) / (2 * b))
6 
7 #if !defined(BL616)
bflb_ir_tx_init(struct bflb_device_s * dev,const struct bflb_ir_tx_config_s * config)8 void bflb_ir_tx_init(struct bflb_device_s *dev, const struct bflb_ir_tx_config_s *config)
9 {
10     uint32_t reg_base;
11     uint32_t regval;
12     uint32_t ir_clock;
13     struct bflb_ir_tx_config_s *tx_config = (struct bflb_ir_tx_config_s *)config;
14 
15 #if defined(BL602) || defined(BL702)
16     *(uint32_t *)0x40000224 |= 1 << 31;
17 #else
18     *(uint32_t *)0x20000144 |= 1 << 31;
19 #endif
20 
21     if (bflb_clk_get_peripheral_clock(BFLB_DEVICE_TYPE_IR, 0)) {
22         ir_clock = bflb_clk_get_peripheral_clock(BFLB_DEVICE_TYPE_IR, 0);
23     } else {
24         ir_clock = 2000000;
25     }
26 
27     if (tx_config->tx_mode == IR_TX_NEC) {
28         tx_config->data_bits = 32;
29         tx_config->tail_inverse = 0;
30         tx_config->tail_enable = 1;
31         tx_config->head_inverse = 0;
32         tx_config->head_enable = 1;
33         tx_config->logic1_inverse = 0;
34         tx_config->logic0_inverse = 0;
35         tx_config->data_enable = 1;
36         tx_config->swm_enable = 0;
37         tx_config->output_modulation = 1;
38         tx_config->output_inverse = 0;
39         tx_config->freerun_enable = 0;
40         tx_config->continue_enable = 0;
41         tx_config->fifo_width = IR_TX_FIFO_WIDTH_32BIT;
42         tx_config->fifo_threshold = 0;
43         tx_config->logic0_pulse_width_1 = 0;
44         tx_config->logic0_pulse_width_0 = 0;
45         tx_config->logic1_pulse_width_1 = 2;
46         tx_config->logic1_pulse_width_0 = 0;
47         tx_config->head_pulse_width_1 = 7;
48         tx_config->head_pulse_width_0 = 15;
49         tx_config->tail_pulse_width_1 = 0;
50         tx_config->tail_pulse_width_0 = 0;
51         tx_config->pulse_width_unit = (ir_clock * 10 / 17777 - 1) & 0xfff;
52     } else if (tx_config->tx_mode == IR_TX_RC5) {
53         tx_config->data_bits = 13;
54         tx_config->tail_inverse = 0;
55         tx_config->tail_enable = 0;
56         tx_config->head_inverse = 1;
57         tx_config->head_enable = 1;
58         tx_config->logic1_inverse = 1;
59         tx_config->logic0_inverse = 0;
60         tx_config->data_enable = 1;
61         tx_config->swm_enable = 0;
62         tx_config->output_modulation = 1;
63         tx_config->output_inverse = 0;
64         tx_config->freerun_enable = 0;
65         tx_config->continue_enable = 0;
66         tx_config->fifo_width = IR_TX_FIFO_WIDTH_32BIT;
67         tx_config->fifo_threshold = 0;
68         tx_config->logic0_pulse_width_1 = 0;
69         tx_config->logic0_pulse_width_0 = 0;
70         tx_config->logic1_pulse_width_1 = 0;
71         tx_config->logic1_pulse_width_0 = 0;
72         tx_config->head_pulse_width_1 = 0;
73         tx_config->head_pulse_width_0 = 0;
74         tx_config->tail_pulse_width_1 = 0;
75         tx_config->tail_pulse_width_0 = 0;
76         tx_config->pulse_width_unit = (ir_clock * 10 / 11248 - 1) & 0xfff;
77     } else if (tx_config->tx_mode == IR_TX_SWM) {
78         tx_config->swm_enable = 1;
79         tx_config->output_modulation = 1;
80         tx_config->output_inverse = 0;
81         tx_config->fifo_width = IR_TX_FIFO_WIDTH_32BIT;
82         tx_config->fifo_threshold = 0;
83     }
84 
85     if (tx_config->tx_mode != IR_TX_CUSTOMIZE) {
86         tx_config->modu_width_1 = ((ir_clock / 11310 + 5) / 10 - 1) & 0xff;
87         tx_config->modu_width_0 = ((ir_clock / 5655 + 5) / 10 - 1) & 0xff;
88     } else {
89         if (tx_config->output_modulation != 0 && tx_config->freerun_enable != 0) {
90             tx_config->continue_enable = 0;
91             if (tx_config->tail_pulse_width_1 < 5) {
92                 tx_config->tail_pulse_width_1 = 5;
93             }
94             if (tx_config->tail_pulse_width_0 < 5) {
95                 tx_config->tail_pulse_width_0 = 5;
96             }
97         }
98     }
99 
100     reg_base = dev->reg_base;
101     regval = (tx_config->pulse_width_unit & 0xfff) | tx_config->modu_width_1 << 16 | tx_config->modu_width_0 << 24;
102     putreg32(regval, reg_base + IRTX_PULSE_WIDTH_OFFSET);
103 
104 #if !defined(BL602) && !defined(BL702)
105     regval = getreg32(reg_base + IR_FIFO_CONFIG_1_OFFSET);
106     regval &= ~IR_TX_FIFO_TH_MASK;
107     regval |= tx_config->fifo_threshold << IR_TX_FIFO_TH_SHIFT;
108     putreg32(regval, reg_base + IR_FIFO_CONFIG_1_OFFSET);
109 #endif
110 
111     regval = getreg32(reg_base + IRTX_CONFIG_OFFSET);
112 #if defined(BL602) || defined(BL702)
113     regval &= ~(IR_CR_IRTX_SWM_EN | IR_CR_IRTX_MOD_EN | IR_CR_IRTX_OUT_INV);
114 #else
115     regval &= ~(IR_CR_IRTX_SWM_EN | IR_CR_IRTX_MOD_EN | IR_CR_IRTX_OUT_INV | IR_CR_IRTX_FRM_FRAME_SIZE_MASK);
116 #endif
117     if (tx_config->swm_enable) {
118         regval |= IR_CR_IRTX_SWM_EN;
119     }
120     if (tx_config->output_modulation) {
121         regval |= IR_CR_IRTX_MOD_EN;
122     }
123     if (tx_config->output_inverse) {
124         regval |= IR_CR_IRTX_OUT_INV;
125     }
126 #if !defined(BL602) && !defined(BL702)
127     regval |= (tx_config->fifo_width & 0x3) << IR_CR_IRTX_FRM_FRAME_SIZE_SHIFT;
128 #endif
129     if (tx_config->tx_mode == IR_TX_SWM) {
130         putreg32(regval, reg_base + IRTX_CONFIG_OFFSET);
131         return;
132     }
133 #if defined(BL602) || defined(BL702)
134     regval &= IR_CR_IRTX_SWM_EN | IR_CR_IRTX_MOD_EN | IR_CR_IRTX_OUT_INV;
135 #else
136     regval &= IR_CR_IRTX_SWM_EN | IR_CR_IRTX_MOD_EN | IR_CR_IRTX_OUT_INV | IR_CR_IRTX_FRM_FRAME_SIZE_MASK;
137 #endif
138     regval |= (tx_config->data_bits - 1) << IR_CR_IRTX_DATA_NUM_SHIFT;
139     if (tx_config->tail_inverse) {
140         regval |= IR_CR_IRTX_TAIL_HL_INV;
141     }
142     if (tx_config->tail_enable) {
143         regval |= IR_CR_IRTX_TAIL_EN;
144     }
145     if (tx_config->head_inverse) {
146         regval |= IR_CR_IRTX_HEAD_HL_INV;
147     }
148     if (tx_config->head_enable) {
149         regval |= IR_CR_IRTX_HEAD_EN;
150     }
151     if (tx_config->logic1_inverse) {
152         regval |= IR_CR_IRTX_LOGIC1_HL_INV;
153     }
154     if (tx_config->logic0_inverse) {
155         regval |= IR_CR_IRTX_LOGIC0_HL_INV;
156     }
157     if (tx_config->data_enable) {
158         regval |= IR_CR_IRTX_DATA_EN;
159     }
160 #if !defined(BL602) && !defined(BL702)
161     if (tx_config->freerun_enable) {
162         regval |= IR_CR_IRTX_FRM_EN;
163     }
164     if (tx_config->continue_enable) {
165         regval |= IR_CR_IRTX_FRM_CONT_EN;
166     }
167 #endif
168     putreg32(regval, reg_base + IRTX_CONFIG_OFFSET);
169 
170 #if defined(BL602) || defined(BL702)
171     regval = (tx_config->tail_pulse_width_1 & 0xf) << 28 | \
172              (tx_config->tail_pulse_width_0 & 0xf) << 24 | \
173              (tx_config->head_pulse_width_1 & 0xf) << 20 | \
174              (tx_config->head_pulse_width_0 & 0xf) << 16 | \
175              (tx_config->logic1_pulse_width_1 & 0xf) << 12 | \
176              (tx_config->logic1_pulse_width_0 & 0xf) << 8 | \
177              (tx_config->logic0_pulse_width_1 & 0xf) << 4 | \
178              (tx_config->logic0_pulse_width_0 & 0xf);
179     putreg32(regval, reg_base + IRTX_PW_OFFSET);
180 #else
181     regval = tx_config->logic0_pulse_width_0 | tx_config->logic0_pulse_width_1 << 8 | \
182              tx_config->logic1_pulse_width_0 << 16 | tx_config->logic1_pulse_width_1 << 24;
183     putreg32(regval, reg_base + IRTX_PW_0_OFFSET);
184 
185     regval = tx_config->head_pulse_width_0 | tx_config->head_pulse_width_1 << 8 | \
186              tx_config->tail_pulse_width_0 << 16 | tx_config->tail_pulse_width_1 << 24;
187     putreg32(regval, reg_base + IRTX_PW_1_OFFSET);
188 #endif
189 }
190 
bflb_ir_send(struct bflb_device_s * dev,uint32_t * data,uint32_t length)191 void bflb_ir_send(struct bflb_device_s *dev, uint32_t *data, uint32_t length)
192 {
193     uint32_t reg_base;
194     uint32_t regval;
195 #if !defined(BL602) && !defined(BL702)
196     uint32_t i = 0;
197 #endif
198 
199     bflb_ir_txint_clear(dev);
200 
201     reg_base = dev->reg_base;
202 #if defined(BL602) || defined(BL702)
203     putreg32(data[0], reg_base + IRTX_DATA_WORD0_OFFSET);
204     if (length > 1) {
205         putreg32(data[1], reg_base + IRTX_DATA_WORD1_OFFSET);
206     }
207 #endif
208 
209     regval = getreg32(reg_base + IRTX_CONFIG_OFFSET);
210     regval |= IR_CR_IRTX_EN;
211     putreg32(regval, reg_base + IRTX_CONFIG_OFFSET);
212 
213 #if !defined(BL602) && !defined(BL702)
214     if ((regval & IR_CR_IRTX_FRM_EN) == 0) {
215         length = length < 4 ? length : 4;
216     }
217     while(i < length){
218         if (bflb_ir_get_txfifo_cnt(dev) > 0) {
219             putreg32(data[i], reg_base + IR_FIFO_WDATA_OFFSET);
220             i++;
221         }
222     }
223 
224     if ((getreg32(reg_base + IRTX_CONFIG_OFFSET) & IR_CR_IRTX_FRM_EN) == 0) {
225         while((bflb_ir_get_txint_status(dev) & IR_TX_INTSTS_END) == 0){
226             /* Waiting for sending */
227         }
228     } else {
229         while(bflb_ir_get_txfifo_cnt(dev) < 4){
230             /* Waiting for sending */
231         }
232     }
233 #else
234     while((bflb_ir_get_txint_status(dev) & IR_TX_INTSTS_END) == 0){
235         /* Waiting for sending */
236     }
237 #endif
238 
239     regval &= ~IR_CR_IRTX_EN;
240     putreg32(regval, reg_base + IRTX_CONFIG_OFFSET);
241 
242     bflb_ir_txint_clear(dev);
243 }
244 
bflb_ir_swm_send(struct bflb_device_s * dev,uint16_t * data,uint8_t length)245 void bflb_ir_swm_send(struct bflb_device_s *dev, uint16_t *data, uint8_t length)
246 {
247     uint32_t reg_base;
248     uint32_t regval;
249     uint16_t min_data = data[0];
250 #if defined(BL602) || defined(BL702)
251     uint32_t count = (length + 7) / 8;
252 #else
253     uint32_t count = (length + 3) / 4;
254 #endif
255     uint32_t pwval = 0;
256     uint32_t i, j;
257 
258     if (length > 128) {
259         length = 128;
260     }
261 
262     bflb_ir_txint_clear(dev);
263 
264     /* Search for min value */
265     for (i = 1; i < length; i++) {
266         if (min_data > data[i] && data[i] != 0) {
267             min_data = data[i];
268         }
269     }
270 
271     /* Set min value as pulse width unit */
272     reg_base = dev->reg_base;
273     regval = getreg32(reg_base + IRTX_PULSE_WIDTH_OFFSET);
274     regval &= ~IR_CR_IRTX_PW_UNIT_MASK;
275     regval |= min_data << IR_CR_IRTX_PW_UNIT_SHIFT;
276     putreg32(regval, reg_base + IRTX_PULSE_WIDTH_OFFSET);
277 
278 #if defined(BL602) || defined(BL702)
279     /* Set tx SWM pulse width data as multiples of pulse width unit */
280     for (i = 0; i < count; i++) {
281         pwval = 0;
282 
283         if (i < count - 1) {
284             for (j = 0; j < 8; j++) {
285                 regval = ((2 * data[j + i * 8] + min_data) / (2 * min_data) - 1) & 0xf;
286                 pwval |= regval << (4 * j);
287             }
288 
289             putreg32(pwval, reg_base + IRTX_SWM_PW_0_OFFSET + i * 4);
290         } else {
291             for (j = 0; j < length % 8; j++) {
292                 regval = ((2 * data[j + i * 8] + min_data) / (2 * min_data) - 1) & 0xf;
293                 pwval |= regval << (4 * j);
294             }
295 
296             putreg32(pwval, reg_base + IRTX_SWM_PW_0_OFFSET + i * 4);
297         }
298     }
299 #endif
300 
301     regval = getreg32(reg_base + IRTX_CONFIG_OFFSET);
302     regval &= ~IR_CR_IRTX_DATA_NUM_MASK;
303     regval |= (length - 1) << IR_CR_IRTX_DATA_NUM_SHIFT;
304     regval |= IR_CR_IRTX_EN;
305     putreg32(regval, reg_base + IRTX_CONFIG_OFFSET);
306 
307 #if !defined(BL602) && !defined(BL702)
308     /* Calculate tx SWM pulse width data as multiples of pulse width unit */
309     for (i = 0; i < count; i++) {
310         pwval = 0;
311 
312         if (i < count - 1) {
313             /* Put every four pulse width together as a 32-bit value to tx fifo */
314             for (j = 0; j < 4; j++) {
315                 /* Every pulse width divided by pulse width unit */
316                 regval = (DIVIDE_ROUND(data[j + i * 4], min_data) - 1) & 0xff;
317                 /* Tx fifo 32-bit value: pwval[7:0]:first pulse width, pwval[15:8]:second pulse width... */
318                 pwval |= regval << (8 * j);
319             }
320         } else {
321             /* Deal with pulse width data remained which is less than 4 */
322             for (j = 0; j < length % 4; j++) {
323                 regval = (DIVIDE_ROUND(data[j + i * 4], min_data) - 1) & 0xff;
324                 pwval |= regval << (8 * j);
325             }
326         }
327 
328         /* Write to tx fifo */
329         while(bflb_ir_get_txfifo_cnt(dev) == 0){}
330         putreg32(pwval, reg_base + IR_FIFO_WDATA_OFFSET);
331     }
332 #endif
333 
334     while((bflb_ir_get_txint_status(dev) & IR_TX_INTSTS_END) == 0){
335         /* Waiting for sending */
336     }
337 
338     regval = getreg32(reg_base + IRTX_CONFIG_OFFSET);
339     regval &= ~IR_CR_IRTX_EN;
340     putreg32(regval, reg_base + IRTX_CONFIG_OFFSET);
341 
342     bflb_ir_txint_clear(dev);
343 }
344 
bflb_ir_tx_enable(struct bflb_device_s * dev,bool enable)345 void bflb_ir_tx_enable(struct bflb_device_s *dev, bool enable)
346 {
347     uint32_t reg_base;
348     uint32_t regval;
349 
350     reg_base = dev->reg_base;
351     regval = getreg32(reg_base + IRTX_CONFIG_OFFSET);
352     if (enable) {
353         regval |= IR_CR_IRTX_EN;
354     } else {
355         regval &= ~IR_CR_IRTX_EN;
356     }
357     putreg32(regval, reg_base + IRTX_CONFIG_OFFSET);
358 }
359 
bflb_ir_txint_mask(struct bflb_device_s * dev,uint8_t int_type,bool mask)360 void bflb_ir_txint_mask(struct bflb_device_s *dev, uint8_t int_type, bool mask)
361 {
362     uint32_t reg_base;
363     uint32_t regval;
364 
365     reg_base = dev->reg_base;
366     regval = getreg32(reg_base + IRTX_INT_STS_OFFSET);
367     if (mask) {
368         regval |= (int_type & 0x7) << 8;
369     } else {
370         regval &= ~((int_type & 0x7) << 8);
371     }
372     putreg32(regval, reg_base + IRTX_INT_STS_OFFSET);
373 }
374 
bflb_ir_txint_clear(struct bflb_device_s * dev)375 void bflb_ir_txint_clear(struct bflb_device_s *dev)
376 {
377     uint32_t reg_base;
378     uint32_t regval;
379 
380     reg_base = dev->reg_base;
381     regval = getreg32(reg_base + IRTX_INT_STS_OFFSET);
382     regval |= IR_CR_IRTX_END_CLR;
383     putreg32(regval, reg_base + IRTX_INT_STS_OFFSET);
384 }
385 
bflb_ir_get_txint_status(struct bflb_device_s * dev)386 uint32_t bflb_ir_get_txint_status(struct bflb_device_s *dev)
387 {
388     uint32_t reg_base;
389 
390     reg_base = dev->reg_base;
391     return (getreg32(reg_base + IRTX_INT_STS_OFFSET) & 0x7);
392 }
393 
394 #if !defined(BL602) && !defined(BL702)
bflb_ir_link_txdma(struct bflb_device_s * dev,bool enable)395 void bflb_ir_link_txdma(struct bflb_device_s *dev, bool enable)
396 {
397     uint32_t reg_base;
398     uint32_t regval;
399 
400     reg_base = dev->reg_base;
401     regval = getreg32(reg_base + IR_FIFO_CONFIG_0_OFFSET);
402     if (enable) {
403         regval |= IRTX_DMA_EN;
404     } else {
405         regval &= ~IRTX_DMA_EN;
406     }
407     putreg32(regval, reg_base + IR_FIFO_CONFIG_0_OFFSET);
408 }
409 
bflb_ir_get_txfifo_cnt(struct bflb_device_s * dev)410 uint8_t bflb_ir_get_txfifo_cnt(struct bflb_device_s *dev)
411 {
412     uint32_t reg_base;
413 
414     reg_base = dev->reg_base;
415     return ((getreg32(reg_base + IR_FIFO_CONFIG_1_OFFSET) & IR_TX_FIFO_CNT_MASK) >> IR_TX_FIFO_CNT_SHIFT);
416 }
417 
bflb_ir_txfifo_clear(struct bflb_device_s * dev)418 void bflb_ir_txfifo_clear(struct bflb_device_s *dev)
419 {
420     uint32_t reg_base;
421     uint32_t regval;
422 
423     reg_base = dev->reg_base;
424     regval = getreg32(reg_base + IR_FIFO_CONFIG_0_OFFSET);
425     regval |= IR_TX_FIFO_CLR;
426     putreg32(regval, reg_base + IR_FIFO_CONFIG_0_OFFSET);
427 }
428 #endif
429 #endif
430 
431 #if !defined(BL702L)
bflb_ir_rx_init(struct bflb_device_s * dev,const struct bflb_ir_rx_config_s * config)432 void bflb_ir_rx_init(struct bflb_device_s *dev, const struct bflb_ir_rx_config_s *config)
433 {
434     uint32_t reg_base;
435     uint32_t regval;
436     uint32_t ir_clock;
437     uint16_t data_threshold, end_threshold;
438 
439     if (bflb_clk_get_peripheral_clock(BFLB_DEVICE_TYPE_IR, 0)) {
440         ir_clock = bflb_clk_get_peripheral_clock(BFLB_DEVICE_TYPE_IR, 0);
441     } else {
442         ir_clock = 2000000;
443     }
444 
445     reg_base = dev->reg_base;
446     regval = getreg32(reg_base + IRRX_CONFIG_OFFSET);
447     regval &= ~IR_CR_IRRX_MODE_MASK;
448     regval |= (config->rx_mode & 0x3) << IR_CR_IRRX_MODE_SHIFT;
449     if (config->input_inverse) {
450         regval |= IR_CR_IRRX_IN_INV;
451     } else {
452         regval &= ~IR_CR_IRRX_IN_INV;
453     }
454     if (!config->deglitch_enable) {
455         regval &= ~IR_CR_IRRX_DEG_EN;
456     } else {
457         regval |= IR_CR_IRRX_DEG_EN;
458         regval &= ~IR_CR_IRRX_DEG_CNT_MASK;
459         regval |= config->deglitch_cnt << IR_CR_IRRX_DEG_CNT_SHIFT;
460     }
461     putreg32(regval, reg_base + IRRX_CONFIG_OFFSET);
462 
463     if (config->rx_mode == IR_RX_NEC) {
464         data_threshold = (ir_clock / 588 - 1) & 0xffff;
465         end_threshold = (ir_clock / 222 - 1) & 0xffff;
466     } else if (config->rx_mode == IR_RX_RC5) {
467         data_threshold = (ir_clock / 750 - 1) & 0xffff;
468         end_threshold = (ir_clock / 400 - 1) & 0xffff;
469     } else {
470         data_threshold = config->data_threshold;
471         end_threshold = config->end_threshold;
472     }
473     regval = getreg32(reg_base + IRRX_PW_CONFIG_OFFSET);
474     regval = end_threshold << IR_CR_IRRX_END_TH_SHIFT | data_threshold;
475     putreg32(regval, reg_base + IRRX_PW_CONFIG_OFFSET);
476 
477 #if !defined(BL602) && !defined(BL702)
478     regval = getreg32(reg_base + IR_FIFO_CONFIG_1_OFFSET);
479     regval &= ~IR_RX_FIFO_TH_MASK;
480     regval |= config->fifo_threshold << IR_RX_FIFO_TH_SHIFT;
481     putreg32(regval, reg_base + IR_FIFO_CONFIG_1_OFFSET);
482 #endif
483 }
484 
bflb_ir_receive(struct bflb_device_s * dev,uint64_t * data)485 uint8_t bflb_ir_receive(struct bflb_device_s *dev, uint64_t *data)
486 {
487     uint32_t reg_base;
488     uint32_t regval;
489 
490     bflb_ir_rxint_clear(dev);
491 
492     reg_base = dev->reg_base;
493     regval = getreg32(reg_base + IRRX_CONFIG_OFFSET);
494     regval |= IR_CR_IRRX_EN;
495     putreg32(regval, reg_base + IRRX_CONFIG_OFFSET);
496 
497     while((bflb_ir_get_rxint_status(dev) & IR_RX_INTSTS_END) == 0){
498         /* Waiting for receiving */
499     }
500 
501     regval &= ~IR_CR_IRRX_EN;
502     putreg32(regval, reg_base + IRRX_CONFIG_OFFSET);
503 
504     bflb_ir_rxint_clear(dev);
505 
506     regval = getreg32(reg_base + IRRX_DATA_COUNT_OFFSET) & IR_STS_IRRX_DATA_CNT_MASK;
507     if (regval <= 32) {
508         *data = getreg32(reg_base + IRRX_DATA_WORD0_OFFSET);
509     } else {
510         *data = getreg32(reg_base + IRRX_DATA_WORD0_OFFSET) | (uint64_t)getreg32(reg_base + IRRX_DATA_WORD1_OFFSET) << 32;
511     }
512 
513     return regval;
514 }
515 
bflb_ir_swm_receive(struct bflb_device_s * dev,uint16_t * data,uint8_t length)516 uint8_t bflb_ir_swm_receive(struct bflb_device_s *dev, uint16_t *data, uint8_t length)
517 {
518     uint32_t reg_base;
519     uint32_t regval;
520     uint32_t i = 0;
521 
522     bflb_ir_rxint_clear(dev);
523 
524     reg_base = dev->reg_base;
525     regval = getreg32(reg_base + IRRX_CONFIG_OFFSET);
526     regval |= IR_CR_IRRX_EN;
527     putreg32(regval, reg_base + IRRX_CONFIG_OFFSET);
528 
529     while((bflb_ir_get_rxint_status(dev) & IR_RX_INTSTS_END) == 0){
530         if (bflb_ir_get_rxfifo_cnt(dev) != 0 && i < length) {
531 #if defined(BL602) || defined(BL702)
532             data[i] = getreg32(reg_base + IRRX_SWM_FIFO_RDATA_OFFSET);
533 #else
534             data[i] = getreg32(reg_base + IR_FIFO_RDATA_OFFSET);
535 #endif
536             i++;
537         }
538     }
539 
540     regval = getreg32(reg_base + IRRX_CONFIG_OFFSET);
541     regval &= ~IR_CR_IRRX_EN;
542     putreg32(regval, reg_base + IRRX_CONFIG_OFFSET);
543 
544     bflb_ir_rxint_clear(dev);
545 
546     return(getreg32(reg_base + IRRX_DATA_COUNT_OFFSET) & IR_STS_IRRX_DATA_CNT_MASK);
547 }
548 
bflb_ir_rx_enable(struct bflb_device_s * dev,bool enable)549 void bflb_ir_rx_enable(struct bflb_device_s *dev, bool enable)
550 {
551     uint32_t reg_base;
552     uint32_t regval;
553 
554     reg_base = dev->reg_base;
555     regval = getreg32(reg_base + IRRX_CONFIG_OFFSET);
556     if (enable) {
557         regval |= IR_CR_IRRX_EN;
558     } else {
559         regval &= ~IR_CR_IRRX_EN;
560     }
561     putreg32(regval, reg_base + IRRX_CONFIG_OFFSET);
562 }
563 
bflb_ir_rxint_mask(struct bflb_device_s * dev,uint8_t int_type,bool mask)564 void bflb_ir_rxint_mask(struct bflb_device_s *dev, uint8_t int_type, bool mask)
565 {
566     uint32_t reg_base;
567     uint32_t regval;
568 
569     reg_base = dev->reg_base;
570     regval = getreg32(reg_base + IRRX_INT_STS_OFFSET);
571     if (mask) {
572         regval |= (int_type & 0x7) << 8;
573     } else {
574         regval &= ~((int_type & 0x7) << 8);
575     }
576     putreg32(regval, reg_base + IRRX_INT_STS_OFFSET);
577 }
578 
bflb_ir_rxint_clear(struct bflb_device_s * dev)579 void bflb_ir_rxint_clear(struct bflb_device_s *dev)
580 {
581     uint32_t reg_base;
582     uint32_t regval;
583 
584     reg_base = dev->reg_base;
585     regval = getreg32(reg_base + IRRX_INT_STS_OFFSET);
586     regval |= IR_CR_IRRX_END_CLR;
587     putreg32(regval, reg_base + IRRX_INT_STS_OFFSET);
588 }
589 
bflb_ir_get_rxint_status(struct bflb_device_s * dev)590 uint32_t bflb_ir_get_rxint_status(struct bflb_device_s *dev)
591 {
592     uint32_t reg_base;
593 
594     reg_base = dev->reg_base;
595     return (getreg32(reg_base + IRRX_INT_STS_OFFSET) & 0x7);
596 }
597 
bflb_ir_get_rxfifo_cnt(struct bflb_device_s * dev)598 uint8_t bflb_ir_get_rxfifo_cnt(struct bflb_device_s *dev)
599 {
600     uint32_t reg_base;
601 
602     reg_base = dev->reg_base;
603 #if defined(BL602) || defined(BL702)
604     return ((getreg32(reg_base + IRRX_SWM_FIFO_CONFIG_0_OFFSET) & IR_RX_FIFO_CNT_MASK) >> IR_RX_FIFO_CNT_SHIFT);
605 #else
606     return ((getreg32(reg_base + IR_FIFO_CONFIG_1_OFFSET) & IR_RX_FIFO_CNT_MASK) >> IR_RX_FIFO_CNT_SHIFT);
607 #endif
608 }
609 
bflb_ir_rxfifo_clear(struct bflb_device_s * dev)610 void bflb_ir_rxfifo_clear(struct bflb_device_s *dev)
611 {
612     uint32_t reg_base;
613     uint32_t regval;
614 
615     reg_base = dev->reg_base;
616 #if defined(BL602) || defined(BL702)
617     regval = getreg32(reg_base + IRRX_SWM_FIFO_CONFIG_0_OFFSET);
618     regval |= IR_RX_FIFO_CLR;
619     putreg32(regval, reg_base + IRRX_SWM_FIFO_CONFIG_0_OFFSET);
620 #else
621     regval = getreg32(reg_base + IR_FIFO_CONFIG_0_OFFSET);
622     regval |= IR_RX_FIFO_CLR;
623     putreg32(regval, reg_base + IR_FIFO_CONFIG_0_OFFSET);
624 #endif
625 }
626 #endif
627 
bflb_ir_feature_control(struct bflb_device_s * dev,int cmd,size_t arg)628 int bflb_ir_feature_control(struct bflb_device_s *dev, int cmd, size_t arg)
629 {
630     int ret = 0;
631     switch (cmd) {
632         default:
633             ret = -EPERM;
634             break;
635     }
636     return ret;
637 }
638