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