]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - tas256xsw-android/tas2563-android-driver.git/blob - tas2563-misc.c
Add readme for reference
[tas256xsw-android/tas2563-android-driver.git] / tas2563-misc.c
1 /*
2 ** =============================================================================
3 ** Copyright (c) 2016  Texas Instruments Inc.
4 **
5 ** This program is free software; you can redistribute it and/or modify it under
6 ** the terms of the GNU General Public License as published by the Free Software
7 ** Foundation; version 2.
8 **
9 ** This program is distributed in the hope that it will be useful, but WITHOUT
10 ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 ** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 **
13 ** File:
14 **     tas2563-misc.c
15 **
16 ** Description:
17 **     misc driver for Texas Instruments TAS2563 High Performance 4W Smart Amplifier
18 **
19 ** =============================================================================
20 */
22 #ifdef CONFIG_TAS2563_MISC
24 #define DEBUG
25 #include <linux/module.h>
26 #include <linux/moduleparam.h>
27 #include <linux/init.h>
28 #include <linux/delay.h>
29 #include <linux/pm.h>
30 #include <linux/i2c.h>
31 #include <linux/gpio.h>
32 #include <linux/regulator/consumer.h>
33 #include <linux/firmware.h>
34 #include <linux/regmap.h>
35 #include <linux/of.h>
36 #include <linux/of_gpio.h>
37 #include <linux/slab.h>
38 #include <linux/syscalls.h>
39 #include <linux/fcntl.h>
40 #include <linux/miscdevice.h>
41 #include <linux/uaccess.h>
43 #include "tas2563.h"
44 #include "tas2563-misc.h"
45 #include <linux/dma-mapping.h>
47 static int g_logEnable = 1;
48 static struct tas2563_priv *g_tas2563;
50 static int tas2563_file_open(struct inode *inode, struct file *file)
51 {
52         struct tas2563_priv *pTAS2563 = g_tas2563;
54         if (!try_module_get(THIS_MODULE))
55                 return -ENODEV;
57         file->private_data = (void *)pTAS2563;
58         if (g_logEnable)
59                 dev_info(pTAS2563->dev, "%s\n", __func__);
60         return 0;
61 }
63 static int tas2563_file_release(struct inode *inode, struct file *file)
64 {
65         struct tas2563_priv *pTAS2563 = (struct tas2563_priv *)file->private_data;
67         if (g_logEnable)
68                 dev_info(pTAS2563->dev, "%s\n", __func__);
69         file->private_data = (void *)NULL;
70         module_put(THIS_MODULE);
72         return 0;
73 }
75 static ssize_t tas2563_file_read(struct file *file, char *buf, size_t count, loff_t *ppos)
76 {
77         struct tas2563_priv *pTAS2563 = (struct tas2563_priv *)file->private_data;
78         int ret = 0;
79         unsigned int nValue = 0;
80         unsigned char value = 0;
81         unsigned char *p_kBuf = NULL;
83         mutex_lock(&pTAS2563->file_lock);
85         switch (pTAS2563->mnDBGCmd) {
86         case TIAUDIO_CMD_REG_READ: {
87                 if (g_logEnable)
88                         dev_info(pTAS2563->dev, "TIAUDIO_CMD_REG_READ: current_reg = 0x%x, count=%d\n",
89                                 pTAS2563->mnCurrentReg, (int)count);
90                 if (count == 1) {
91                         ret = pTAS2563->read(pTAS2563, pTAS2563->mnCurrentReg, &nValue);
92                         if (ret < 0)
93                                 break;
95                         value = (u8)nValue;
96                         if (g_logEnable)
97                                 dev_info(pTAS2563->dev, "TIAUDIO_CMD_REG_READ: nValue=0x%x, value=0x%x\n", nValue, value);
98                         ret = copy_to_user(buf, &value, 1);
99                         if (ret != 0) {
100                                 /* Failed to copy all the data, exit */
101                                 dev_err(pTAS2563->dev, "copy to user fail %d\n", ret);
102                         }
103                 } else if (count > 1) {
104                         p_kBuf = kzalloc(count, GFP_KERNEL);
105                         if (p_kBuf != NULL) {
106                                 ret = pTAS2563->bulk_read(pTAS2563, pTAS2563->mnCurrentReg, p_kBuf, count);
107                                 if (ret < 0)
108                                         break;
109                                 ret = copy_to_user(buf, p_kBuf, count);
110                                 if (ret != 0) {
111                                         /* Failed to copy all the data, exit */
112                                         dev_err(pTAS2563->dev, "copy to user fail %d\n", ret);
113                                 }
114                                 kfree(p_kBuf);
115                         } else
116                                 dev_err(pTAS2563->dev, "read no mem\n");
117                 }
118         }
119         break;
121         }
122         pTAS2563->mnDBGCmd = 0;
124         mutex_unlock(&pTAS2563->file_lock);
125         return count;
128 static ssize_t tas2563_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
130         struct tas2563_priv *pTAS2563 = (struct tas2563_priv *)file->private_data;
131         int ret = 0;
132         unsigned char *p_kBuf = NULL;
133         unsigned int reg = 0;
134         unsigned int len = 0;
136         mutex_lock(&pTAS2563->file_lock);
138         p_kBuf = kzalloc(count, GFP_KERNEL);
139         if (p_kBuf == NULL) {
140                 dev_err(pTAS2563->dev, "write no mem\n");
141                 goto err;
142         }
144         ret = copy_from_user(p_kBuf, buf, count);
145         if (ret != 0) {
146                 dev_err(pTAS2563->dev, "copy_from_user failed.\n");
147                 goto err;
148         }
150         pTAS2563->mnDBGCmd = p_kBuf[0];
151         switch (pTAS2563->mnDBGCmd) {
152         case TIAUDIO_CMD_REG_WITE:
153                 if (count > 5) {
154                         reg = ((unsigned int)p_kBuf[1] << 24)
155                                 + ((unsigned int)p_kBuf[2] << 16)
156                                 + ((unsigned int)p_kBuf[3] << 8)
157                                 + (unsigned int)p_kBuf[4];
158                         len = count - 5;
159                         if (len == 1) {
160                                 ret = pTAS2563->write(pTAS2563, reg, p_kBuf[5]);
161                                 if (g_logEnable)
162                                         dev_info(pTAS2563->dev, "TIAUDIO_CMD_REG_WITE, Reg=0x%x, Val=0x%x\n", reg, p_kBuf[5]);
163                         } else
164                                 ret = pTAS2563->bulk_write(pTAS2563, reg, &p_kBuf[5], len);
165                 } else
166                         dev_err(pTAS2563->dev, "%s, write len fail, count=%d.\n", __func__, (int)count);
167                 pTAS2563->mnDBGCmd = 0;
168         break;
170         case TIAUDIO_CMD_REG_READ:
171                 if (count == 5) {
172                         pTAS2563->mnCurrentReg = ((unsigned int)p_kBuf[1] << 24)
173                                 + ((unsigned int)p_kBuf[2] << 16)
174                                 + ((unsigned int)p_kBuf[3] << 8)
175                                 + (unsigned int)p_kBuf[4];
176                         if (g_logEnable)
177                                 dev_info(pTAS2563->dev, "TIAUDIO_CMD_REG_READ whole=0x%x\n", pTAS2563->mnCurrentReg);
178                 } else
179                         dev_err(pTAS2563->dev, "read len fail.\n");
180         break;
181         }
183 err:
184         if (p_kBuf != NULL)
185                 kfree(p_kBuf);
187         mutex_unlock(&pTAS2563->file_lock);
189         return count;
192 static const struct file_operations fops = {
193         .owner = THIS_MODULE,
194         .read = tas2563_file_read,
195         .write = tas2563_file_write,
196         .unlocked_ioctl = NULL,
197         .open = tas2563_file_open,
198         .release = tas2563_file_release,
199 };
201 #define MODULE_NAME     "tas2563"
202 static struct miscdevice tas2563_misc = {
203         .minor = MISC_DYNAMIC_MINOR,
204         .name = MODULE_NAME,
205         .fops = &fops,
206 };
208 int tas2563_register_misc(struct tas2563_priv *pTAS2563)
210         int ret = 0;
212         g_tas2563 = pTAS2563;
214         ret = misc_register(&tas2563_misc);
215         if (ret)
216                 dev_err(pTAS2563->dev, "TAS2563 misc fail: %d\n", ret);
218         dev_info(pTAS2563->dev, "%s, leave\n", __func__);
220         return ret;
223 int tas2563_deregister_misc(struct tas2563_priv *pTAS2563)
225         misc_deregister(&tas2563_misc);
226         return 0;
229 MODULE_AUTHOR("Texas Instruments Inc.");
230 MODULE_DESCRIPTION("TAS2563 Misc Smart Amplifier driver");
231 MODULE_LICENSE("GPL v2");
232 #endif