ath9k: merge a few bugfixes
[openwrt.git] / package / lqtapi / src / mps / vmmc-alm.c
1 #include <linux/kernel.h>
2
3 #include "vmmc.h"
4 #include "vmmc-cmds.h"
5 #include "vmmc-alm.h"
6 #include "vmmc-module.h"
7 #include "mps.h"
8
9 static inline struct vmmc_alm *vmmc_module_to_alm(struct vmmc_module *module)
10 {
11         return container_of(module, struct vmmc_alm, module);
12 }
13
14 int vmmc_alm_set_state(struct vmmc_alm *alm, enum vmmc_alm_state state)
15 {
16         int ret;
17
18         ret = vmmc_command_write(alm->vmmc, VMMC_CMD_OPMODE(alm->id), &state);
19         if (!ret)
20                 alm->state = state;
21
22         return ret;
23 }
24
25 enum vmmc_alm_state vmmc_alm_get_state(struct vmmc_alm *alm)
26 {
27         return alm->state;
28 }
29
30 static struct vmmc_alm_coef *vmmc_alm_coef_alloc(unsigned int offset, size_t len)
31 {
32         struct vmmc_alm_coef *coef;
33
34         coef = kzalloc(sizeof(*coef) + sizeof(uint32_t) * DIV_ROUND_UP(len, 4),
35                         GFP_KERNEL);
36         coef->offset = offset;
37         coef->len = len;
38
39         return coef;
40 }
41
42 int vmcc_alm_set_coefficents(struct vmmc_alm *alm,
43         const struct vmmc_alm_coef *coef_list)
44 {
45         int ret = 0;
46         uint32_t cmd;
47         struct vmmc_alm_coef *coef;
48         struct list_head l;
49
50         INIT_LIST_HEAD(&l);
51
52         coef = vmmc_alm_coef_alloc(0x37, 8);
53         coef->data[0] = 0x76d7871d;
54         coef->data[1] = 0x7fbb7ff4;
55         list_add_tail(&coef->list, &l);
56         coef = vmmc_alm_coef_alloc(0x5e, 2);
57         coef->data[0] = 0x7e000000;
58         list_add_tail(&coef->list, &l);
59         coef = vmmc_alm_coef_alloc(0x6c, 2);
60         coef->data[0] = 0x7e000000;
61         list_add_tail(&coef->list, &l);
62
63         list_for_each_entry(coef, &l, list) {
64                 cmd = VMMC_CMD_ALM_COEF(alm->id, coef->offset, coef->len);
65                 ret = vmmc_command_write(alm->vmmc, cmd, coef->data);
66                 if (ret)
67                         break;
68         }
69
70         return ret;
71 }
72
73 static int vmmc_alm_sync(struct vmmc_module *module)
74 {
75         struct vmmc_alm *alm = vmmc_module_to_alm(module);
76
77         alm->cmd_cache[0] = VMMC_CMD_ALI_DATA1(1, 0, 0, 1, 0, module->pins[0], 0x4000);
78         alm->cmd_cache[1] = VMMC_CMD_ALI_DATA2(0x4000, module->pins[1], module->pins[2]);
79         alm->cmd_cache[2] = VMMC_CMD_ALI_DATA3(module->pins[3], module->pins[4]);
80
81         return vmmc_command_write(alm->vmmc, VMMC_CMD_ALI(alm->id), alm->cmd_cache);
82 }
83
84 static int vmmc_alm_enable(struct vmmc_module *module, bool enable)
85 {
86         struct vmmc_alm *alm = vmmc_module_to_alm(module);
87
88         return vmmc_command_write(alm->vmmc, VMMC_CMD_ALI(alm->id), alm->cmd_cache);
89 }
90
91 static const struct vmmc_module_ops vmmc_alm_module_ops = {
92         .sync = vmmc_alm_sync,
93         .enable = vmmc_alm_enable,
94 };
95
96 int vmmc_alm_init(struct vmmc_alm *alm, struct vmmc *vmmc, unsigned int id)
97 {
98         int ret;
99
100         ret = vmmc_module_init(&alm->module, 5, &vmmc_alm_module_ops);
101         if (ret)
102                 return ret;
103
104         alm->id = id;
105         alm->module.id = id + 0x4;
106         alm->vmmc = vmmc;
107
108         alm->cmd_cache[0] = VMMC_CMD_ALI_DATA1(1, 0, 0, 1, 0, 0, 0x2000);
109         alm->cmd_cache[1] = VMMC_CMD_ALI_DATA2(0x2000, 0, 0);
110         alm->cmd_cache[2] = VMMC_CMD_ALI_DATA3(0, 0);
111
112         vmmc_command_write(alm->vmmc, VMMC_CMD_ALI(alm->id), alm->cmd_cache);
113         vmcc_alm_set_coefficents(alm, NULL);
114         vmmc_register_module(vmmc, &alm->module);
115
116 // disable lec
117 // write lec coef
118 // write nlp coef
119 // enable lec
120
121 // ALI_LEC ALI_ES RES_LEC_COEF RES_LEC_NLP_COEF
122
123         return ret;
124 }
125
126 void vmmc_alm_hook_event_handler(struct vmmc *vmmc, uint32_t id, uint32_t data)
127 {
128         tapi_report_hook_event(&vmmc->tdev, &vmmc->tdev.ports[id], data & 1);
129 }