/alps/ipecamera

To get this branch, use:
bzr branch http://darksoft.org/webbzr/alps/ipecamera

« back to all changes in this revision

Viewing changes to dma/nwl.c

  • Committer: Suren A. Chilingaryan
  • Date: 2015-04-27 00:28:57 UTC
  • Revision ID: csa@suren.me-20150427002857-82fk6r3e8rfgy4wr
First stand-alone ipecamera implementation

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#define _PCILIB_DMA_NWL_C
2
 
#define _BSD_SOURCE
3
 
 
4
 
#include <stdio.h>
5
 
#include <stdlib.h>
6
 
#include <string.h>
7
 
#include <unistd.h>
8
 
#include <sys/time.h>
9
 
 
10
 
#include "pci.h"
11
 
#include "pcilib.h"
12
 
#include "error.h"
13
 
#include "tools.h"
14
 
#include "nwl_private.h"
15
 
 
16
 
#include "nwl_defines.h"
17
 
 
18
 
int dma_nwl_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) {
19
 
    int err;
20
 
    nwl_dma_t *ctx = (nwl_dma_t*)vctx;
21
 
 
22
 
    if (!ctx->started) {
23
 
        // global initialization, should we do anything?
24
 
        ctx->started = 1;
25
 
    }
26
 
 
27
 
    if (dma == PCILIB_DMA_ENGINE_INVALID) return 0;
28
 
    else if (dma > ctx->n_engines) return PCILIB_ERROR_INVALID_BANK;
29
 
 
30
 
    if (flags&PCILIB_DMA_FLAG_PERSISTENT) ctx->engines[dma].preserve = 1;
31
 
 
32
 
    err = dma_nwl_start_engine(ctx, dma);
33
 
    
34
 
    return err;
35
 
}
36
 
 
37
 
int dma_nwl_stop(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) {
38
 
    int err;
39
 
    int preserving = 0;
40
 
 
41
 
    nwl_dma_t *ctx = (nwl_dma_t*)vctx;
42
 
    
43
 
    if (!ctx->started) return 0;
44
 
    
45
 
        // stop everything
46
 
    if (dma == PCILIB_DMA_ENGINE_INVALID) {
47
 
        for (dma = 0; dma < ctx->n_engines; dma++) {
48
 
            if (flags&PCILIB_DMA_FLAG_PERSISTENT) {
49
 
                ctx->engines[dma].preserve = 0;
50
 
            }
51
 
        
52
 
            if (ctx->engines[dma].preserve) preserving = 1;
53
 
            
54
 
            err = dma_nwl_stop_engine(ctx, dma);
55
 
            if (err) return err;
56
 
        }
57
 
            
58
 
            // global cleanup, should we do anything?
59
 
        if (!preserving) {
60
 
            ctx->started = 0;
61
 
        }
62
 
        
63
 
        return 0;
64
 
    }
65
 
    
66
 
    if (dma > ctx->n_engines) return PCILIB_ERROR_INVALID_BANK;
67
 
    
68
 
            // ignorign previous setting if flag specified
69
 
    if (flags&PCILIB_DMA_FLAG_PERSISTENT) {
70
 
        ctx->engines[dma].preserve = 0;
71
 
    }
72
 
    
73
 
    return dma_nwl_stop_engine(ctx, dma);
74
 
}
75
 
 
76
 
 
77
 
pcilib_dma_context_t *dma_nwl_init(pcilib_t *pcilib, pcilib_dma_modification_t type, void *arg) {
78
 
    int i;
79
 
    int err;
80
 
    pcilib_dma_engine_t n_engines;
81
 
 
82
 
    pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib);
83
 
    
84
 
    nwl_dma_t *ctx = malloc(sizeof(nwl_dma_t));
85
 
    if (ctx) {
86
 
        memset(ctx, 0, sizeof(nwl_dma_t));
87
 
        ctx->pcilib = pcilib;
88
 
        ctx->type = type;
89
 
 
90
 
        if (type == PCILIB_NWL_MODIFICATION_IPECAMERA) {
91
 
            ctx->dmactx.ignore_eop = 1;
92
 
        }
93
 
 
94
 
        pcilib_register_bank_t dma_bank = pcilib_find_bank_by_addr(pcilib, PCILIB_REGISTER_BANK_DMA);
95
 
        if (dma_bank == PCILIB_REGISTER_BANK_INVALID) {
96
 
            free(ctx);
97
 
            pcilib_error("DMA Register Bank could not be found");
98
 
            return NULL;
99
 
        }
100
 
        
101
 
        ctx->dma_bank = model_info->banks + dma_bank;
102
 
        ctx->base_addr = pcilib_resolve_register_address(pcilib, ctx->dma_bank->bar, ctx->dma_bank->read_addr);
103
 
 
104
 
        for (i = 0, n_engines = 0; i < 2 * PCILIB_MAX_DMA_ENGINES; i++) {
105
 
            char *addr = ctx->base_addr + DMA_OFFSET + i * DMA_ENGINE_PER_SIZE;
106
 
 
107
 
            memset(ctx->engines + n_engines, 0, sizeof(pcilib_nwl_engine_description_t));
108
 
 
109
 
            err = dma_nwl_read_engine_config(ctx, ctx->engines + n_engines, addr);
110
 
            if (err) continue;
111
 
            
112
 
            pcilib_set_dma_engine_description(pcilib, n_engines, (pcilib_dma_engine_description_t*)(ctx->engines + n_engines));
113
 
            ++n_engines;
114
 
        }
115
 
        pcilib_set_dma_engine_description(pcilib, n_engines, NULL);
116
 
        
117
 
        ctx->n_engines = n_engines;
118
 
        
119
 
        err = nwl_add_registers(ctx);
120
 
        if (err) {
121
 
            free(ctx);
122
 
            pcilib_error("Failed to add DMA registers");
123
 
            return NULL;
124
 
        }
125
 
    }
126
 
    return (pcilib_dma_context_t*)ctx;
127
 
}
128
 
 
129
 
void  dma_nwl_free(pcilib_dma_context_t *vctx) {
130
 
    nwl_dma_t *ctx = (nwl_dma_t*)vctx;
131
 
 
132
 
    if (ctx) {
133
 
        if (ctx->type == PCILIB_DMA_MODIFICATION_DEFAULT) dma_nwl_stop_loopback(ctx);
134
 
        dma_nwl_free_irq(ctx);
135
 
        dma_nwl_stop(vctx, PCILIB_DMA_ENGINE_ALL, PCILIB_DMA_FLAGS_DEFAULT);
136
 
            
137
 
        free(ctx);
138
 
    }
139
 
}