oleavr-rgl-a500-mini-linux-.../drivers/media/platform/sunxi-vin/utility/vin_os.c
Ole André Vadla Ravnås 169c65d57e Initial commit
2022-05-07 01:01:45 +02:00

183 lines
4.6 KiB
C

/*
******************************************************************************
*
* vfe_os.c
*
* Hawkview ISP - vfe_os.c module
*
* Copyright (c) 2015 by Allwinnertech Co., Ltd. http://www.allwinnertech.com
*
* Version Author Date Description
*
* 3.0 Yang Feng 2015/12/02 ISP Tuning Tools Support
*
******************************************************************************
*/
#include <linux/module.h>
#include "vin_os.h"
unsigned int vin_log_mask;
EXPORT_SYMBOL_GPL(vin_log_mask);
int os_gpio_set(struct gpio_config *gc)
{
#ifndef FPGA_VER
char pin_name[32];
__u32 config;
if (gc == NULL)
return -1;
if (gc->gpio == GPIO_INDEX_INVALID)
return -1;
if (!IS_AXP_PIN(gc->gpio)) {
/* valid pin of sunxi-pinctrl,
* config pin attributes individually.
*/
sunxi_gpio_to_name(gc->gpio, pin_name);
config =
SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC, gc->mul_sel);
pin_config_set(SUNXI_PINCTRL, pin_name, config);
if (gc->pull != GPIO_PULL_DEFAULT) {
config =
SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_PUD, gc->pull);
pin_config_set(SUNXI_PINCTRL, pin_name, config);
}
if (gc->drv_level != GPIO_DRVLVL_DEFAULT) {
config =
SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_DRV,
gc->drv_level);
pin_config_set(SUNXI_PINCTRL, pin_name, config);
}
if (gc->data != GPIO_DATA_DEFAULT) {
config =
SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_DAT, gc->data);
pin_config_set(SUNXI_PINCTRL, pin_name, config);
}
} else {
/* valid pin of axp-pinctrl,
* config pin attributes individually.
*/
sunxi_gpio_to_name(gc->gpio, pin_name);
config =
SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_FUNC, gc->mul_sel);
pin_config_set(AXP_PINCTRL, pin_name, config);
if (gc->data != GPIO_DATA_DEFAULT) {
config =
SUNXI_PINCFG_PACK(SUNXI_PINCFG_TYPE_DAT, gc->data);
pin_config_set(AXP_PINCTRL, pin_name, config);
}
}
#endif
return 0;
}
EXPORT_SYMBOL_GPL(os_gpio_set);
int os_gpio_write(u32 gpio, __u32 out_value, int force_value_flag)
{
#ifndef FPGA_VER
if (gpio == GPIO_INDEX_INVALID)
return 0;
if (1 == force_value_flag) {
gpio_direction_output(gpio, 0);
__gpio_set_value(gpio, out_value);
} else {
if (out_value == 0) {
gpio_direction_output(gpio, 0);
__gpio_set_value(gpio, out_value);
} else {
gpio_direction_input(gpio);
}
}
#endif
return 0;
}
EXPORT_SYMBOL_GPL(os_gpio_write);
int os_mem_alloc(struct device *dev, struct vin_mm *mem_man)
{
#ifdef SUNXI_MEM
int ret = -1;
char *ion_name = "ion_vfe";
mem_man->client = sunxi_ion_client_create(ion_name);
if (IS_ERR_OR_NULL(mem_man->client)) {
vin_err("sunxi_ion_client_create failed!!");
goto err_client;
}
mem_man->handle = ion_alloc(mem_man->client, mem_man->size, PAGE_SIZE,
ION_HEAP_CARVEOUT_MASK |
ION_HEAP_TYPE_DMA_MASK, 0);
if (IS_ERR_OR_NULL(mem_man->handle)) {
vin_err("ion_alloc failed!!");
goto err_alloc;
}
mem_man->vir_addr = ion_map_kernel(mem_man->client, mem_man->handle);
if (IS_ERR_OR_NULL(mem_man->vir_addr)) {
vin_err("ion_map_kernel failed!!");
goto err_map_kernel;
}
ret =
ion_phys(mem_man->client, mem_man->handle,
(ion_phys_addr_t *)&mem_man->phy_addr, &mem_man->size);
if (ret) {
vin_err("ion_phys failed!!");
goto err_phys;
}
mem_man->dma_addr =
mem_man->phy_addr + HW_DMA_OFFSET - CPU_DRAM_PADDR_ORG;
return 0;
err_phys:
ion_unmap_kernel(mem_man->client, mem_man->handle);
err_map_kernel:
ion_free(mem_man->client, mem_man->handle);
err_alloc:
ion_client_destroy(mem_man->client);
err_client:
return -1;
#else
mem_man->vir_addr = dma_alloc_coherent(dev, (size_t) mem_man->size,
(dma_addr_t *)&mem_man->phy_addr,
GFP_KERNEL);
if (!mem_man->vir_addr) {
vin_err("dma_alloc_coherent memory alloc failed\n");
return -ENOMEM;
}
#if defined(CONFIG_SUNXI_IOMMU)
mem_man->dma_addr = mem_man->phy_addr;
#else
mem_man->dma_addr =
mem_man->phy_addr + HW_DMA_OFFSET - CPU_DRAM_PADDR_ORG;
#endif
return 0;
#endif
}
EXPORT_SYMBOL_GPL(os_mem_alloc);
void os_mem_free(struct device *dev, struct vin_mm *mem_man)
{
#ifdef SUNXI_MEM
if (IS_ERR_OR_NULL(mem_man->client) || IS_ERR_OR_NULL(mem_man->handle)
|| IS_ERR_OR_NULL(mem_man->vir_addr))
return;
ion_unmap_kernel(mem_man->client, mem_man->handle);
ion_free(mem_man->client, mem_man->handle);
ion_client_destroy(mem_man->client);
#else
if (mem_man->vir_addr)
dma_free_coherent(dev, mem_man->size, mem_man->vir_addr,
(dma_addr_t) mem_man->phy_addr);
#endif
mem_man->phy_addr = NULL;
mem_man->dma_addr = NULL;
mem_man->vir_addr = NULL;
}
EXPORT_SYMBOL_GPL(os_mem_free);
MODULE_AUTHOR("raymonxiu");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("Video front end OSAL for sunxi");