/******************************************************************************
版权所有：    @copyright (C) 2024-2034 HaiYang Technology Corp. All rights reserved.
文件名称：    bsp_ccu.c
文件版本：    01.01
创建作者:     zhaoyang
创建日期：    2025-07-28
功能说明：    CCU模块驱动程序。
其它说明：
修改记录：
*/
#include "bsp_ccu.h"
#include <stddef.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>

int g_ccu_fd = -1;
unsigned g_ccu_mapped_size;
void *g_ccu_map_base, *g_ccu_virt_addr = NULL;

/******************************************************************************
函数名称：    ccu_init
函数版本：    01.01
创建作者：    zhaoyang
创建日期：    2025-07-28
函数说明：    映射CCU寄存器地址空间。
参数说明：    无
返回值：      无
修改记录：
*/
int ccu_init(void)
{
    // unsigned long read_result;
    off_t target;
	unsigned page_size, offset_in_page;
    unsigned width = 8 * sizeof(int);
    target = CCU_BASE;
    // 获取页面大小
    g_ccu_mapped_size = page_size = sysconf(_SC_PAGESIZE);
    offset_in_page = (unsigned)target & (page_size - 1);
    if (offset_in_page + width > page_size) {
		/* This access spans pages.
		 * Must map two pages to make it possible: */
		g_ccu_mapped_size *= 2;
	}

    g_ccu_fd = open("/dev/mem",  O_RDWR | O_SYNC);
    if (g_ccu_fd < 0)  
    {
        printf("open(/dev/mem) failed.\n");    
        return -1;
    }
    fflush(stdout);

    g_ccu_map_base = mmap (NULL, g_ccu_mapped_size, PROT_READ | PROT_WRITE, MAP_SHARED, g_ccu_fd, target & ~(off_t)(page_size - 1));
    if (g_ccu_map_base == (void *)-1)
    {
        printf ("NULL pointer!\n");
    }
    else
    {
        printf ("CCU map Successfull!\n");
    }
    fflush(stdout);

    g_ccu_virt_addr = (char*)g_ccu_map_base + offset_in_page;
    // printf("g_ccu_virt_addr: %p %p %x\n", g_ccu_virt_addr, g_ccu_map_base, offset_in_page);

    // read_result =  *(volatile u_int32_t*)g_ccu_virt_addr;

    // printf("ccu_init res: 0x%08lx\n", read_result);
    return 0; 
}

/******************************************************************************
函数名称：    ccu_exit
函数版本：    01.01
创建作者：    zhaoyang
创建日期：    2025-07-28
函数说明：    CCU模块注销
参数说明：    无
返回值：      无
修改记录：
*/
int ccu_exit(void)
{
    if (g_ccu_fd >= 0)
    {
        close(g_ccu_fd);
        g_ccu_fd = -1;
    }

    if (munmap(g_ccu_map_base, g_ccu_mapped_size) == -1) {
        printf("munmap failed!");
        return -1;
    }
    return 0;
}
