1
0
mirror of https://github.com/physwizz/a155-U-u1.git synced 2025-07-03 17:37:33 +00:00
Files
physwizz 99537be4e2 first
2024-03-11 06:53:12 +11:00

178 lines
4.2 KiB
C

// SPDX-License-Identifier: GPL-2.0
//
// mtk-mmap-ion.c -- Mediatek Audio MMAP Get ION Buffer
//
// Copyright (c) 2017 MediaTek Inc.
// Author: Chih-Hao Chang <chih-hao.chang@mediatek.com>
#include <linux/io.h>
#include "mtk-mmap-ion.h"
#include <linux/dma-buf.h>
#include <linux/module.h>
#include <linux/slab.h>
static void *dl_alloc_vaddr;
static void *ul_alloc_vaddr;
static unsigned long dl_phy_addr;
static unsigned long ul_phy_addr;
static void *dl_vir_addr;
static void *ul_vir_addr;
static size_t dl_size;
static size_t ul_size;
static int dl_fd;
static int ul_fd;
struct device *dmabuf_dev;
int mtk_get_mmap_dl_fd(void)
{
return dl_fd;
}
EXPORT_SYMBOL_GPL(mtk_get_mmap_dl_fd);
int mtk_get_mmap_ul_fd(void)
{
return ul_fd;
}
EXPORT_SYMBOL_GPL(mtk_get_mmap_ul_fd);
void mtk_get_mmap_dl_buffer(unsigned long *phy_addr, void **vir_addr)
{
*phy_addr = dl_phy_addr;
*vir_addr = dl_vir_addr;
}
EXPORT_SYMBOL_GPL(mtk_get_mmap_dl_buffer);
void mtk_get_mmap_ul_buffer(unsigned long *phy_addr, void **vir_addr)
{
*phy_addr = ul_phy_addr;
*vir_addr = ul_vir_addr;
}
EXPORT_SYMBOL_GPL(mtk_get_mmap_ul_buffer);
static struct sg_table *mtk_map_dma_buf(struct dma_buf_attachment *attachment,
enum dma_data_direction dir)
{
return NULL;
}
static void mtk_unmap_dma_buf(struct dma_buf_attachment *attachment,
struct sg_table *table,
enum dma_data_direction dir)
{
}
static void mtk_release(struct dma_buf *dmabuf)
{
}
static int mtk_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
{
int ret;
void *vaddr = dmabuf->priv;
unsigned long size = vma->vm_end - vma->vm_start;
// check size
size = (size > dmabuf->size) ? dmabuf->size : size;
// nocached
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
ret = remap_pfn_range(vma, vma->vm_start, virt_to_pfn(vaddr),
size, vma->vm_page_prot);
dev_info(dmabuf_dev, "%s(), ret %d, %p, %p, size %ld %ld\n",
__func__, ret, vaddr, vma->vm_start, size, dmabuf->size);
return ret;
}
static const struct dma_buf_ops exp_dmabuf_ops = {
.map_dma_buf = mtk_map_dma_buf,
.unmap_dma_buf = mtk_unmap_dma_buf,
.release = mtk_release,
.mmap = mtk_mmap, // for user space
};
static struct dma_buf *mtk_dma_buf_init(struct device *dev, void **vaddr)
{
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
struct dma_buf *dmabuf;
dmabuf_dev = dev;
if (*vaddr == NULL) {
dev_info(dev, "%s(), kazlloc()\n", __func__);
*vaddr = kzalloc(MMAP_BUFFER_SIZE, GFP_KERNEL);
if (!(*vaddr)) {
dev_info(dev, "%s() kzalloc fail!!\n", __func__);
return NULL;
}
}
exp_info.ops = &exp_dmabuf_ops;
exp_info.size = MMAP_BUFFER_SIZE;
exp_info.flags = O_RDWR;
exp_info.priv = *vaddr;
dev_info(dev, "%s(), priv %p %p\n", __func__, *vaddr, exp_info.priv);
dmabuf = dma_buf_export(&exp_info);
if (IS_ERR_OR_NULL(dmabuf)) {
dev_info(dev, "%s() couldn't export dma_buf", __func__);
kfree(vaddr);
return NULL;
}
return dmabuf;
}
int mtk_exporter_init(struct device *dev)
{
struct dma_buf *dmabuf;
dev_info(dev, "%s(), dl_alloc_vaddr %p, ul_alloc_vaddr %p\n",
__func__, dl_alloc_vaddr, ul_alloc_vaddr);
// for DL
dmabuf = mtk_dma_buf_init(dev, &dl_alloc_vaddr);
if (dmabuf != NULL) {
//dev_info(dev, "+%s() for DL, addr %p, phy_addr %ld, size %zu, fd %d\n",
// __func__, dl_vir_addr, dl_phy_addr, dl_size, dl_fd);
dl_vir_addr = dl_alloc_vaddr;
dl_phy_addr = __pa(dl_vir_addr);
dl_size = MMAP_BUFFER_SIZE;
dl_fd = dma_buf_fd(dmabuf, O_CLOEXEC);
dev_info(dev, "-%s() for DL, addr %p, phy_addr %ld, size %zu, fd %d\n",
__func__, dl_vir_addr, dl_phy_addr, dl_size, dl_fd);
}
// for UL
dmabuf = mtk_dma_buf_init(dev, &ul_alloc_vaddr);
if (dmabuf != NULL) {
//dev_info(dev, "+%s() for UL, addr %p, phy_addr %ld, size %zu, fd %d\n",
// __func__, ul_vir_addr, ul_phy_addr, ul_size, ul_fd);
ul_vir_addr = ul_alloc_vaddr;
ul_phy_addr = __pa(ul_vir_addr);
ul_size = MMAP_BUFFER_SIZE;
ul_fd = dma_buf_fd(dmabuf, O_CLOEXEC);
dev_info(dev, "-%s() for UL, addr %p, phy_addr %ld, size %zu, fd %d\n",
__func__, ul_vir_addr, ul_phy_addr, ul_size, ul_fd);
}
return 0;
}
EXPORT_SYMBOL_GPL(mtk_exporter_init);
MODULE_DESCRIPTION("Mediatek Smart Phone PCM Operation");
MODULE_AUTHOR("Chih-Hao Chang <chih-hao.chang@mediatek.com>");
MODULE_LICENSE("GPL v2");