chenlh
2025-09-18 345edc823540089925b8ae60af34404d608fdfb4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
 * linkport.c
 *
 *  Created on: 2024Äê5ÔÂ22ÈÕ
 *      Author: 86189
 */
#include <stdint.h>
#include <stdio.h>
#include <services/int/adi_int.h>
#include <drivers/linkport/adi_linkport.h>
#include <signal.h>
#include "linkport.h"
#include "gpio.h"
#include "config.h"
#include "dma.h"
#include "memory.h"
#include "../src/f2f.h"
 
struct link_port_regs{
    volatile uint32_t ctl;
    volatile uint32_t stat;
    volatile uint32_t div;
    volatile uint32_t dummy_1;
    //volatile uint32_t dummy_2;
    volatile uint32_t tx;
    volatile uint32_t rx;
    volatile uint32_t txin_shdw;
    volatile uint32_t txout_shdw;
};
 
//#define LP_BUFFER_SIZE 64//channel_num*frame_num
static AudioCodec mLinkPortAudio[2];
 
struct DMA_Desc{
     struct DMA_Desc *next;
     void * buffer;
};
static struct DMA_Desc lp_desc[4]; //for rx.
 
static volatile LPRegsDef*  gLPs[2] = {
        LINK_PORT0,LINK_PORT1
};
 
 
volatile LPRegsDef* get_LP_regs(uint32_t lpid)
{
    if(lpid < 2) {
        return gLPs[lpid];
    }
 
    return 0;
}
 
void LP_config(volatile LPRegsDef* regs , struct LinkPortDef* config)
{
    u32 i;
 
    volatile DMARegsDef* dma = get_dma_regs(config->lpid + 16);
    struct DMA_Desc* desca_0 = &lp_desc[config->lpid*2 + 0];
    struct DMA_Desc* desca_1 = &lp_desc[config->lpid*2 + 1];
 
    uvoid *lp_buffer = sram_malloc(SRAM_L1 , mem_any ,SAMPLE_NUM*config->slots*sizeof(s32));
    if(lp_buffer == NULL) {
        printf("lp_buffer malloc fail.\n");
    }
    mLinkPortAudio[config->lpid].dataPtr[0] = lp_buffer;
    mLinkPortAudio[config->lpid].dataPtr[1] = lp_buffer;
    mLinkPortAudio[config->lpid].rx = config->rx;
    mLinkPortAudio[config->lpid].slot_num = config->slots;
    mLinkPortAudio[config->lpid].channel_num = config->slots;
    mLinkPortAudio[config->lpid].enable_sec =0 ;
    mLinkPortAudio[config->lpid].follow_intr_no = config->follow_intr_no;
 
    if(config->lpid) {
        SetAudioCodec(LP1, 1, &mLinkPortAudio[config->lpid]);
    }
    else {
        SetAudioCodec(LP0, 1, &mLinkPortAudio[config->lpid]);
    }
 
    if(config->rx) {
        desca_0->next = (struct DMA_Desc *)((uint32_t)desca_1|MP_OFFSET);
        desca_0->buffer = (void*)((uint32_t)lp_buffer|MP_OFFSET);//
        desca_1->next = (struct DMA_Desc *)((uint32_t)desca_0|MP_OFFSET);//
        desca_1->buffer = (void*)((uint32_t)lp_buffer|MP_OFFSET);//
 
        dma_config(dma, (uint32_t)desca_0|MP_OFFSET
                    , SAMPLE_NUM*config->slots, utrue, ufalse);
    }
 
    regs->div = 0;//255;//2;//8192;////LPclk is equal to sclk if div set 0
    regs->ctl = 0;
    if(config->rx) {
        //regs->ctl |= (0 << 3) | (1 << 9);//receive
        regs->ctl |= (0 << 3);
    } else {
        //regs->ctl |= (1 << 3) | (1 << 8);//transmit
        regs->ctl |= (1 << 3);
    }
 
}
 
void LP_enable(int lp_id)
{
    volatile LPRegsDef* regs = get_LP_regs(lp_id);
    volatile DMARegsDef* dma = get_dma_regs(lp_id + 16);
 
    dma_enable(dma);
    regs->ctl |= 1;
}
 
uvoid LP_transmit()
{
    int i;
 
    for(i =0 ; i < 2 ;i ++) {
        if(mLinkPortAudio[i].slot_num > 0 && mLinkPortAudio[i].rx == ufalse) {
            volatile DMARegsDef* dma = get_dma_regs(i + 16);
            //re-config DMA for transimit.
            dma_config(dma, (uint32_t)mLinkPortAudio[i].dataPtr[0]|MP_OFFSET
                    , SAMPLE_NUM*mLinkPortAudio[i].slot_num, ufalse, utrue);
            LP_enable(i);
        }
    }
}