summaryrefslogtreecommitdiff
path: root/asoc/codecs/tas256x/algo/src/tas25xx-calib.c
diff options
context:
space:
mode:
Diffstat (limited to 'asoc/codecs/tas256x/algo/src/tas25xx-calib.c')
-rw-r--r--asoc/codecs/tas256x/algo/src/tas25xx-calib.c196
1 files changed, 196 insertions, 0 deletions
diff --git a/asoc/codecs/tas256x/algo/src/tas25xx-calib.c b/asoc/codecs/tas256x/algo/src/tas25xx-calib.c
new file mode 100644
index 00000000..3af138d3
--- /dev/null
+++ b/asoc/codecs/tas256x/algo/src/tas25xx-calib.c
@@ -0,0 +1,196 @@
+/*
+** =============================================================================
+** Copyright (c) 2017 Texas Instruments Inc.
+**
+** This program is free software; you can redistribute it and/or modify it under
+** the terms of the GNU General Public License as published by the Free Software
+** Foundation; version 2.
+**
+** This program is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
+**
+** File:
+** tas25xx-calib.c
+**
+** Description:
+** misc driver for interfacing for Texas Instruments TAS25xx algorithm
+**
+** =============================================================================
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/device.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include "algo/inc/tas_smart_amp_v2.h"
+#include "tas25xx-algo-intf.h"
+
+#define TAS_PAYLOAD_SIZE 14
+
+/* Holds the Packet data required for processing */
+struct tas_dsp_pkt {
+ u8 slave_id;
+ u8 book;
+ u8 page;
+ u8 offset;
+ u8 data[TAS_PAYLOAD_SIZE * 4];
+};
+
+static int smartamp_params_ctrl(uint8_t *input, u8 dir, u8 count)
+{
+ u32 length = count / 4;
+ u32 paramid = 0;
+ u32 index;
+ int ret = 0;
+ int special_index = 0;
+ struct tas_dsp_pkt *ppacket;
+
+ if (length >= TAS_PAYLOAD_SIZE) {
+ pr_err("TI-SmartPA: %s: Unsupported length!", __func__);
+ return -EINVAL;
+ }
+
+ ppacket = (struct tas_dsp_pkt *)kmalloc(sizeof(struct tas_dsp_pkt),
+ GFP_KERNEL);
+ if (!ppacket) {
+ pr_err("TI-SmartPA: %s: kmalloc failed!", __func__);
+ return -ENOMEM;
+ }
+
+ memset(ppacket, 0, sizeof(struct tas_dsp_pkt));
+ ret = copy_from_user(ppacket, input, sizeof(struct tas_dsp_pkt));
+ if (ret) {
+ pr_err("TI-SmartPA: %s: Error copying from user\n", __func__);
+ kfree(ppacket);
+ return -EFAULT;
+ }
+
+ index = (ppacket->page - 1) * 30 + (ppacket->offset - 8) / 4;
+ special_index = TAS_SA_IS_SPL_IDX(index);
+ pr_info("TI-SmartPA: %s: index = %d", __func__, index);
+ if (special_index == 0) {
+ if ((index < 0 || index > MAX_DSP_PARAM_INDEX)) {
+ pr_err("TI-SmartPA: %s: invalid index !\n", __func__);
+ kfree(ppacket);
+ return -EINVAL;
+ }
+ }
+ pr_info("TI-SmartPA: %s: Valid Index. special = %s\n",
+ __func__, special_index ? "Yes" : "No");
+
+ /* speakers are differentiated by slave ids */
+ if (ppacket->slave_id == SLAVE1) {
+ paramid = TAS_CALC_PARAM_IDX(index, length, CHANNEL0);
+ pr_err("TI-SmartPA: %s: Rcvd Slave id for slave 1, %x\n", __func__, ppacket->slave_id);
+ } else if (ppacket->slave_id == SLAVE2) {
+ paramid = TAS_CALC_PARAM_IDX(index, length, CHANNEL1);
+ pr_err("TI-SmartPA: %s: Rcvd Slave id for slave 2, %x\n", __func__, ppacket->slave_id);
+ } else {
+ pr_err("TI-SmartPA: %s: Wrong slaveid = %x\n",
+ __func__, ppacket->slave_id);
+ }
+
+ ret = tas25xx_smartamp_algo_ctrl(ppacket->data, paramid,
+ dir, length * 4, 0/*Default to Rx*/);
+ if (ret)
+ pr_err("TI-SmartPA: %s: %s Slave 0x%x params failed from afe, ret=%x\n",
+ __func__,
+ dir == TAS_GET_PARAM ? "get" : "set",
+ ppacket->slave_id, ret);
+ else
+ pr_info("TI-SmartPA: %s: Algo control returned %d\n",
+ __func__, ret);
+
+ if (dir == TAS_GET_PARAM) {
+ ret = copy_to_user(input, ppacket, sizeof(struct tas_dsp_pkt));
+ if (ret) {
+ pr_err("TI-SmartPA: %s: Error copying to user after DSP",
+ __func__);
+ ret = -EFAULT;
+ }
+ }
+
+ kfree(ppacket);
+ return ret;
+}
+
+static int tas_calib_open(struct inode *inode, struct file *fd)
+{
+ return 0;
+}
+
+static ssize_t tas_calib_write(struct file *file,
+ const char __user *buffer, size_t count, loff_t *offp)
+{
+ int rc = 0;
+
+ rc = smartamp_params_ctrl((uint8_t *)buffer, TAS_SET_PARAM, count);
+ return rc;
+}
+
+static ssize_t tas_calib_read(struct file *file, char __user *buffer,
+ size_t count, loff_t *ptr)
+{
+ int rc;
+
+ rc = smartamp_params_ctrl((uint8_t *)buffer, TAS_GET_PARAM, count);
+ if (rc < 0)
+ count = rc;
+ return count;
+}
+
+static long tas_calib_ioctl(struct file *filp, uint cmd, ulong arg)
+{
+ return 0;
+}
+
+static int tas_calib_release(struct inode *inode, struct file *fd)
+{
+ return 0;
+}
+
+const struct file_operations tas_calib_fops = {
+ .owner = THIS_MODULE,
+ .open = tas_calib_open,
+ .write = tas_calib_write,
+ .read = tas_calib_read,
+ .release = tas_calib_release,
+ .unlocked_ioctl = tas_calib_ioctl,
+};
+
+static struct miscdevice tas_calib_misc = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "tas_calib",
+ .fops = &tas_calib_fops,
+};
+
+int tas_calib_init(void)
+{
+ int rc;
+
+ pr_info("TI-SmartPA: %s", __func__);
+ rc = misc_register(&tas_calib_misc);
+ if (rc)
+ pr_err("TI-SmartPA: %s: register calib misc failed\n",
+ __func__);
+ return rc;
+}
+
+void tas_calib_exit(void)
+{
+ misc_deregister(&tas_calib_misc);
+}
+
+/*
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_DESCRIPTION("tas2560 Misc driver");
+MODULE_LICENSE("GPL v2");
+*/