1088 lines
33 KiB
C
1088 lines
33 KiB
C
// Copyright 2019 Fuzhou Rockchip Electronics Co., Ltd. All rights reserved.
|
||
// Use of this source code is governed by a BSD-style license that can be
|
||
// found in the LICENSE file.
|
||
#include "sample_comm_aov.h"
|
||
#include "sample_comm.h"
|
||
#include <net/if.h> // must be included later than <net/if.h>
|
||
#include <linux/if.h> // must be included later than <net/if.h>
|
||
#include <linux/netlink.h>
|
||
#include <linux/rtnetlink.h>
|
||
#include <pthread.h>
|
||
#include <sys/mman.h>
|
||
#include <sys/mount.h>
|
||
#include <sys/select.h>
|
||
#include <sys/socket.h>
|
||
#include <sys/stat.h>
|
||
#include <sys/time.h>
|
||
#include <sys/types.h>
|
||
#include <unistd.h>
|
||
#include <linux/input.h>
|
||
|
||
#define MAX_CAMERA_NUM 3
|
||
|
||
#ifdef AOV_FASTBOOT_ENABLE
|
||
|
||
#include "rk_meta.h"
|
||
#include "rk_meta_wakeup_param.h"
|
||
#include "sensor_iq_info.h"
|
||
|
||
// Memory region definitions
|
||
#define META_PHY_ADDR 0x800000
|
||
// Meta region
|
||
#define META_SIZE (384 * 1024)
|
||
|
||
struct meta_para_vir {
|
||
int mem_fd;
|
||
void *mapped_base;
|
||
void *meta_head;
|
||
int meta_head_size;
|
||
void *param_share2kernel_offset;
|
||
int param_share2kernel_offset_size;
|
||
void *sensor_init_offset;
|
||
int sensor_init_offset_size;
|
||
void *cmdline_offset;
|
||
int cmdline_offset_size;
|
||
void *ae_table_offset;
|
||
int ae_table_offset_size;
|
||
void *app_param_offset;
|
||
int app_param_offset_size;
|
||
void *secondary_sensor_init_offset;
|
||
int secondary_sensor_init_offset_size;
|
||
void *wakeup_param_offset;
|
||
int wakeup_param_offset_size;
|
||
void *reserve;
|
||
int reserve_size;
|
||
void *backup;
|
||
int backup_size;
|
||
void *sensor_iq_bin_offset;
|
||
int sensor_iq_bin_offset_size;
|
||
void *secondary_sensor_iq_bin_offset;
|
||
int secondary_sensor_iq_bin_offset_size;
|
||
|
||
void *wakeup_aov_param_offset;
|
||
int wakeup_aov_param_max_size;
|
||
};
|
||
|
||
static struct meta_para_vir *g_meta_vir = NULL;
|
||
#endif // #ifdef AOV_FASTBOOT_ENABLE
|
||
|
||
#define MAX_NL_BUF_SIZE (1024 * 16)
|
||
#define MAX_SELECT_TIMEOUT (2 * 1000 * 1000)
|
||
|
||
static pthread_mutex_t g_wakeup_run_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||
|
||
static RK_S32 g_input_device_fd = -1;
|
||
|
||
#ifdef AOV_FASTBOOT_ENABLE
|
||
static void SAMPLE_COMM_AOV_MetaDump() {
|
||
if (!g_meta_vir) {
|
||
printf("[%s()] empty meta!\n", __func__);
|
||
return;
|
||
}
|
||
printf("g_meta_vir->mem_fd: %d\n", g_meta_vir->mem_fd);
|
||
printf("g_meta_vir->mapped_base: %p\n", g_meta_vir->mapped_base);
|
||
printf("g_meta_vir->meta_head: %p\n", g_meta_vir->meta_head);
|
||
printf("g_meta_vir->meta_head_size: %d\n", g_meta_vir->meta_head_size);
|
||
printf("g_meta_vir->param_share2kernel_offset: %p\n",
|
||
g_meta_vir->param_share2kernel_offset);
|
||
printf("g_meta_vir->param_share2kernel_offset_size: %d\n",
|
||
g_meta_vir->param_share2kernel_offset_size);
|
||
printf("g_meta_vir->sensor_init_offset: %p\n", g_meta_vir->sensor_init_offset);
|
||
printf("g_meta_vir->sensor_init_offset_size: %d\n",
|
||
g_meta_vir->sensor_init_offset_size);
|
||
printf("g_meta_vir->cmdline_offset: %p\n", g_meta_vir->cmdline_offset);
|
||
printf("g_meta_vir->cmdline_offset_size: %d\n", g_meta_vir->cmdline_offset_size);
|
||
printf("g_meta_vir->ae_table_offset: %p\n", g_meta_vir->ae_table_offset);
|
||
printf("g_meta_vir->ae_table_offset_size: %d\n", g_meta_vir->ae_table_offset_size);
|
||
printf("g_meta_vir->app_param_offset: %p\n", g_meta_vir->app_param_offset);
|
||
printf("g_meta_vir->app_param_offset_size: %d\n", g_meta_vir->app_param_offset_size);
|
||
printf("g_meta_vir->secondary_sensor_init_offset: %p\n",
|
||
g_meta_vir->secondary_sensor_init_offset);
|
||
printf("g_meta_vir->secondary_sensor_init_offset_size: %d\n",
|
||
g_meta_vir->wakeup_param_offset_size);
|
||
printf("g_meta_vir->wakeup_param_offset: %p\n", g_meta_vir->wakeup_param_offset);
|
||
printf("g_meta_vir->wakeup_param_offset_size: %d\n",
|
||
g_meta_vir->secondary_sensor_init_offset_size);
|
||
printf("g_meta_vir->reserve: %p\n", g_meta_vir->reserve);
|
||
printf("g_meta_vir->reserve_size: %d\n", g_meta_vir->reserve_size);
|
||
printf("g_meta_vir->backup: %p\n", g_meta_vir->backup);
|
||
printf("g_meta_vir->backup_size: %d\n", g_meta_vir->backup_size);
|
||
printf("g_meta_vir->sensor_iq_bin_offset: %p\n", g_meta_vir->sensor_iq_bin_offset);
|
||
printf("g_meta_vir->sensor_iq_bin_offset_size: %d\n",
|
||
g_meta_vir->sensor_iq_bin_offset_size);
|
||
printf("g_meta_vir->secondary_sensor_iq_bin_offset: %p\n",
|
||
g_meta_vir->secondary_sensor_iq_bin_offset);
|
||
printf("g_meta_vir->secondary_sensor_iq_bin_offset_size: %d\n",
|
||
g_meta_vir->secondary_sensor_iq_bin_offset_size);
|
||
printf("g_meta_vir->wakeup_aov_param_offset: %p\n",
|
||
g_meta_vir->wakeup_aov_param_offset);
|
||
printf("g_meta_vir->wakeup_aov_param_max_size: %d\n",
|
||
g_meta_vir->wakeup_aov_param_max_size);
|
||
// ... Print other fields ...
|
||
}
|
||
|
||
#define se32_to_be32(x) \
|
||
((0x000000FF & x) << 24) | ((0x0000FF00 & x) << 8) | ((0x00FF0000 & x) >> 8) | \
|
||
((0xFF000000 & x) >> 24)
|
||
|
||
static int SAMPLE_COMM_AOV_MetaMmap() {
|
||
int mem_fd = -1;
|
||
void *mapped_base, *virt_addr;
|
||
uint32_t meta_addr, meta_size;
|
||
int dts_fd;
|
||
|
||
if (g_meta_vir != NULL) {
|
||
printf("[%s()] g_meta_vir has been mapped!", __func__);
|
||
return RK_FAILURE;
|
||
}
|
||
g_meta_vir = malloc(sizeof(struct meta_para_vir));
|
||
if (g_meta_vir == NULL) {
|
||
printf("[%s()] g_meta_vir malloc failed!", __func__);
|
||
return RK_FAILURE;
|
||
}
|
||
memset(g_meta_vir, 0, sizeof(struct meta_para_vir));
|
||
|
||
mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
|
||
if (mem_fd == -1) {
|
||
perror("Error opening /dev/mem");
|
||
return EXIT_FAILURE;
|
||
}
|
||
|
||
dts_fd =
|
||
open("/sys/firmware/devicetree/base/reserved-memory/meta@800000/reg", O_RDONLY);
|
||
if (dts_fd > 0) {
|
||
int read_bytes = read(dts_fd, &meta_addr, sizeof(meta_addr));
|
||
read_bytes = read(dts_fd, &meta_size, sizeof(meta_size));
|
||
if (read_bytes > 0) {
|
||
meta_size = se32_to_be32(meta_size);
|
||
meta_addr = se32_to_be32(meta_addr);
|
||
printf("# read firmware meta addr 0X%08x size 0X%08x!\n", meta_addr,
|
||
meta_size);
|
||
} else {
|
||
meta_size = META_SIZE;
|
||
meta_addr = META_PHY_ADDR;
|
||
printf("# read dts reg failed!\n");
|
||
}
|
||
close(dts_fd);
|
||
} else {
|
||
meta_size = META_SIZE;
|
||
meta_addr = META_PHY_ADDR;
|
||
printf("# read dts failed!\n");
|
||
}
|
||
|
||
mapped_base =
|
||
mmap(0, meta_size, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, meta_addr);
|
||
if (mapped_base == MAP_FAILED) {
|
||
perror("Error mapping physical address to virtual address");
|
||
close(mem_fd);
|
||
return EXIT_FAILURE;
|
||
}
|
||
|
||
g_meta_vir->mem_fd = mem_fd;
|
||
g_meta_vir->mapped_base = mapped_base;
|
||
g_meta_vir->meta_head = mapped_base + META_INFO_HEAD_OFFSET;
|
||
g_meta_vir->meta_head_size = META_INFO_SIZE;
|
||
g_meta_vir->param_share2kernel_offset = mapped_base + PARAM_SHARE2KERNEL_OFFSET;
|
||
g_meta_vir->param_share2kernel_offset_size = PARAM_SHARE2KERNEL_SIZE;
|
||
g_meta_vir->sensor_init_offset = mapped_base + SENSOR_INIT_OFFSET;
|
||
g_meta_vir->sensor_init_offset_size = SENSOR_INIT_MAX_SIZE;
|
||
g_meta_vir->cmdline_offset = mapped_base + CMDLINE_OFFSET;
|
||
g_meta_vir->cmdline_offset_size = CMDLINE_MAX_SIZE;
|
||
g_meta_vir->ae_table_offset = mapped_base + AE_TABLE_OFFSET;
|
||
g_meta_vir->ae_table_offset_size = AE_TABLE_MAX_SIZE;
|
||
g_meta_vir->app_param_offset = mapped_base + APP_PARAM_OFFSET;
|
||
g_meta_vir->app_param_offset_size = APP_PARAM_MAX_SIZE;
|
||
g_meta_vir->secondary_sensor_init_offset = mapped_base + SECONDARY_SENSOR_INIT_OFFSET;
|
||
g_meta_vir->secondary_sensor_init_offset_size = SECONDARY_SENSOR_INIT_MAX_SIZE;
|
||
g_meta_vir->wakeup_param_offset = mapped_base + WAKEUP_PARAM_OFFSET;
|
||
g_meta_vir->wakeup_param_offset_size = WAKEUP_PARAM_MAX_SIZE;
|
||
// g_meta_vir->reserve = mapped_base + RESERVE;
|
||
// g_meta_vir->reserve_size = RESERVE_SIZE;
|
||
// g_meta_vir->backup = mapped_base + BACKUP;
|
||
// g_meta_vir->backup_size = BACKUP_SIZE;
|
||
g_meta_vir->sensor_iq_bin_offset = mapped_base + SENSOR_IQ_BIN_OFFSET;
|
||
g_meta_vir->sensor_iq_bin_offset_size = SENSOR_IQ_BIN_MAX_SIZE;
|
||
g_meta_vir->secondary_sensor_iq_bin_offset =
|
||
mapped_base + SECONDARY_SENSOR_IQ_BIN_OFFSET;
|
||
g_meta_vir->secondary_sensor_iq_bin_offset_size = SENSOR_IQ_BIN_MAX_SIZE;
|
||
// g_meta_vir->secondary_sensor_iq_bin_offset_size = 0; // not support
|
||
g_meta_vir->wakeup_aov_param_offset = mapped_base + WAKEUP_AOV_PARAM_OFFSET;
|
||
g_meta_vir->wakeup_aov_param_max_size = WAKEUP_AOV_PARAM_MAX_SIZE;
|
||
|
||
SAMPLE_COMM_AOV_MetaDump(g_meta_vir);
|
||
|
||
// init mcu mode
|
||
struct wakeup_param_info *wakeup_param =
|
||
(struct wakeup_param_info *)g_meta_vir->wakeup_param_offset;
|
||
wakeup_param->wakeup_mode = 0;
|
||
wakeup_param->ae_wakeup_mode = 0;
|
||
wakeup_param->arm_run_count = 0;
|
||
wakeup_param->arm_max_run_count = -1;
|
||
wakeup_param->mcu_run_count = 0;
|
||
wakeup_param->mcu_max_run_count = -1;
|
||
|
||
return RK_SUCCESS;
|
||
}
|
||
|
||
static int SAMPLE_COMM_AOV_MetaMunmap() {
|
||
if (g_meta_vir) {
|
||
if (g_meta_vir->mapped_base)
|
||
munmap(g_meta_vir->mapped_base, META_SIZE);
|
||
if (g_meta_vir->mem_fd >= 0)
|
||
close(g_meta_vir->mem_fd);
|
||
free(g_meta_vir);
|
||
g_meta_vir = NULL;
|
||
} else {
|
||
printf("[%s()] empty g_meta_vir!\n", __func__);
|
||
return RK_FAILURE;
|
||
}
|
||
return RK_SUCCESS;
|
||
}
|
||
|
||
#endif // #ifdef AOV_FASTBOOT_ENABLE
|
||
|
||
#ifdef RK_ENABLE_RTT
|
||
int SAMPLE_COMM_Get_WakeupBin_Info(uint32_t *addr, uint32_t *size) {
|
||
|
||
#define RTT_BIN_PARAM "/proc/device-tree/reserved-memory/rtos@40000/reg"
|
||
#define uswap_32(x) \
|
||
((((x)&0xff000000) >> 24) | (((x)&0x00ff0000) >> 8) | (((x)&0x0000ff00) << 8) | \
|
||
(((x)&0x000000ff) << 24))
|
||
|
||
int rtt_bin_param_fd = -1;
|
||
struct RttBinParam {
|
||
unsigned int addr;
|
||
unsigned int size;
|
||
};
|
||
|
||
struct RttBinParam bin_param = {0, 0};
|
||
if ((rtt_bin_param_fd = open(RTT_BIN_PARAM, O_RDONLY)) < 0) {
|
||
printf("cannot open [%s]\n", RTT_BIN_PARAM);
|
||
return RK_FAILURE;
|
||
}
|
||
|
||
if (read(rtt_bin_param_fd, (void *)&bin_param, sizeof(bin_param)) == -1) {
|
||
printf("read log param error.\n");
|
||
if (rtt_bin_param_fd != -1)
|
||
close(rtt_bin_param_fd);
|
||
return RK_FAILURE;
|
||
}
|
||
|
||
if (rtt_bin_param_fd != -1)
|
||
close(rtt_bin_param_fd);
|
||
|
||
bin_param.addr = uswap_32(bin_param.addr);
|
||
bin_param.size = uswap_32(bin_param.size);
|
||
printf("rtt wakeup bin addr [%#x]\n", bin_param.addr);
|
||
printf("rtt wakeup bin size [%#x]\n", bin_param.size);
|
||
|
||
*addr = bin_param.addr;
|
||
*size = bin_param.size;
|
||
return RK_SUCCESS;
|
||
}
|
||
|
||
int SAMPLE_COMM_AOV_WakeupBinMmap(const char *rtthread_wakeup_bin_path) {
|
||
int mem_fd = -1;
|
||
uint32_t rtt_bin_addr, rtt_bin_max_size;
|
||
void *mapped_base, *virt_addr;
|
||
if (access(rtthread_wakeup_bin_path, F_OK) != 0) {
|
||
perror("read ree wakeup bin info error");
|
||
return EXIT_FAILURE;
|
||
}
|
||
|
||
if (SAMPLE_COMM_Get_WakeupBin_Info(&rtt_bin_addr, &rtt_bin_max_size) != 0) {
|
||
return EXIT_FAILURE;
|
||
}
|
||
|
||
FILE *rtt_bin_file = fopen(rtthread_wakeup_bin_path, "r");
|
||
if (rtt_bin_file == NULL) {
|
||
perror("Error opening meta file");
|
||
close(mem_fd);
|
||
return EXIT_FAILURE;
|
||
}
|
||
mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
|
||
if (mem_fd == -1) {
|
||
perror("Error opening /dev/mem");
|
||
fclose(rtt_bin_file);
|
||
return EXIT_FAILURE;
|
||
}
|
||
mapped_base = mmap(0, rtt_bin_max_size, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd,
|
||
rtt_bin_addr);
|
||
if (mapped_base == MAP_FAILED) {
|
||
perror("Error mapping physical address to virtual address");
|
||
fclose(rtt_bin_file);
|
||
close(mem_fd);
|
||
return EXIT_FAILURE;
|
||
}
|
||
|
||
memset(mapped_base, 0, rtt_bin_max_size);
|
||
|
||
char buffer[1024];
|
||
size_t read_bytes;
|
||
while ((read_bytes = fread(buffer, 1, sizeof(buffer), rtt_bin_file)) > 0) {
|
||
memcpy(mapped_base, buffer, read_bytes);
|
||
mapped_base += read_bytes;
|
||
}
|
||
fclose(rtt_bin_file);
|
||
munmap(mapped_base, rtt_bin_max_size);
|
||
close(mem_fd);
|
||
return RK_SUCCESS;
|
||
}
|
||
#endif // #ifdef RK_ENABLE_RTT
|
||
|
||
int SAMPLE_COMM_AOV_Init() {
|
||
#ifdef AOV_FASTBOOT_ENABLE
|
||
SAMPLE_COMM_AOV_MetaMmap();
|
||
#endif
|
||
// INFO:
|
||
// Find event device path in /proc/bus/input/devices is a better way.
|
||
g_input_device_fd = open("/dev/input/event0", O_RDONLY | O_NONBLOCK);
|
||
if (g_input_device_fd < 0) {
|
||
printf("Open failed /dev/input/event0: %s, you can ignore this"
|
||
" msg if you don't need gpio wakeup...\n",
|
||
strerror(errno));
|
||
}
|
||
|
||
pthread_mutex_init(&g_wakeup_run_mutex, NULL);
|
||
return RK_SUCCESS;
|
||
}
|
||
|
||
int SAMPLE_COMM_AOV_Deinit() {
|
||
pthread_mutex_lock(&g_wakeup_run_mutex);
|
||
#ifdef AOV_FASTBOOT_ENABLE
|
||
SAMPLE_COMM_AOV_MetaMunmap();
|
||
#endif
|
||
pthread_mutex_unlock(&g_wakeup_run_mutex);
|
||
pthread_mutex_destroy(&g_wakeup_run_mutex);
|
||
|
||
if (g_input_device_fd >= 0)
|
||
close(g_input_device_fd);
|
||
}
|
||
|
||
void SAMPLE_COMM_AOV_EnterSleep() {
|
||
#if 0
|
||
|
||
pthread_mutex_lock(&g_wakeup_run_mutex);
|
||
writeReg(0x02000200, 8); // output
|
||
// writeReg(0x02000000, 0); //low
|
||
// usleep(50 * 1000);
|
||
writeReg(0x02000200, 0); // high
|
||
#endif
|
||
|
||
pthread_mutex_lock(&g_wakeup_run_mutex);
|
||
|
||
FILE *file;
|
||
// 打开文件
|
||
file = fopen("/sys/power/state", "w");
|
||
if (file == NULL) {
|
||
perror("Failed to open /sys/power/state");
|
||
pthread_mutex_unlock(&g_wakeup_run_mutex);
|
||
exit(EXIT_FAILURE);
|
||
}
|
||
// 写入字符串
|
||
const char *state = "mem";
|
||
printf("start echo mem > /sys/power/state\n");
|
||
// 进入休眠
|
||
size_t bytes_written = fwrite(state, sizeof(char), strlen(state), file);
|
||
if (bytes_written != strlen(state)) {
|
||
perror("Failed to write to /sys/power/state");
|
||
fclose(file);
|
||
pthread_mutex_unlock(&g_wakeup_run_mutex);
|
||
exit(EXIT_FAILURE);
|
||
}
|
||
fflush(file);
|
||
// 关闭文件
|
||
fclose(file);
|
||
#if 0
|
||
writeReg(0x02000200, 8); // output
|
||
writeReg(0x02000000, 0); // low
|
||
// writeReg(0x02000200, 8); //output
|
||
// writeReg(0x02000000, 0); //low
|
||
// usleep(50 * 1000);
|
||
// writeReg(0x02000200, 0); //high
|
||
pthread_mutex_unlock(&g_wakeup_run_mutex);
|
||
#endif
|
||
pthread_mutex_unlock(&g_wakeup_run_mutex);
|
||
}
|
||
|
||
int SAMPLE_COMM_AOV_SetSuspendTime(int wakeup_suspend_time) {
|
||
char wakeup_cmd[256];
|
||
sprintf(wakeup_cmd, "io -4 0xff300048 %d", wakeup_suspend_time * 32);
|
||
system(wakeup_cmd);
|
||
sleep(1);
|
||
printf("wakeup suspend time = %d", wakeup_suspend_time);
|
||
return RK_SUCCESS;
|
||
}
|
||
|
||
int SAMPLE_COMM_AOV_PreInitIsp(const char *sensor_name, const char *iq_file_dir,
|
||
int cam_index) {
|
||
int ret = RK_SUCCESS;
|
||
rk_aiq_tb_info_t tb_info;
|
||
struct sensor_iq_info *sensor_iq = NULL;
|
||
void *main_iq_offset = NULL;
|
||
void *secondary_iq_offset = NULL;
|
||
|
||
pthread_mutex_lock(&g_wakeup_run_mutex);
|
||
memset(&tb_info, 0, sizeof(rk_aiq_tb_info_t));
|
||
tb_info.magic = sizeof(rk_aiq_tb_info_t) - 2;
|
||
|
||
#ifdef AOV_FASTBOOT_ENABLE
|
||
if (!g_meta_vir) {
|
||
printf("[%s()] empty meta image!\n", __func__);
|
||
pthread_mutex_unlock(&g_wakeup_run_mutex);
|
||
return RK_FAILURE;
|
||
}
|
||
|
||
if (cam_index < MAX_CAMERA_NUM) {
|
||
sensor_iq = (struct sensor_iq_info *)g_meta_vir->sensor_iq_bin_offset;
|
||
main_iq_offset = (uint8_t *)g_meta_vir->mapped_base +
|
||
(sensor_iq->main_sensor_iq_offset - META_PHY_ADDR);
|
||
secondary_iq_offset = (uint8_t *)g_meta_vir->mapped_base +
|
||
(sensor_iq->secondary_sensor_iq_offset - META_PHY_ADDR);
|
||
printf("[%s()] main addr %p size %d, second addr %p size %d\n", __func__,
|
||
sensor_iq->main_sensor_iq_offset, sensor_iq->main_sensor_iq_size,
|
||
sensor_iq->secondary_sensor_iq_offset,
|
||
sensor_iq->secondary_sensor_iq_size);
|
||
} else {
|
||
printf("[%s()] error camera index %d!\n", __func__, cam_index);
|
||
pthread_mutex_unlock(&g_wakeup_run_mutex);
|
||
return RK_FAILURE;
|
||
}
|
||
|
||
tb_info.is_start_once = true;
|
||
tb_info.is_pre_aiq = true;
|
||
tb_info.prd_type = RK_AIQ_PRD_TYPE_TB_BATIPC;
|
||
// tb_info.rtt_share_addr = g_meta_vir->wakeup_aov_param_offset;
|
||
tb_info.rtt_share_addr = 0;
|
||
#else
|
||
tb_info.is_start_once = false;
|
||
tb_info.is_pre_aiq = false;
|
||
tb_info.prd_type = RK_AIQ_PRD_TYPE_SINGLE_FRAME;
|
||
tb_info.rtt_share_addr = 0;
|
||
if (iq_file_dir != NULL) {
|
||
printf("rkaiq use iqfiles from %s\n", iq_file_dir);
|
||
tb_info.iq_bin_mode = RK_AIQ_META_NOT_FULL_IQ_BIN;
|
||
}
|
||
#endif
|
||
ret = rk_aiq_uapi2_sysctl_preInit_tb_info(sensor_name, &tb_info);
|
||
if (ret != RK_SUCCESS)
|
||
printf("[%s()] rk_aiq_uapi2_sysctl_preInit_tb_info failed %#X!\n", __func__, ret);
|
||
|
||
#ifdef AOV_FASTBOOT_ENABLE
|
||
if (cam_index == 0)
|
||
ret = rk_aiq_uapi2_sysctl_preInit_iq_addr(sensor_name, main_iq_offset,
|
||
sensor_iq->main_sensor_iq_size);
|
||
else if (cam_index == 1)
|
||
ret = rk_aiq_uapi2_sysctl_preInit_iq_addr(sensor_name, secondary_iq_offset,
|
||
sensor_iq->secondary_sensor_iq_size);
|
||
else
|
||
printf("[%s()] not support camera index %d now!\n", cam_index);
|
||
if (ret != RK_SUCCESS)
|
||
printf("[%s()] rk_aiq_uapi2_sysctl_preInit_iq_addr failed %#X!\n", __func__, ret);
|
||
#endif
|
||
pthread_mutex_unlock(&g_wakeup_run_mutex);
|
||
return ret;
|
||
}
|
||
|
||
#define ETHERNET_DEVICE "ffa80000.ethernet"
|
||
#define ETHERNET_DRIVER "/sys/bus/platform/drivers/rk_gmac-dwmac/"
|
||
// #define NIC_DEVICE "stmmac-0:02"
|
||
// #define NIC_DRIVER "/sys/bus/mdio_bus/drivers/RK630 PHY/"
|
||
#define ETHERNET_BIND_DONE "/sys/bus/platform/drivers/rk_gmac-dwmac/"
|
||
#define ETHERNET_UNBNID_DONE "/sys/bus/platform/drivers/rk_gmac-dwmac/"
|
||
|
||
int SAMPLE_COMM_AOV_BindEthernet() {
|
||
char buf[MAX_NL_BUF_SIZE] = {'\0'};
|
||
char name[256] = {'\0'};
|
||
int ret = 0;
|
||
int fd = -1;
|
||
int len = MAX_NL_BUF_SIZE;
|
||
fd_set read_set;
|
||
struct ifreq ifr;
|
||
struct timeval timeout;
|
||
struct sockaddr_nl addr;
|
||
struct nlmsghdr *nh = NULL;
|
||
struct ifinfomsg *ifinfo = NULL;
|
||
|
||
printf("[%s()] Enter\n", __func__);
|
||
if (access(ETHERNET_DRIVER ETHERNET_DEVICE, F_OK) == 0) {
|
||
printf("[%s()] ethernet device already bind!\n", __func__);
|
||
goto __FAILED;
|
||
}
|
||
|
||
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||
setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &len, sizeof(len));
|
||
memset(&addr, 0, sizeof(addr));
|
||
addr.nl_family = AF_NETLINK;
|
||
addr.nl_groups = RTNLGRP_LINK;
|
||
addr.nl_pid = getpid();
|
||
if (fd < 0) {
|
||
printf("[%s()] Failed to open network netlink because %s\n", __func__,
|
||
strerror(errno));
|
||
goto __FAILED;
|
||
} else if (bind(fd, (struct sockaddr *)(&addr), sizeof(addr)) != 0) {
|
||
printf("[%s()] bind network netlink addr failed because %s\n", __func__,
|
||
strerror(errno));
|
||
goto __FAILED;
|
||
}
|
||
|
||
FD_ZERO(&read_set);
|
||
FD_SET(fd, &read_set);
|
||
timeout.tv_sec = 0;
|
||
timeout.tv_usec = MAX_SELECT_TIMEOUT;
|
||
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout,
|
||
(socklen_t)sizeof(struct timeval));
|
||
|
||
// bind ethernet driver
|
||
SAMPLE_COMM_ECHO(ETHERNET_DRIVER "bind", ETHERNET_DEVICE, (strlen(ETHERNET_DEVICE)));
|
||
|
||
#if 1
|
||
// open etherner device
|
||
system("ifconfig eth0 up");
|
||
// reset local ip, gateway and dns resolvation
|
||
system("killall -9 udhcpc"); // restart udhcpc
|
||
system("route del default gw 0.0.0.0"); // delete default gateway
|
||
system("cat /dev/null > /etc/resolv.conf"); // reset DNS resolvation
|
||
system("udhcpc -i eth0 -T 1 -A 0 -b -q"); // find a new ip address for eth0
|
||
#endif
|
||
// wait for bind success
|
||
// FIXME:
|
||
// there has some bug for select()
|
||
// ret = select(fd + 1, &read_set, NULL, NULL, &timeout);
|
||
memset(&buf, 0, sizeof(buf));
|
||
while ((ret = read(fd, buf, sizeof(buf))) > 0) {
|
||
for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, ret); nh = NLMSG_NEXT(nh, ret)) {
|
||
if (nh->nlmsg_type == NLMSG_DONE) {
|
||
printf("[%s()] NLMSG_DONE\n", __func__);
|
||
goto __FAILED;
|
||
}
|
||
if (nh->nlmsg_type == NLMSG_ERROR) {
|
||
printf("[%s()] NLMSG_ERROR\n", __func__);
|
||
goto __FAILED;
|
||
}
|
||
if (nh->nlmsg_type != RTM_NEWLINK) {
|
||
printf("[%s()] not RTM_NEWLINK, ignore\n", __func__);
|
||
continue;
|
||
}
|
||
ifinfo = NLMSG_DATA(nh);
|
||
if_indextoname(ifinfo->ifi_index, name);
|
||
|
||
// printf("[%s()] %s: up %s, lower up %s, running %s, value 0X%X\n", __func__
|
||
// , name
|
||
// , (ifinfo->ifi_flags & IFF_UP) ? "true" : "false"
|
||
// , (ifinfo->ifi_flags & IFF_LOWER_UP) ? "true" : "false"
|
||
// , (ifinfo->ifi_flags & IFF_RUNNING) ? "true" : "false"
|
||
// , ifinfo->ifi_flags
|
||
// );
|
||
|
||
if ((ifinfo->ifi_flags & IFF_RUNNING) && (ifinfo->ifi_flags & IFF_LOWER_UP) &&
|
||
(ifinfo->ifi_flags & IFF_UP)) {
|
||
printf("[%s()] ethernet bind success!\n", __func__);
|
||
goto __SUCCESS;
|
||
}
|
||
}
|
||
}
|
||
if (ret < 0)
|
||
goto __FAILED;
|
||
|
||
__SUCCESS:
|
||
if (fd >= 0)
|
||
close(fd);
|
||
printf("[%s()] Exit\n", __func__);
|
||
return RK_SUCCESS;
|
||
__FAILED:
|
||
if (fd >= 0)
|
||
close(fd);
|
||
printf("[%s()] Exit Error\n", __func__);
|
||
return RK_FAILURE;
|
||
}
|
||
|
||
int SAMPLE_COMM_AOV_UnbindEthernet() {
|
||
char buf[MAX_NL_BUF_SIZE] = {'\0'};
|
||
char name[256] = {'\0'};
|
||
int ret = 0;
|
||
int fd = -1;
|
||
int len = MAX_NL_BUF_SIZE;
|
||
fd_set read_set;
|
||
struct sockaddr_nl addr;
|
||
struct timeval timeout;
|
||
struct nlmsghdr *nh = NULL;
|
||
struct ifinfomsg *ifinfo = NULL;
|
||
|
||
printf("[%s()] Enter\n", __func__);
|
||
if (access(ETHERNET_DRIVER ETHERNET_DEVICE, F_OK) != 0) {
|
||
printf("[%s()] ethernet device already unbind!\n", __func__);
|
||
goto __FAILED;
|
||
}
|
||
|
||
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||
setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &len, sizeof(len));
|
||
memset(&addr, 0, sizeof(addr));
|
||
addr.nl_family = AF_NETLINK;
|
||
addr.nl_groups = RTNLGRP_LINK;
|
||
addr.nl_pid = getpid();
|
||
if (fd < 0) {
|
||
printf("[%s()] Failed to open network netlink because %s\n", __func__,
|
||
strerror(errno));
|
||
return RK_FAILURE;
|
||
} else if (bind(fd, (struct sockaddr *)(&addr), sizeof(addr)) != 0) {
|
||
printf("[%s()] bind network netlink addr failed because %s\n", __func__,
|
||
strerror(errno));
|
||
goto __FAILED;
|
||
}
|
||
|
||
FD_ZERO(&read_set);
|
||
FD_SET(fd, &read_set);
|
||
timeout.tv_sec = 0;
|
||
timeout.tv_usec = MAX_SELECT_TIMEOUT;
|
||
|
||
// close ethernet device
|
||
system("ifconfig eth0 0.0.0.0");
|
||
system("ifconfig eth0 down");
|
||
// unbind ethernet driver
|
||
SAMPLE_COMM_ECHO(ETHERNET_DRIVER "unbind", ETHERNET_DEVICE,
|
||
(strlen(ETHERNET_DEVICE)));
|
||
// wait for unbind done
|
||
__RETRY:
|
||
ret = select(fd + 1, &read_set, NULL, NULL, &timeout);
|
||
if (ret > 0) {
|
||
memset(&buf, 0, sizeof(buf));
|
||
ret = read(fd, buf, sizeof(buf));
|
||
for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, ret); nh = NLMSG_NEXT(nh, ret)) {
|
||
if (nh->nlmsg_type == NLMSG_DONE) {
|
||
printf("[%s()] NLMSG_DONE\n", __func__);
|
||
goto __FAILED;
|
||
}
|
||
if (nh->nlmsg_type == NLMSG_ERROR) {
|
||
printf("[%s()] NLMSG_ERROR\n", __func__);
|
||
goto __FAILED;
|
||
}
|
||
ifinfo = NLMSG_DATA(nh);
|
||
if_indextoname(ifinfo->ifi_index, name);
|
||
|
||
// printf("[%s()] %s: up %s, lower up %s, running %s, value 0X%X\n", __func__
|
||
// , name
|
||
// , (ifinfo->ifi_flags & IFF_UP) ? "true" : "false"
|
||
// , (ifinfo->ifi_flags & IFF_LOWER_UP) ? "true" : "false"
|
||
// , (ifinfo->ifi_flags & IFF_RUNNING) ? "true" : "false"
|
||
// , ifinfo->ifi_flags
|
||
// );
|
||
|
||
if (!(ifinfo->ifi_flags & IFF_RUNNING) &&
|
||
!(ifinfo->ifi_flags & IFF_LOWER_UP) && !(ifinfo->ifi_flags & IFF_UP)) {
|
||
printf("[%s()] ethernet unbind success!\n", __func__);
|
||
goto __SUCCESS;
|
||
}
|
||
}
|
||
// printf("[%s()] Bind msg: %s\n", __func__, buf);
|
||
goto __RETRY; // drop all message
|
||
} else {
|
||
printf("[%s()] select error: %s\n", __func__, strerror(errno));
|
||
goto __FAILED;
|
||
}
|
||
__SUCCESS:
|
||
close(fd);
|
||
// open etherner device
|
||
printf("[%s()] Exit\n", __func__);
|
||
return RK_SUCCESS;
|
||
__FAILED:
|
||
close(fd);
|
||
printf("[%s()] Exit Error\n", __func__);
|
||
return RK_FAILURE;
|
||
}
|
||
|
||
#define SDCARD_ADDR_STR "ffaa0000.mmc"
|
||
#define SDCARD_NODE_BIND "/sys/bus/platform/drivers/dwmmc_rockchip/bind"
|
||
#define SDCARD_NODE_UNBIND "/sys/bus/platform/drivers/dwmmc_rockchip/unbind"
|
||
#define SDCARD_NODE_DEVICE "/sys/bus/platform/drivers/dwmmc_rockchip/ffaa0000.mmc"
|
||
#define SDCARD_BIND_DONE "bind@/devices/platform/ffaa0000.mmc/mmc_host/mmc1/mmc1"
|
||
#define SDCARD_UNBIND_DONE "unbind@/devices/platform/ffaa0000.mmc"
|
||
|
||
int SAMPLE_COMM_AOV_BindSdcard() {
|
||
int ret = 0;
|
||
int fd = -1;
|
||
char buf[MAX_NL_BUF_SIZE] = {'\0'};
|
||
fd_set read_set;
|
||
struct timeval timeout;
|
||
struct sockaddr_nl addr;
|
||
|
||
if (access(SDCARD_NODE_DEVICE, F_OK) == 0) {
|
||
printf("[%s()] sdcard device already bind!\n", __func__);
|
||
return RK_SUCCESS;
|
||
}
|
||
|
||
memset(&addr, 0, sizeof(addr));
|
||
addr.nl_family = AF_NETLINK;
|
||
addr.nl_groups = NETLINK_KOBJECT_UEVENT;
|
||
addr.nl_pid = 0;
|
||
|
||
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
|
||
if (fd < 0) {
|
||
printf("[%s()] Failed to open sdcard netlink because %s\n", __func__,
|
||
strerror(errno));
|
||
return RK_FAILURE;
|
||
} else if (bind(fd, (struct sockaddr *)(&addr), sizeof(addr)) != 0) {
|
||
printf("[%s()] bind sdcard netlink addr failed because %s\n", __func__,
|
||
strerror(errno));
|
||
goto __FAILED;
|
||
}
|
||
|
||
FD_ZERO(&read_set);
|
||
FD_SET(fd, &read_set);
|
||
timeout.tv_sec = 0;
|
||
timeout.tv_usec = MAX_SELECT_TIMEOUT;
|
||
|
||
// bind sdcard
|
||
SAMPLE_COMM_ECHO(SDCARD_NODE_BIND, SDCARD_ADDR_STR, (sizeof(SDCARD_ADDR_STR)));
|
||
// wait for bind success
|
||
__RETRY:
|
||
ret = select(fd + 1, &read_set, NULL, NULL, &timeout);
|
||
if (ret > 0) {
|
||
memset(&buf, 0, sizeof(buf));
|
||
read(fd, buf, sizeof(buf));
|
||
buf[MAX_NL_BUF_SIZE - 1] = '\0';
|
||
// printf("[%s()] bind msg: %s\n", __func__, buf);
|
||
if (strncmp(buf, SDCARD_BIND_DONE, strlen(SDCARD_BIND_DONE)) == 0) {
|
||
printf("[%s()] Bind success: %s\n", __func__, buf);
|
||
goto __SUCCESS;
|
||
}
|
||
goto __RETRY; // drop all message
|
||
} else {
|
||
printf("[%s()] select error %s\n", __func__, strerror(errno));
|
||
goto __FAILED;
|
||
}
|
||
__SUCCESS:
|
||
close(fd);
|
||
return RK_SUCCESS;
|
||
__FAILED:
|
||
close(fd);
|
||
return RK_FAILURE;
|
||
}
|
||
|
||
int SAMPLE_COMM_AOV_UnbindSdcard() {
|
||
int ret = 0;
|
||
int fd = -1;
|
||
char buf[MAX_NL_BUF_SIZE] = {'\0'};
|
||
fd_set read_set;
|
||
struct timeval timeout;
|
||
struct sockaddr_nl addr;
|
||
|
||
if (access(SDCARD_NODE_DEVICE, F_OK) != 0) {
|
||
printf("[%s()] sdcard device already unbind!\n", __func__);
|
||
return RK_SUCCESS;
|
||
}
|
||
|
||
memset(&addr, 0, sizeof(addr));
|
||
addr.nl_family = AF_NETLINK;
|
||
addr.nl_groups = NETLINK_KOBJECT_UEVENT;
|
||
addr.nl_pid = 0;
|
||
|
||
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
|
||
if (fd < 0) {
|
||
printf("[%s()] Failed to open sdcard netlink because %s\n", __func__,
|
||
strerror(errno));
|
||
return RK_FAILURE;
|
||
} else if (bind(fd, (struct sockaddr *)(&addr), sizeof(addr)) != 0) {
|
||
printf("[%s()] bind sdcard netlink addr failed because %s\n", __func__,
|
||
strerror(errno));
|
||
goto __FAILED;
|
||
}
|
||
|
||
memset(&buf, 0, sizeof(buf));
|
||
FD_ZERO(&read_set);
|
||
FD_SET(fd, &read_set);
|
||
timeout.tv_sec = 0;
|
||
timeout.tv_usec = MAX_SELECT_TIMEOUT;
|
||
|
||
// unbind sdcard
|
||
SAMPLE_COMM_ECHO(SDCARD_NODE_UNBIND, SDCARD_ADDR_STR, (sizeof(SDCARD_ADDR_STR)));
|
||
// wait for unbind success
|
||
__RETRY:
|
||
ret = select(fd + 1, &read_set, NULL, NULL, &timeout);
|
||
if (ret > 0) {
|
||
memset(&buf, 0, sizeof(buf));
|
||
read(fd, buf, sizeof(buf));
|
||
buf[MAX_NL_BUF_SIZE - 1] = '\0';
|
||
// printf("[%s()] unbind msg: %s\n", __func__, buf);
|
||
if (strcmp(buf, SDCARD_UNBIND_DONE) == 0) {
|
||
printf("[%s()] Unbind success: %s\n", __func__, buf);
|
||
goto __SUCCESS;
|
||
}
|
||
goto __RETRY; // drop all message
|
||
} else {
|
||
printf("[%s()] select error %s\n", __func__, strerror(errno));
|
||
goto __FAILED;
|
||
}
|
||
__SUCCESS:
|
||
close(fd);
|
||
return RK_SUCCESS;
|
||
__FAILED:
|
||
close(fd);
|
||
return RK_FAILURE;
|
||
}
|
||
|
||
static int SAMPLE_COMM_AOV_CheckSDcardMount(void) {
|
||
FILE *file = fopen("/proc/mounts", "r");
|
||
int ret = RK_FAILURE;
|
||
if (file == NULL) {
|
||
printf("Failed to open file\n");
|
||
return ret;
|
||
}
|
||
|
||
char line[256];
|
||
while (fgets(line, sizeof(line), file)) {
|
||
if (strstr(line, "/mnt/sdcard")) {
|
||
printf("Found '/mnt/sdcard' in line: %s", line);
|
||
ret = RK_SUCCESS;
|
||
}
|
||
}
|
||
|
||
fclose(file);
|
||
return ret;
|
||
} /* ----- end of function SAMPLE_COMM_AOV_CheckSDcardMount ----- */
|
||
|
||
int SAMPLE_COMM_AOV_CopyStreamToSdcard(int venc_chn_id, char *data, int data_size,
|
||
char *data2, int data2_size) {
|
||
int ret = 0;
|
||
pthread_mutex_lock(&g_wakeup_run_mutex);
|
||
SAMPLE_COMM_AOV_BindSdcard();
|
||
// mount sd
|
||
if (access("/dev/mmcblk1p1", F_OK) == 0) {
|
||
// system("mount -t vfat /dev/mmcblk1p1 /mnt/sdcard/");
|
||
ret = mount("/dev/mmcblk1p1", "/mnt/sdcard", "vfat", 0, NULL);
|
||
if (ret != 0)
|
||
printf("[%s()] mount failed because %s\n", __func__, strerror(errno));
|
||
else
|
||
printf("[%s()] mount success\n", __func__);
|
||
} else if (access("/dev/mmcblk1", F_OK) == 0) {
|
||
// system("mount -t vfat /dev/mmcblk1 /mnt/sdcard/");
|
||
ret = mount("/dev/mmcblk1", "/mnt/sdcard", "vfat", 0, NULL);
|
||
if (ret != 0)
|
||
printf("[%s()] mount failed because %s\n", __func__, strerror(errno));
|
||
else
|
||
printf("[%s()] mount success\n", __func__);
|
||
} else {
|
||
printf("[%s()] bad mount path!\n", __func__);
|
||
goto SAMPLE_COMM_AOV_CopyStreamToSdcard_end;
|
||
}
|
||
|
||
if (0 != SAMPLE_COMM_AOV_CheckSDcardMount()) {
|
||
printf("Not found mount sdcard on /mnt/sdcard\n");
|
||
goto SAMPLE_COMM_AOV_CopyStreamToSdcard_end;
|
||
}
|
||
|
||
static int count_t = 0;
|
||
static char dstPath[256];
|
||
int s32fd = 0;
|
||
char dst[256];
|
||
// 首次进来存储,遍历目录是否可用,最多100个目录
|
||
if (count_t == 0) {
|
||
int i = 0;
|
||
for (i = 0; i < 100; i++) {
|
||
sprintf(dstPath, "/mnt/sdcard/wakeup_frame_%d", i);
|
||
struct stat st;
|
||
if (stat(dstPath, &st) == -1) {
|
||
if (mkdir(dstPath, 0777) == -1)
|
||
printf("mkdir %s failed\n", dstPath);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
sprintf(dst, "%s/venc_chn%d_%d.h265", dstPath, venc_chn_id, count_t);
|
||
FILE *fp = fopen(dst, "wb");
|
||
if (fp != NULL) {
|
||
fwrite(data, 1, data_size, fp);
|
||
if (data2)
|
||
fwrite(data2, 1, data2_size, fp);
|
||
s32fd = fileno(fp);
|
||
fsync(s32fd);
|
||
fclose(fp);
|
||
count_t++;
|
||
}
|
||
// unmount sdcard
|
||
umount2("/mnt/sdcard", MNT_DETACH);
|
||
|
||
SAMPLE_COMM_AOV_CopyStreamToSdcard_end:
|
||
SAMPLE_COMM_AOV_UnbindSdcard();
|
||
pthread_mutex_unlock(&g_wakeup_run_mutex);
|
||
|
||
return RK_SUCCESS;
|
||
}
|
||
|
||
void SAMPLE_COMM_AOV_DumpPtsToTMP(uint32_t seq, uint64_t pts, int max_dump_pts_count) {
|
||
static int line_count = 0;
|
||
static FILE *file;
|
||
const char *file_path = "/tmp/pts.txt";
|
||
|
||
if (line_count >= max_dump_pts_count) {
|
||
return;
|
||
}
|
||
|
||
if (line_count == 0) {
|
||
file = fopen(file_path, "w");
|
||
if (file == NULL) {
|
||
perror("Error opening file");
|
||
return;
|
||
}
|
||
}
|
||
|
||
if (file != NULL)
|
||
fprintf(file, "seq: %u, pts: %llums\n", seq, (unsigned long long)pts / 1000);
|
||
|
||
line_count++;
|
||
|
||
if (line_count >= max_dump_pts_count) {
|
||
printf("Closed file after writing %d lines.\n", max_dump_pts_count);
|
||
fclose(file);
|
||
file = NULL;
|
||
}
|
||
}
|
||
|
||
// Return true is there has input event happened.
|
||
bool SAMPLE_COMM_AOV_GetGpioIrqStat() {
|
||
bool input_event_happened = false;
|
||
struct input_event event;
|
||
|
||
if (g_input_device_fd < 0) {
|
||
// printf("[%s()] unsupport input event detector\n", __func__);
|
||
return input_event_happened;
|
||
}
|
||
|
||
// The read() operation is non-block, so the loop would
|
||
// return EGAGIN if there has no any new input event.
|
||
while (read(g_input_device_fd, &event, sizeof(event)) > 0) {
|
||
// printf("[%s()] detect event type %d, code %d, value %d\n"
|
||
// , __func__
|
||
// , event.type
|
||
// , event.code
|
||
// , event.value
|
||
// );
|
||
// Translate ISP state if gpio-key is pressed between
|
||
// sleeping time.
|
||
if (event.type == EV_KEY && event.code == KEY_POWER && event.value == 1)
|
||
input_event_happened = true;
|
||
}
|
||
return input_event_happened;
|
||
}
|
||
|
||
#define SOUND_BIND_DONE "bind@/devices/platform/acodec-sound"
|
||
#define SOUND_UNBIND_DONE "unbind@/devices/platform/ffae0000.i2s"
|
||
#define I2S_DRIVER "/sys/bus/platform/drivers/rockchip-i2s-tdm/"
|
||
#define ACODEC_DRIVER "/sys/bus/platform/drivers/rv1106-acodec/"
|
||
#define ASOC_DRIVER "/sys/bus/platform/drivers/asoc-simple-card/"
|
||
#define I2S_DEVICE "ffae0000.i2s"
|
||
#define ACODEC_DEVICE "ff480000.acodec"
|
||
#define ASOC_DEVICE "acodec-sound"
|
||
|
||
int SAMPLE_COMM_AOV_BindSoundcard() {
|
||
int ret = 0;
|
||
int fd = -1;
|
||
char buf[MAX_NL_BUF_SIZE] = {'\0'};
|
||
fd_set read_set;
|
||
struct timeval timeout;
|
||
struct sockaddr_nl addr;
|
||
|
||
memset(&addr, 0, sizeof(addr));
|
||
addr.nl_family = AF_NETLINK;
|
||
addr.nl_groups = NETLINK_KOBJECT_UEVENT;
|
||
addr.nl_pid = 0;
|
||
|
||
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
|
||
if (fd < 0) {
|
||
printf("[%s()] Failed to open netlink because %s\n", __func__, strerror(errno));
|
||
return RK_FAILURE;
|
||
} else if (bind(fd, (struct sockaddr *)(&addr), sizeof(addr)) != 0) {
|
||
printf("[%s()] bind netlink addr failed because %s\n", __func__, strerror(errno));
|
||
goto __FAILED;
|
||
}
|
||
|
||
memset(&buf, 0, sizeof(buf));
|
||
FD_ZERO(&read_set);
|
||
FD_SET(fd, &read_set);
|
||
timeout.tv_sec = 0;
|
||
timeout.tv_usec = MAX_SELECT_TIMEOUT;
|
||
|
||
SAMPLE_COMM_ECHO(I2S_DRIVER "bind", I2S_DEVICE, (sizeof(I2S_DEVICE)));
|
||
SAMPLE_COMM_ECHO(ACODEC_DRIVER "bind", ACODEC_DEVICE, (sizeof(ACODEC_DEVICE)));
|
||
SAMPLE_COMM_ECHO(ASOC_DRIVER "bind", ASOC_DEVICE, (sizeof(ASOC_DEVICE)));
|
||
__RETRY:
|
||
ret = select(fd + 1, &read_set, NULL, NULL, &timeout);
|
||
if (ret > 0) {
|
||
memset(&buf, 0, sizeof(buf));
|
||
read(fd, buf, sizeof(buf));
|
||
buf[MAX_NL_BUF_SIZE - 1] = '\0';
|
||
// printf("[%s()] msg: %s\n", __func__, buf);
|
||
if (strncmp(buf, SOUND_BIND_DONE, strlen(SOUND_BIND_DONE)) == 0) {
|
||
printf("[%s()] Bind success: %s\n", __func__, buf);
|
||
goto __SUCCESS;
|
||
}
|
||
goto __RETRY; // drop all message
|
||
} else {
|
||
printf("[%s()] select error %s\n", __func__, strerror(errno));
|
||
goto __FAILED;
|
||
}
|
||
|
||
__SUCCESS:
|
||
close(fd);
|
||
return RK_SUCCESS;
|
||
__FAILED:
|
||
close(fd);
|
||
return RK_FAILURE;
|
||
}
|
||
|
||
int SAMPLE_COMM_AOV_UnbindSoundcard() {
|
||
int ret = 0;
|
||
int fd = -1;
|
||
char buf[MAX_NL_BUF_SIZE] = {'\0'};
|
||
fd_set read_set;
|
||
struct timeval timeout;
|
||
struct sockaddr_nl addr;
|
||
|
||
memset(&addr, 0, sizeof(addr));
|
||
addr.nl_family = AF_NETLINK;
|
||
addr.nl_groups = NETLINK_KOBJECT_UEVENT;
|
||
addr.nl_pid = 0;
|
||
|
||
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
|
||
if (fd < 0) {
|
||
printf("[%s()] Failed to open netlink because %s\n", __func__, strerror(errno));
|
||
return RK_FAILURE;
|
||
} else if (bind(fd, (struct sockaddr *)(&addr), sizeof(addr)) != 0) {
|
||
printf("[%s()] bind netlink addr failed because %s\n", __func__, strerror(errno));
|
||
goto __FAILED;
|
||
}
|
||
|
||
memset(&buf, 0, sizeof(buf));
|
||
FD_ZERO(&read_set);
|
||
FD_SET(fd, &read_set);
|
||
timeout.tv_sec = 0;
|
||
timeout.tv_usec = MAX_SELECT_TIMEOUT;
|
||
|
||
SAMPLE_COMM_ECHO(ASOC_DRIVER "unbind", ASOC_DEVICE, (sizeof(ASOC_DEVICE)));
|
||
SAMPLE_COMM_ECHO(ACODEC_DRIVER "unbind", ACODEC_DEVICE, (sizeof(ACODEC_DEVICE)));
|
||
SAMPLE_COMM_ECHO(I2S_DRIVER "unbind", I2S_DEVICE, (sizeof(I2S_DEVICE)));
|
||
__RETRY:
|
||
ret = select(fd + 1, &read_set, NULL, NULL, &timeout);
|
||
if (ret > 0) {
|
||
memset(&buf, 0, sizeof(buf));
|
||
read(fd, buf, sizeof(buf));
|
||
buf[MAX_NL_BUF_SIZE - 1] = '\0';
|
||
// printf("[%s()] msg: %s\n", __func__, buf);
|
||
if (strncmp(buf, SOUND_UNBIND_DONE, strlen(SOUND_UNBIND_DONE)) == 0) {
|
||
printf("[%s()] Unbind success: %s\n", __func__, buf);
|
||
goto __SUCCESS;
|
||
}
|
||
goto __RETRY; // drop all message
|
||
} else {
|
||
printf("[%s()] select error %s\n", __func__, strerror(errno));
|
||
goto __FAILED;
|
||
}
|
||
|
||
__SUCCESS:
|
||
close(fd);
|
||
return RK_SUCCESS;
|
||
__FAILED:
|
||
close(fd);
|
||
return RK_FAILURE;
|
||
}
|