aboutsummaryrefslogtreecommitdiffstats
path: root/package/lqtapi/src/mps/vmmc-alm.c
diff options
context:
space:
mode:
Diffstat (limited to 'package/lqtapi/src/mps/vmmc-alm.c')
-rw-r--r--package/lqtapi/src/mps/vmmc-alm.c129
1 files changed, 129 insertions, 0 deletions
diff --git a/package/lqtapi/src/mps/vmmc-alm.c b/package/lqtapi/src/mps/vmmc-alm.c
new file mode 100644
index 0000000000..828376fb91
--- /dev/null
+++ b/package/lqtapi/src/mps/vmmc-alm.c
@@ -0,0 +1,129 @@
+#include <linux/kernel.h>
+
+#include "vmmc.h"
+#include "vmmc-cmds.h"
+#include "vmmc-alm.h"
+#include "vmmc-module.h"
+#include "mps.h"
+
+static inline struct vmmc_alm *vmmc_module_to_alm(struct vmmc_module *module)
+{
+ return container_of(module, struct vmmc_alm, module);
+}
+
+int vmmc_alm_set_state(struct vmmc_alm *alm, enum vmmc_alm_state state)
+{
+ int ret;
+
+ ret = vmmc_command_write(alm->vmmc, VMMC_CMD_OPMODE(alm->id), &state);
+ if (!ret)
+ alm->state = state;
+
+ return ret;
+}
+
+enum vmmc_alm_state vmmc_alm_get_state(struct vmmc_alm *alm)
+{
+ return alm->state;
+}
+
+static struct vmmc_alm_coef *vmmc_alm_coef_alloc(unsigned int offset, size_t len)
+{
+ struct vmmc_alm_coef *coef;
+
+ coef = kzalloc(sizeof(*coef) + sizeof(uint32_t) * DIV_ROUND_UP(len, 4),
+ GFP_KERNEL);
+ coef->offset = offset;
+ coef->len = len;
+
+ return coef;
+}
+
+int vmcc_alm_set_coefficents(struct vmmc_alm *alm,
+ const struct vmmc_alm_coef *coef_list)
+{
+ int ret = 0;
+ uint32_t cmd;
+ struct vmmc_alm_coef *coef;
+ struct list_head l;
+
+ INIT_LIST_HEAD(&l);
+
+ coef = vmmc_alm_coef_alloc(0x37, 8);
+ coef->data[0] = 0x76d7871d;
+ coef->data[1] = 0x7fbb7ff4;
+ list_add_tail(&coef->list, &l);
+ coef = vmmc_alm_coef_alloc(0x5e, 2);
+ coef->data[0] = 0x7e000000;
+ list_add_tail(&coef->list, &l);
+ coef = vmmc_alm_coef_alloc(0x6c, 2);
+ coef->data[0] = 0x7e000000;
+ list_add_tail(&coef->list, &l);
+
+ list_for_each_entry(coef, &l, list) {
+ cmd = VMMC_CMD_ALM_COEF(alm->id, coef->offset, coef->len);
+ ret = vmmc_command_write(alm->vmmc, cmd, coef->data);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
+static int vmmc_alm_sync(struct vmmc_module *module)
+{
+ struct vmmc_alm *alm = vmmc_module_to_alm(module);
+
+ alm->cmd_cache[0] = VMMC_CMD_ALI_DATA1(1, 0, 0, 1, 0, module->pins[0], 0x4000);
+ alm->cmd_cache[1] = VMMC_CMD_ALI_DATA2(0x4000, module->pins[1], module->pins[2]);
+ alm->cmd_cache[2] = VMMC_CMD_ALI_DATA3(module->pins[3], module->pins[4]);
+
+ return vmmc_command_write(alm->vmmc, VMMC_CMD_ALI(alm->id), alm->cmd_cache);
+}
+
+static int vmmc_alm_enable(struct vmmc_module *module, bool enable)
+{
+ struct vmmc_alm *alm = vmmc_module_to_alm(module);
+
+ return vmmc_command_write(alm->vmmc, VMMC_CMD_ALI(alm->id), alm->cmd_cache);
+}
+
+static const struct vmmc_module_ops vmmc_alm_module_ops = {
+ .sync = vmmc_alm_sync,
+ .enable = vmmc_alm_enable,
+};
+
+int vmmc_alm_init(struct vmmc_alm *alm, struct vmmc *vmmc, unsigned int id)
+{
+ int ret;
+
+ ret = vmmc_module_init(&alm->module, 5, &vmmc_alm_module_ops);
+ if (ret)
+ return ret;
+
+ alm->id = id;
+ alm->module.id = id + 0x4;
+ alm->vmmc = vmmc;
+
+ alm->cmd_cache[0] = VMMC_CMD_ALI_DATA1(1, 0, 0, 1, 0, 0, 0x2000);
+ alm->cmd_cache[1] = VMMC_CMD_ALI_DATA2(0x2000, 0, 0);
+ alm->cmd_cache[2] = VMMC_CMD_ALI_DATA3(0, 0);
+
+ vmmc_command_write(alm->vmmc, VMMC_CMD_ALI(alm->id), alm->cmd_cache);
+ vmcc_alm_set_coefficents(alm, NULL);
+ vmmc_register_module(vmmc, &alm->module);
+
+// disable lec
+// write lec coef
+// write nlp coef
+// enable lec
+
+// ALI_LEC ALI_ES RES_LEC_COEF RES_LEC_NLP_COEF
+
+ return ret;
+}
+
+void vmmc_alm_hook_event_handler(struct vmmc *vmmc, uint32_t id, uint32_t data)
+{
+ tapi_report_hook_event(&vmmc->tdev, &vmmc->tdev.ports[id], data & 1);
+}