sdk-hwV1.3/lichee/linux-4.9/sound/soc/sunxi/sunxi-aio/mpp-aio.c

267 lines
6.7 KiB
C
Raw Normal View History

2024-05-07 10:09:20 +00:00
/*
* sound/soc/sunxi/sunxi-aio/aio.c
* (C) Copyright 2016-2018
* Allwinner Technology Co., Ltd. <www.allwinnertech.com>
*
* zhangjingzhou <zhangjingzhou@allwinnertech.com>
* yumingfeng <yumingfeng@allwinnertech.com>
*
* Driver for embedded vision engine(AIO).
*
* 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; either version 2 of
* the License, or (at your option) any later version.
*
*/
#include "mpp-aio.h"
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/ctype.h>
#include <linux/signal.h>
#include <linux/mpp.h>
struct sunxi_audio_mpp_debugfs *mpp_audio_debugfs;
EXPORT_SYMBOL(mpp_audio_debugfs);
static int aio_write_to_usr(char __user *dst, char *src, size_t count, loff_t *ppos)
{
int len = strlen(src);
if (len) {
if (*ppos >= len)
return 0;
if (count >= len)
count = len;
if (count > (len - *ppos))
count = (len - *ppos);
if (copy_to_user(dst, src, count)) {
pr_warn("copy_to_user fail\n");
return 0;
}
*ppos += count;
} else {
count = 0;
}
return count;
}
static int aio_info_get(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
{
int wr_cnt = 0;
char info[1024];
sprintf(info, "%s%s%s%s%s%s%s%s%s\n%s%s%s%s%s%s%s%s%s",
mpp_audio_debugfs->ai_info,
mpp_audio_debugfs->ai_devenable,
mpp_audio_debugfs->ai_channelcnt,
mpp_audio_debugfs->ai_cardtype,
mpp_audio_debugfs->ai_samplerate,
mpp_audio_debugfs->ai_bitwidth,
mpp_audio_debugfs->ai_trackcnt,
mpp_audio_debugfs->ai_bMute,
mpp_audio_debugfs->ai_volume,
mpp_audio_debugfs->ao_info,
mpp_audio_debugfs->ao_devenable,
mpp_audio_debugfs->ao_channelcnt,
mpp_audio_debugfs->ao_cardtype,
mpp_audio_debugfs->ao_samplerate,
mpp_audio_debugfs->ao_bitwidth,
mpp_audio_debugfs->ao_trackcnt,
mpp_audio_debugfs->ao_bMute,
mpp_audio_debugfs->ao_volume);
wr_cnt = aio_write_to_usr(buf, info, count, ppos);
return wr_cnt;
}
static int aio_info_set(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
char info[64] = {0};
char *dst_ptr;
int match_flag = 1;
if (count > 64) {
pr_warn("copy_from_user fail, count:%d too big!\n", count);
return count;
}
if (copy_from_user(info, buf, count)) {
pr_warn("copy_from_user fail\n");
return 0;
}
switch (info[0]) {
case '0':
dst_ptr = mpp_audio_debugfs->ai_devenable;
break;
case '1':
dst_ptr = mpp_audio_debugfs->ai_channelcnt;
break;
case '2':
dst_ptr = mpp_audio_debugfs->ai_cardtype;
break;
case '3':
dst_ptr = mpp_audio_debugfs->ai_samplerate;
break;
case '4':
dst_ptr = mpp_audio_debugfs->ai_bitwidth;
break;
case '5':
dst_ptr = mpp_audio_debugfs->ai_trackcnt;
break;
case '6':
dst_ptr = mpp_audio_debugfs->ai_bMute;
break;
case '7':
dst_ptr = mpp_audio_debugfs->ai_volume;
break;
case '8':
dst_ptr = mpp_audio_debugfs->ao_devenable;
break;
case '9':
dst_ptr = mpp_audio_debugfs->ao_channelcnt;
break;
case 'a':
dst_ptr = mpp_audio_debugfs->ao_cardtype;
break;
case 'b':
dst_ptr = mpp_audio_debugfs->ao_samplerate;
break;
case 'c':
dst_ptr = mpp_audio_debugfs->ao_bitwidth;
break;
case 'd':
dst_ptr = mpp_audio_debugfs->ao_trackcnt;
break;
case 'e':
dst_ptr = mpp_audio_debugfs->ao_bMute;
break;
case 'f':
dst_ptr = mpp_audio_debugfs->ao_volume;
break;
default:
pr_warn("unknown aio debugfs setting[%s]!\n", info);
pr_warn("MUST be: echo x[0,f] yz > path!\n");
match_flag = 0;
break;
}
while ((*dst_ptr != '\0') && (*dst_ptr != ':'))
++dst_ptr;
if (match_flag && strlen(info) < 15)
snprintf(dst_ptr + 2, strlen(info), "%s", info + 2);
else
pr_warn("update fail! match_flag:%d, strlen: %d\n", match_flag, strlen(info));
return count;
}
int mpp_aio_info_set(char *dst_ptr, unsigned int size, unsigned int value)
{
unsigned int count = 0;
if (dst_ptr == NULL) {
pr_err("[%s] dst_ptr is NULL!\n", __func__);
return -EINVAL;
}
while ((*dst_ptr != '\0') && (*dst_ptr != ':')) {
count++;
++dst_ptr;
}
if (size <= 64)
snprintf(dst_ptr + 2, size-count, "%u\n", value);
else
pr_warn("update fail! [size-count]:%d, strlen(dst_ptr): %d\n",
size-count, strlen(dst_ptr));
return 0;
}
static int aio_info_open(struct inode *inode, struct file *file)
{
return 0;
}
static int aio_info_release(struct inode *inode, struct file *file)
{
return 0;
}
static const struct file_operations info_ops = {
.write = aio_info_set,
.read = aio_info_get,
.open = aio_info_open,
.release = aio_info_release,
};
static int __init debugfs_aio_init(void)
{
#ifdef CONFIG_SUNXI_MPP
mpp_audio_debugfs = kzalloc(sizeof(struct sunxi_audio_mpp_debugfs), GFP_KERNEL);
if (mpp_audio_debugfs)
mpp_audio_debugfs->debugfsP = debugfs_create_file("sunxi-aio", 0644, debugfs_mpp_root, NULL, &info_ops);
else {
mpp_audio_debugfs = NULL;
pr_err("[%s] can not malloc mpp_audio_debugfs", __func__);
}
if (mpp_audio_debugfs) {
/* ai dev attr */
mpp_audio_debugfs->ai_info = "-----------AI Dev ATTR(V1.0)---------------\n";
strcpy(mpp_audio_debugfs->ai_devenable, "ai_enable: 0\n");
strcpy(mpp_audio_debugfs->ai_channelcnt, "ai_chncnt: 0\n");
strcpy(mpp_audio_debugfs->ai_cardtype, "ai_cardtype[0-codec; 1-linein]: 0\n");
strcpy(mpp_audio_debugfs->ai_samplerate, "ai_samplerate: 0\n");
strcpy(mpp_audio_debugfs->ai_bitwidth, "ai_bitwidth: 0\n");
strcpy(mpp_audio_debugfs->ai_trackcnt, "ai_trackcnt: 0\n");
strcpy(mpp_audio_debugfs->ai_bMute, "ai_bMute: 0\n");
strcpy(mpp_audio_debugfs->ai_volume, "ai_volume: 0\n");
/* ao dev attr */
mpp_audio_debugfs->ao_info = "-----------AO Dev ATTR(V1.0)---------------\n";
strcpy(mpp_audio_debugfs->ao_devenable, "ao_enable: 0\n");
strcpy(mpp_audio_debugfs->ao_channelcnt, "ao_chncnt: 0\n");
strcpy(mpp_audio_debugfs->ao_cardtype, "ao_cardtype[0-codec; 1-hdmi]: 0\n");
strcpy(mpp_audio_debugfs->ao_samplerate, "ao_samplerate: 0\n");
strcpy(mpp_audio_debugfs->ao_bitwidth, "ao_bitwidth: 0\n");
strcpy(mpp_audio_debugfs->ao_trackcnt, "ao_trackcnt: 0\n");
strcpy(mpp_audio_debugfs->ao_bMute, "ao_bMute: 0\n");
strcpy(mpp_audio_debugfs->ao_volume, "ao_volume: 0\n");
}
#else
mpp_audio_debugfs = NULL;
#endif
return 0;
}
module_init(debugfs_aio_init);
static void __exit debugfs_aio_exit(void)
{
#ifdef CONFIG_SUNXI_MPP
if (mpp_audio_debugfs) {
if (mpp_audio_debugfs->debugfsP)
debugfs_remove_recursive(mpp_audio_debugfs->debugfsP);
kfree(mpp_audio_debugfs);
}
#endif
}
module_exit(debugfs_aio_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("zhangjingzhou<zhangjingzhou@allwinnertech.com>");
MODULE_DESCRIPTION("AIO debuginfo driver");
MODULE_VERSION("1.0");
MODULE_ALIAS("platform:AIO(AW1721)");