aml_audio_hal: Add more hal tests [1/1]
PD#TV-17788
PD#TV-18504
PD#SWPL-23836
Problem:
Need sample code to show audio HAL dap_settings,
output format config, speaker and ARC delay and
arc/earc output.
Solution:
Provide sample test code.
Verify:
Local on AB311 platform.
Change-Id: I99c2aa45c9a5dea3ef04a26279eb0a19d53a4bf9
diff --git a/Makefile b/Makefile
index 46f1346..7851c34 100644
--- a/Makefile
+++ b/Makefile
@@ -12,6 +12,11 @@
TEST_PCM_OBJS=src/test.o
TEST_DOLBY_OBJS=src/test_ac3.o
TEST_HALPLAY_OBJS=src/halplay.o
+TEST_MS12_OBJS=src/dap_setting.o
+TEST_SPEAKER_DELAY_OBJS=src/speaker_delay.o
+TEST_DIGITAL_MODE_OBJS=src/digital_mode.o
+TEST_ARC_TEST_OBJS=src/test_arc.o
+TEST_START_ARC_OBJS=src/start_arc.o
PROTOC=$(HOST_DIR)/bin/protoc
PROTOC_INC=$(HOST_DIR)/include
@@ -36,7 +41,7 @@
%.o: %.c
$(CC) -c $(CFLAGS) -o $@ $<
-all: audio_server libaudio_client.so audio_client_test audio_client_test_ac3 halplay
+all: audio_server libaudio_client.so audio_client_test audio_client_test_ac3 halplay dap_setting speaker_delay digital_mode test_arc start_arc
audio_server: $(SERVER_OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
@@ -53,12 +58,32 @@
halplay: $(TEST_HALPLAY_OBJS) libaudio_client.so
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
+dap_setting: $(TEST_MS12_OBJS) libaudio_client.so
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
+
+speaker_delay: $(TEST_SPEAKER_DELAY_OBJS) libaudio_client.so
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
+
+digital_mode: $(TEST_DIGITAL_MODE_OBJS) libaudio_client.so
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
+
+test_arc: $(TEST_ARC_TEST_OBJS) libaudio_client.so
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
+
+start_arc: $(TEST_START_ARC_OBJS)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
+
.PHONY: install
install:
install -m 755 -D audio_server -t $(TARGET_DIR)/usr/bin/
install -m 755 -D audio_client_test -t $(TARGET_DIR)/usr/bin/
install -m 755 -D audio_client_test_ac3 $(TARGET_DIR)/usr/bin/
install -m 755 -D halplay $(TARGET_DIR)/usr/bin/
+ install -m 755 -D dap_setting $(TARGET_DIR)/usr/bin/
+ install -m 755 -D speaker_delay $(TARGET_DIR)/usr/bin/
+ install -m 755 -D digital_mode $(TARGET_DIR)/usr/bin/
+ install -m 755 -D test_arc $(TARGET_DIR)/usr/bin/
+ install -m 755 -D start_arc $(TARGET_DIR)/usr/bin/
install -m 644 -D libaudio_client.so -t $(TARGET_DIR)/usr/lib/
install -m 644 -D libaudio_client.so -t $(STAGING_DIR)/usr/lib/
install -m 644 -D include/audio_if_client.h -t $(STAGING_DIR)/usr/include
@@ -76,6 +101,8 @@
rm -f audio_client_test
rm -f audio_client_test_ac3
rm -f halplay
+ rm -f test_arc
+ rm -f start_arc
rm -rf $(STAGING_DIR)/usr/include/hardware
rm -rf $(STAGING_DIR)/usr/include/system
rm -f libaudio_client.so
@@ -83,6 +110,10 @@
rm -f $(TARGET_DIR)/usr/bin/audio_client_test
rm -f $(TARGET_DIR)/usr/bin/audio_client_test_ac3
rm -f $(TARGET_DIR)/usr/bin/halplay
+ rm -f $(TARGET_DIR)/usr/bin/speaker_delay
+ rm -f $(TARGET_DIR)/usr/bin/digital_mode
+ rm -f $(TARGET_DIR)/usr/bin/test_arc
+ rm -f $(TARGET_DIR)/usr/bin/start_arc
rm -f $(TARGET_DIR)/usr/lib/libaudio_client.so
rm -f $(STAGING_DIR)/usr/lib/libaudio_client.so
rm -f $(STAGING_DIR)/usr/include/audio_if_client.h
diff --git a/src/dap_setting.c b/src/dap_setting.c
new file mode 100644
index 0000000..f1b5029
--- /dev/null
+++ b/src/dap_setting.c
@@ -0,0 +1,53 @@
+#include <stdio.h>
+#include <audio_if.h>
+
+#define MS12_RUNTIME_CMD \
+ "ms12_runtime="
+#define DAP_DISABLE_SURROUND_DECODER_CMD \
+ "-dap_surround_decoder_enable 0"
+#define DAP_BOOST_TREBLE \
+ "-dap_graphic_eq 1,2,8000,16000,500,500"
+#define DAP_GAIN \
+ "-dap_gains -1024"
+#define SPACE \
+ " "
+
+int main()
+{
+ audio_hw_device_t *device;
+ int ret = audio_hw_load_interface(&device);
+
+ if (ret) {
+ fprintf(stderr, "audio_hw_load_interface failed: %d\n", ret);
+ return ret;
+ }
+
+ printf("hw version: %x\n", device->common.version);
+ printf("hal api version: %x\n", device->common.module->hal_api_version);
+ printf("module id: %s\n", device->common.module->id);
+ printf("module name: %s\n", device->common.module->name);
+
+ int inited = device->init_check(device);
+ if (inited) {
+ printf("device not inited, quit\n");
+ audio_hw_unload_interface(device);
+ return -1;
+ }
+
+#if 1
+ ret = device->set_parameters(device,
+ MS12_RUNTIME_CMD
+ DAP_DISABLE_SURROUND_DECODER_CMD
+ SPACE
+ DAP_BOOST_TREBLE);
+#else
+ ret = device->set_parameters(device,
+ MS12_RUNTIME_CMD
+ DAP_GAIN);
+#endif
+
+ audio_hw_unload_interface(device);
+
+ return ret;
+}
+
diff --git a/src/digital_mode.c b/src/digital_mode.c
new file mode 100644
index 0000000..061af5d
--- /dev/null
+++ b/src/digital_mode.c
@@ -0,0 +1,51 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <audio_if.h>
+
+#define DIGITAL_MODE_PCM 0
+#define DIGITAL_MODE_DD 4
+#define DIGITAL_MODE_AUTO 5
+
+#define DIGITAL_MODE_CMD "hdmi_mode="
+
+int main(int argc, char **argv)
+{
+ audio_hw_device_t *device;
+ int mode, ret;
+ char cmd[256];
+
+ if (argc < 2) {
+ printf("Usage: digital_mode <mode>\n");
+ return -1;
+ }
+
+ mode = atoi(argv[1]);
+ if ((mode != DIGITAL_MODE_PCM) &&
+ (mode != DIGITAL_MODE_DD) &&
+ (mode != DIGITAL_MODE_AUTO)) {
+ printf("Invalid mode\n");
+ return -2;
+ }
+ snprintf(cmd, sizeof(cmd), "%s%d", DIGITAL_MODE_CMD, mode);
+
+ ret = audio_hw_load_interface(&device);
+ if (ret) {
+ fprintf(stderr, "audio_hw_load_interface failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = device->init_check(device);
+ if (ret) {
+ printf("device not inited, quit\n");
+ audio_hw_unload_interface(device);
+ return -1;
+ }
+
+ ret = device->set_parameters(device, cmd);
+ printf("set_parameters returns %d\n", ret);
+
+ audio_hw_unload_interface(device);
+
+ return ret;
+}
+
diff --git a/src/hdmi_tx_cec_20.h b/src/hdmi_tx_cec_20.h
new file mode 100644
index 0000000..42d964c
--- /dev/null
+++ b/src/hdmi_tx_cec_20.h
@@ -0,0 +1,337 @@
+/*
+ * include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_cec_20.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef _TX_CEC_H_
+#define _TX_CEC_H_
+
+/*#include <linux/irq.h>
+#include <linux/amlogic/cpu_version.h>
+#include "hdmi_info_global.h"
+#include "hdmi_tx_module.h"*/
+
+#define CEC0_LOG_ADDR 4 /* MBX logical address */
+#define TV_CEC_INTERVAL (HZ*3)
+
+#define CEC_VERSION "v1.3"
+#define _RX_DATA_BUF_SIZE_ 16
+
+#define AO_CEC /* for switch between aocec and hdmi cec2.0 */
+
+#define MAX_MSG 16
+#define MAX_NUM_OF_DEV 16
+
+enum _cec_log_dev_addr_e {
+ CEC_TV_ADDR = 0x00,
+ CEC_RECORDING_DEVICE_1_ADDR,
+ CEC_RECORDING_DEVICE_2_ADDR,
+ CEC_TUNER_1_ADDR,
+ CEC_PLAYBACK_DEVICE_1_ADDR,
+ CEC_AUDIO_SYSTEM_ADDR,
+ CEC_TUNER_2_ADDR,
+ CEC_TUNER_3_ADDR,
+ CEC_PLAYBACK_DEVICE_2_ADDR,
+ CEC_RECORDING_DEVICE_3_ADDR,
+ CEC_TUNER_4_ADDR,
+ CEC_PLAYBACK_DEVICE_3_ADDR,
+ CEC_RESERVED_1_ADDR,
+ CEC_RESERVED_2_ADDR,
+ CEC_FREE_USE_ADDR,
+ CEC_UNREGISTERED_ADDR
+};
+
+#define CEC_BROADCAST_ADDR CEC_UNREGISTERED_ADDR
+
+#define CEC_TV (1 << CEC_TV_ADDR)
+#define CEC_RECORDING_DEVICE_1 (1 << CEC_RECORDING_DEVICE_1_ADDR)
+#define CEC_RECORDING_DEVICE_2 (1 << CEC_RECORDING_DEVICE_2_ADDR)
+#define CEC_TUNER_1 (1 << CEC_TUNER_1_ADDR)
+#define CEC_PLAYBACK_DEVICE_1 (1 << CEC_PLAYBACK_DEVICE_1_ADDR)
+#define CEC_AUDIO_SYSTEM (1 << CEC_AUDIO_SYSTEM_ADDR)
+#define CEC_TUNER_2 (1 << CEC_TUNER_2_ADDR)
+#define CEC_TUNER_3 (1 << CEC_TUNER_3_ADDR)
+#define CEC_PLAYBACK_DEVICE_2 (1 << CEC_PLAYBACK_DEVICE_2_ADDR)
+#define CEC_RECORDING_DEVICE_3 (1 << CEC_RECORDING_DEVICE_3_ADDR)
+#define CEC_TUNER_4 (1 << CEC_TUNER_4_ADDR)
+#define CEC_PLAYBACK_DEVICE_3 (1 << CEC_PLAYBACK_DEVICE_3_ADDR)
+#define CEC_RESERVED_1 (1 << CEC_RESERVED_1_ADDR)
+#define CEC_RESERVED_2 (1 << CEC_RESERVED_2_ADDR)
+#define CEC_FREE_USE (1 << CEC_FREE_USE_ADDR)
+#define CEC_UNREGISTERED (1 << CEC_UNREGISTERED_ADDR)
+
+#define CEC_DISPLAY_DEVICE (CEC_TV | CEC_FREE_USE)
+#define CEC_RECORDING_DEVICE (CEC_RECORDING_DEVICE_1 \
+ | CEC_RECORDING_DEVICE_2 | CEC_RECORDING_DEVICE_3)
+#define CEC_PLAYBACK_DEVICE (CEC_PLAYBACK_DEVICE_1 \
+ | CEC_PLAYBACK_DEVICE_2 | CEC_PLAYBACK_DEVICE_3)
+#define CEC_TUNER_DEVICE (CEC_TUNER_1 | CEC_TUNER_2 \
+ | CEC_TUNER_3 | CEC_TUNER_4)
+#define CEC_AUDIO_SYSTEM_DEVICE (CEC_AUDIO_SYSTEM)
+
+#define CEC_IOC_MAGIC 'C'
+#define CEC_IOC_GET_PHYSICAL_ADDR _IOR(CEC_IOC_MAGIC, 0x00, uint16_t)
+#define CEC_IOC_GET_VERSION _IOR(CEC_IOC_MAGIC, 0x01, int)
+#define CEC_IOC_GET_VENDOR_ID _IOR(CEC_IOC_MAGIC, 0x02, uint32_t)
+#define CEC_IOC_GET_PORT_INFO _IOR(CEC_IOC_MAGIC, 0x03, int)
+#define CEC_IOC_GET_PORT_NUM _IOR(CEC_IOC_MAGIC, 0x04, int)
+#define CEC_IOC_GET_SEND_FAIL_REASON _IOR(CEC_IOC_MAGIC, 0x05, uint32_t)
+#define CEC_IOC_SET_OPTION_WAKEUP _IOW(CEC_IOC_MAGIC, 0x06, uint32_t)
+#define CEC_IOC_SET_OPTION_ENALBE_CEC _IOW(CEC_IOC_MAGIC, 0x07, uint32_t)
+#define CEC_IOC_SET_OPTION_SYS_CTRL _IOW(CEC_IOC_MAGIC, 0x08, uint32_t)
+#define CEC_IOC_SET_OPTION_SET_LANG _IOW(CEC_IOC_MAGIC, 0x09, uint32_t)
+#define CEC_IOC_GET_CONNECT_STATUS _IOR(CEC_IOC_MAGIC, 0x0A, uint32_t)
+#define CEC_IOC_ADD_LOGICAL_ADDR _IOW(CEC_IOC_MAGIC, 0x0B, uint32_t)
+#define CEC_IOC_CLR_LOGICAL_ADDR _IOW(CEC_IOC_MAGIC, 0x0C, uint32_t)
+#define CEC_IOC_SET_DEV_TYPE _IOW(CEC_IOC_MAGIC, 0x0D, uint32_t)
+#define CEC_IOC_SET_ARC_ENABLE _IOW(CEC_IOC_MAGIC, 0x0E, uint32_t)
+#define CEC_IOC_SET_AUTO_DEVICE_OFF _IOW(CEC_IOC_MAGIC, 0x0F, uint32_t)
+#define CEC_IOC_GET_BOOT_ADDR _IOW(CEC_IOC_MAGIC, 0x10, uint32_t)
+#define CEC_IOC_GET_BOOT_REASON _IOW(CEC_IOC_MAGIC, 0x11, uint32_t)
+#define CEC_IOC_SET_FREEZE_MODE _IOW(CEC_IOC_MAGIC, 0x12, uint32_t)
+#define CEC_IOC_GET_BOOT_PORT _IOW(CEC_IOC_MAGIC, 0x13, uint32_t)
+
+enum cec_tx_ret {
+ CEC_FAIL_NONE = 0,
+ CEC_FAIL_NACK = 1,
+ CEC_FAIL_BUSY = 2,
+ CEC_FAIL_OTHER = 3
+};
+
+enum hdmi_port_type {
+ HDMI_INPUT = 0,
+ HDMI_OUTPUT = 1
+};
+
+struct hdmi_port_info {
+ int type;
+ /* Port ID should start from 1 which corresponds to HDMI "port 1". */
+ int port_id;
+ int cec_supported;
+ int arc_supported;
+ uint16_t physical_address;
+};
+
+enum cec_dev_type_addr {
+ CEC_DISPLAY_DEVICE_TYPE = 0x0,
+ CEC_RECORDING_DEVICE_TYPE,
+ CEC_RESERVED_DEVICE_TYPE,
+ CEC_TUNER_DEVICE_TYPE,
+ CEC_PLAYBACK_DEVICE_TYPE,
+ CEC_AUDIO_SYSTEM_DEVICE_TYPE,
+ CEC_UNREGISTERED_DEVICE_TYPE,
+};
+
+enum cec_feature_abort_e {
+ CEC_UNRECONIZED_OPCODE = 0x0,
+ CEC_NOT_CORRECT_MODE_TO_RESPOND,
+ CEC_CANNOT_PROVIDE_SOURCE,
+ CEC_INVALID_OPERAND,
+ CEC_REFUSED,
+ CEC_UNABLE_TO_DETERMINE,
+};
+
+/*
+ * CEC OPCODES
+ */
+#define CEC_OC_ABORT_MESSAGE 0xFF
+#define CEC_OC_ACTIVE_SOURCE 0x82
+#define CEC_OC_CEC_VERSION 0x9E
+#define CEC_OC_CLEAR_ANALOGUE_TIMER 0x33
+#define CEC_OC_CLEAR_DIGITAL_TIMER 0x99
+#define CEC_OC_CLEAR_EXTERNAL_TIMER 0xA1
+#define CEC_OC_DECK_CONTROL 0x42
+#define CEC_OC_DECK_STATUS 0x1B
+#define CEC_OC_DEVICE_VENDOR_ID 0x87
+#define CEC_OC_FEATURE_ABORT 0x00
+#define CEC_OC_GET_CEC_VERSION 0x9F
+#define CEC_OC_GET_MENU_LANGUAGE 0x91
+#define CEC_OC_GIVE_AUDIO_STATUS 0x71
+#define CEC_OC_GIVE_DECK_STATUS 0x1A
+#define CEC_OC_GIVE_DEVICE_POWER_STATUS 0x8F
+#define CEC_OC_GIVE_DEVICE_VENDOR_ID 0x8C
+#define CEC_OC_GIVE_OSD_NAME 0x46
+#define CEC_OC_GIVE_PHYSICAL_ADDRESS 0x83
+#define CEC_OC_GIVE_SYSTEM_AUDIO_MODE_STATUS 0x7D
+#define CEC_OC_GIVE_TUNER_DEVICE_STATUS 0x08
+#define CEC_OC_IMAGE_VIEW_ON 0x04
+#define CEC_OC_INACTIVE_SOURCE 0x9D
+#define CEC_OC_MENU_REQUEST 0x8D
+#define CEC_OC_MENU_STATUS 0x8E
+#define CEC_OC_PLAY 0x41
+#define CEC_OC_POLLING_MESSAGE 0xFC
+#define CEC_OC_RECORD_OFF 0x0B
+#define CEC_OC_RECORD_ON 0x09
+#define CEC_OC_RECORD_STATUS 0x0A
+#define CEC_OC_RECORD_TV_SCREEN 0x0F
+#define CEC_OC_REPORT_AUDIO_STATUS 0x7A
+#define CEC_OC_REPORT_PHYSICAL_ADDRESS 0x84
+#define CEC_OC_REPORT_POWER_STATUS 0x90
+#define CEC_OC_REQUEST_ACTIVE_SOURCE 0x85
+#define CEC_OC_ROUTING_CHANGE 0x80
+#define CEC_OC_ROUTING_INFORMATION 0x81
+#define CEC_OC_SELECT_ANALOGUE_SERVICE 0x92
+#define CEC_OC_SELECT_DIGITAL_SERVICE 0x93
+#define CEC_OC_SET_ANALOGUE_TIMER 0x34
+#define CEC_OC_SET_AUDIO_RATE 0x9A
+#define CEC_OC_SET_DIGITAL_TIMER 0x97
+#define CEC_OC_SET_EXTERNAL_TIMER 0xA2
+#define CEC_OC_SET_MENU_LANGUAGE 0x32
+#define CEC_OC_SET_OSD_NAME 0x47
+#define CEC_OC_SET_OSD_STRING 0x64
+#define CEC_OC_SET_STREAM_PATH 0x86
+#define CEC_OC_SET_SYSTEM_AUDIO_MODE 0x72
+#define CEC_OC_SET_TIMER_PROGRAM_TITLE 0x67
+#define CEC_OC_STANDBY 0x36
+#define CEC_OC_SYSTEM_AUDIO_MODE_REQUEST 0x70
+#define CEC_OC_SYSTEM_AUDIO_MODE_STATUS 0x7E
+#define CEC_OC_TEXT_VIEW_ON 0x0D
+#define CEC_OC_TIMER_CLEARED_STATUS 0x43
+#define CEC_OC_TIMER_STATUS 0x35
+#define CEC_OC_TUNER_DEVICE_STATUS 0x07
+#define CEC_OC_TUNER_STEP_DECREMENT 0x06
+#define CEC_OC_TUNER_STEP_INCREMENT 0x05
+#define CEC_OC_USER_CONTROL_PRESSED 0x44
+#define CEC_OC_USER_CONTROL_RELEASED 0x45
+#define CEC_OC_VENDOR_COMMAND 0x89
+#define CEC_OC_VENDOR_COMMAND_WITH_ID 0xA0
+#define CEC_OC_VENDOR_REMOTE_BUTTON_DOWN 0x8A
+#define CEC_OC_VENDOR_REMOTE_BUTTON_UP 0x8B
+
+/* cec global struct */
+
+enum cec_node_status_e {
+ STATE_UNKNOWN = 0x00,
+ STATE_START,
+ STATE_STOP
+};
+
+enum cec_power_status_e {
+ CEC_PW_POWER_ON = 0x00,
+ CEC_PW_STANDBY,
+ CEC_PW_TRANS_STANDBY_TO_ON,
+ CEC_PW_TRANS_ON_TO_STANDBY,
+};
+
+enum status_req_mode_e {
+ STATUS_REQ_ON = 1,
+ STATUS_REQ_OFF,
+ STATUS_REQ_ONCE,
+};
+
+enum deck_info_e {
+ DECK_UNKNOWN_STATUS = 0,
+ DECK_PLAY = 0X11,
+ DECK_RECORD,
+ DECK_PLAY_REVERSE,
+ DECK_STILL,
+ DECK_SLOW,
+ DECK_SLOW_REVERSE,
+ DECK_FAST_FORWARD,
+ DECK_FAST_REVERSE,
+ DECK_NO_MEDIA,
+ DECK_STOP,
+ DECK_SKIP_FORWARD_WIND,
+ DECK_SKIP_REVERSE_REWIND,
+ DECK_INDEX_SEARCH_FORWARD,
+ DECK_INDEX_SEARCH_REVERSE,
+ DECK_OTHER_STATUS,
+};
+
+enum deck_cnt_mode_e {
+ DECK_CNT_SKIP_FORWARD_WIND = 1,
+ DECK_CNT_SKIP_REVERSE_REWIND,
+ DECK_CNT_STOP,
+ DECK_CNT_EJECT,
+};
+
+enum play_mode_e {
+ PLAY_FORWARD = 0X24,
+ PLAY_REVERSE = 0X20,
+ PLAY_STILL = 0X25,
+ FAST_FORWARD_MIN_SPEED = 0X05,
+ FAST_FORWARD_MEDIUM_SPEED = 0X06,
+ FAST_FORWARD_MAX_SPEED = 0X07,
+ FAST_REVERSE_MIN_SPEED = 0X09,
+ FAST_REVERSE_MEDIUM_SPEED = 0X0A,
+ FAST_REVERSE_MAX_SPEED = 0X0B,
+ SLOW_FORWARD_MIN_SPEED = 0X15,
+ SLOW_FORWARD_MEDIUM_SPEED = 0X16,
+ SLOW_FORWARD_MAX_SPEED = 0X17,
+ SLOW_REVERSE_MIN_SPEED = 0X19,
+ SLOW_REVERSE_MEDIUM_SPEED = 0X1A,
+ SLOW_REVERSE_MAX_SPEED = 0X1B,
+};
+
+enum cec_version_e {
+ CEC_VERSION_11 = 0,
+ CEC_VERSION_12,
+ CEC_VERSION_12A,
+ CEC_VERSION_13,
+ CEC_VERSION_13A,
+ CEC_VERSION_14A,
+ CEC_VERSION_20,
+};
+
+
+#define INFO_MASK_CEC_VERSION (1<<0)
+#define INFO_MASK_VENDOR_ID (1<<1)
+#define INFO_MASK_DEVICE_TYPE (1<<2)
+#define INFO_MASK_POWER_STATUS (1<<3)
+#define INFO_MASK_PHYSICAL_ADDRESS (1<<4)
+#define INFO_MASK_LOGIC_ADDRESS (1<<5)
+#define INFO_MASK_OSD_NAME (1<<6)
+#define INFO_MASK_MENU_STATE (1<<7)
+#define INFO_MASK_MENU_LANGUAGE (1<<8)
+#define INFO_MASK_DECK_INfO (1<<9)
+#define INFO_MASK_PLAY_MODE (1<<10)
+
+/*CEC UI MASK*/
+/*
+#define CEC_FUNC_MSAK 0
+#define ONE_TOUCH_PLAY_MASK 1
+#define ONE_TOUCH_STANDBY_MASK 2
+#define AUTO_POWER_ON_MASK 3
+*/
+
+/*
+ * only for 1 tx device
+ */
+/*struct cec_global_info_t {
+ dev_t dev_no;
+ atomic_t open_count;
+ unsigned int hal_ctl; // message controlled by hal
+ unsigned int vendor_id:24;
+ unsigned int menu_lang;
+ unsigned int cec_version;
+ unsigned char power_status;
+ unsigned char log_addr;
+ unsigned int addr_enable;
+ unsigned char menu_status;
+ unsigned char osd_name[16];
+ struct input_dev *remote_cec_dev; // cec input device
+ struct hdmitx_dev *hdmitx_device;
+};*/
+
+enum cec_device_menu_state_e {
+ DEVICE_MENU_ACTIVE = 0,
+ DEVICE_MENU_INACTIVE,
+};
+
+int cec_ll_tx(const unsigned char *msg, unsigned char len);
+int cec_ll_rx(unsigned char *msg, unsigned char *len);
+extern void cec_enable_arc_pin(bool enable);
+#endif
+
diff --git a/src/speaker_delay.c b/src/speaker_delay.c
new file mode 100644
index 0000000..b598ad8
--- /dev/null
+++ b/src/speaker_delay.c
@@ -0,0 +1,46 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <audio_if.h>
+
+#define SPEAKER_DELAY_CMD "hal_param_speaker_delay_time_ms="
+
+int main(int argc, char **argv)
+{
+ audio_hw_device_t *device;
+ int delay = 0, ret;
+ char cmd[256];
+
+ if (argc < 2) {
+ printf("Usage: hal_set_speaker_delay <delay in ms>\n");
+ return -1;
+ }
+
+ delay = atoi(argv[1]);
+ if ((delay < 0) || (delay >= 1000)) {
+ printf("Delay out of range\n");
+ return -2;
+ }
+ snprintf(cmd, sizeof(cmd), "%s%d", SPEAKER_DELAY_CMD, delay);
+
+ ret = audio_hw_load_interface(&device);
+ if (ret) {
+ fprintf(stderr, "audio_hw_load_interface failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = device->init_check(device);
+ if (ret) {
+ printf("device not inited, quit\n");
+ audio_hw_unload_interface(device);
+ return -1;
+ }
+
+ ret = device->set_parameters(device, cmd);
+ printf("set_parameters returns %d\n", ret);
+
+ audio_hw_unload_interface(device);
+
+ return ret;
+}
+
+
diff --git a/src/start_arc.c b/src/start_arc.c
new file mode 100644
index 0000000..ffdabec
--- /dev/null
+++ b/src/start_arc.c
@@ -0,0 +1,160 @@
+
+#include <string.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/poll.h>
+#include <sys/time.h>
+
+//#include</linux/amlogic/cec_common.h>
+#include "hdmi_tx_cec_20.h"
+
+#define DEV_CEC "/dev/cec"
+static int Cec_fd = 0;
+#define HDR 0
+#define OPCODE 1
+#define OPERAND 2
+
+#define CEC_MSG_HDR_BROADCAST 0x0F
+#define CEC_MSG_HDR 0x05
+#define INITIATE_ARC 0XC0
+#define REPORT_ARC_INITIATED 0XC1
+#define REPORT_ARC_TERMINATED 0XC2
+#define REQUEST_ARC_INITIATION 0XC3
+#define REQUEST_ARC_TERMINATION 0XC4
+#define TERMINATE_ARC 0XC5
+char CEC_MSG_ARC_INITIATED[]={CEC_MSG_HDR,REPORT_ARC_INITIATED};
+
+static pthread_t CEC_Event_Thread;
+struct pollfd polling;
+static bool arc_not_initialised = true;
+static char cecmsg[16] ;
+static int stop =0;
+static char msg_to_send[16];
+
+void process_cec_msg(char * cec_msg,int len)
+{
+ int i = 0;
+
+ switch (cec_msg[OPCODE]) {
+ case INITIATE_ARC :
+ printf("Got the Initiate ARC message Amplifeir requesting to start ARC\n");
+ arc_not_initialised = false;
+ write(Cec_fd,CEC_MSG_ARC_INITIATED, 2);
+ printf("Sending the ARC initiated message to the Amplifier\n");
+ stop =1;
+ break;
+
+ case CEC_OC_GIVE_PHYSICAL_ADDRESS :
+ printf("CEC_OC_GIVE_PHYSICAL_ADDRESS\n");
+ msg_to_send[0] = CEC_MSG_HDR_BROADCAST;
+ msg_to_send[1] = CEC_OC_REPORT_PHYSICAL_ADDRESS;
+ msg_to_send[2] = 0x00;
+ msg_to_send[3] = 0x00;
+ msg_to_send[4] = 0x00;
+
+ write(Cec_fd,msg_to_send,5);
+ printf("Sending CEC_OC_REPORT_PHYSICAL_ADDRESS\n");
+ break;
+
+ default :
+ {
+ printf("CEC msg is ");
+ for(i=0;i< len;i++) {
+ printf(" 0x%x ",cec_msg[i]);
+ }
+ }
+ printf("\n###################");
+ break;
+ }
+}
+
+void* CEC_event_read_fn (void *data)
+{
+ int timeout = -1;
+ unsigned int mask = 0;
+ int read_len =0;
+
+ polling.fd= Cec_fd;
+ polling.events = POLLIN;
+
+ while(!stop) {
+ mask = poll(&polling,1,timeout);
+
+ if (mask & POLLIN || mask & POLLRDNORM ) {
+ read_len= read(Cec_fd, &cecmsg, 1);
+ process_cec_msg(cecmsg,read_len);
+ }
+ }
+}
+
+static void sighandler(int sig)
+{
+ printf("Interrupted by signal %d\n", sig);
+ stop= 1;
+ printf("sighandler! Done\n");
+}
+
+int main ( int argc, char *argv[] )
+{
+ char msg[16];
+ int ret=0;
+
+ Cec_fd = open (DEV_CEC, O_RDWR);
+
+ if (Cec_fd < 0) {
+ printf ("%s CEC_device opening returned %d",DEV_CEC);
+ return -1;
+ }
+
+ ret = pthread_create(&CEC_Event_Thread, NULL, CEC_event_read_fn, NULL);
+ if (ret){
+ printf("Unable to create decoder event thread\n");
+ }
+
+ /* setup the signal handler for CTRL-C */
+ signal(SIGINT, sighandler);
+ /*kill -USR1 pid */
+ signal(SIGUSR1, sighandler);
+
+ ioctl(Cec_fd, CEC_IOC_SET_OPTION_SYS_CTRL, 0x8);
+
+ ioctl(Cec_fd, CEC_IOC_ADD_LOGICAL_ADDR, 0x0);
+
+ /* request ARC initialisation */
+ msg[HDR]=CEC_MSG_HDR;
+ msg[OPCODE]=REQUEST_ARC_INITIATION;
+ write(Cec_fd,msg,2);
+ printf("sending ARC initialisation \n");
+
+ while (!stop) {
+ sleep(1);
+ if (arc_not_initialised) {
+ printf("TV sending Request ARC initialisation to Amplifier \n");
+ write(Cec_fd,msg,2);
+ }
+ }
+
+ ret = pthread_join(CEC_Event_Thread, NULL);
+ if (ret != 0) {
+ printf("CEC_Event_Thread returned error\n");
+ }
+
+ //ioctl(Cec_fd, CEC_IOC_CLR_LOGICAL_ADDR, 0x0);
+ //ioctl(Cec_fd, CEC_IOC_SET_OPTION_SYS_CTRL, 0x0);
+
+ close(Cec_fd);
+
+ return 0;
+}
+
+
+
diff --git a/src/test_arc.c b/src/test_arc.c
new file mode 100644
index 0000000..7bcadca
--- /dev/null
+++ b/src/test_arc.c
@@ -0,0 +1,422 @@
+
+#include <string.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/poll.h>
+#include <sys/time.h>
+
+//#include</linux/amlogic/cec_common.h>
+#include "hdmi_tx_cec_20.h"
+#include "data.h"
+#include "audio_if.h"
+
+
+#define DEV_CEC "/dev/cec"
+static int Cec_fd = 0;
+#define HDR 0
+#define OPCODE 1
+#define OPERAND 2
+
+#define CEC_MSG_HDR_BROADCAST 0x0F
+#define CEC_MSG_HDR 0x05
+#define INITIATE_ARC 0XC0
+#define REPORT_ARC_INITIATED 0XC1
+#define REPORT_ARC_TERMINATED 0XC2
+#define REQUEST_ARC_INITIATION 0XC3
+#define REQUEST_ARC_TERMINATION 0XC4
+#define TERMINATE_ARC 0XC5
+char CEC_MSG_ARC_INITIATED[]={CEC_MSG_HDR,REPORT_ARC_INITIATED};
+
+static pthread_t CEC_Event_Thread;
+struct pollfd polling;
+static bool arc_not_initialised = true;
+static char cecmsg[16] ;
+static int stop =0;
+static char msg_to_send[16];
+
+/* Audio stuffs */
+
+
+#define TV_AUDIO_OUTPUT
+
+#ifdef TV_AUDIO_OUTPUT
+static struct audio_port_config source_;
+static struct audio_port_config sink_;
+static audio_patch_handle_t patch_h_;
+
+static void test_patch(audio_hw_device_t *device)
+{
+ int ret;
+ /* create mixer to device patch */
+ source_.id = 1;
+ source_.role = AUDIO_PORT_ROLE_SOURCE;
+ source_.type = AUDIO_PORT_TYPE_MIX;
+ source_.config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE |
+ AUDIO_PORT_CONFIG_FORMAT;
+ source_.sample_rate = 48000;
+ source_.format = AUDIO_FORMAT_PCM_16_BIT;
+
+ sink_.id = 2;
+ sink_.role = AUDIO_PORT_ROLE_SINK;
+ sink_.type = AUDIO_PORT_TYPE_DEVICE;
+ sink_.config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE |
+ AUDIO_PORT_CONFIG_FORMAT;
+ sink_.sample_rate = 48000;
+ sink_.format = AUDIO_FORMAT_PCM_16_BIT;
+ sink_.ext.device.type = AUDIO_DEVICE_OUT_HDMI_ARC;
+
+ printf("create mix --> ARC patch...");
+ ret = device->create_audio_patch(device, 1, &source_, 1, &sink_, &patch_h_);
+ if (ret) {
+ printf("fail ret:%d\n",ret);
+ } else {
+ printf("success\n");
+ }
+}
+
+static void destroy_patch(audio_hw_device_t *device)
+{
+ if (patch_h_) {
+ int ret;
+ printf("destroy patch...");
+ ret = device->release_audio_patch(device, patch_h_);
+ if (ret) {
+ printf("fail ret:%d\n",ret);
+ } else {
+ printf("success\n");
+ }
+ }
+}
+#endif
+static void test_vol(audio_hw_device_t *device, int gain)
+{
+ int ret;
+ float vol = 0;
+ ret = device->get_master_volume(device, &vol);
+ if (ret) {
+ printf("get_master_volume fail\n");
+ } else {
+ printf("cur master vol:%f\n", vol);
+ }
+ ret = device->set_master_volume(device, 0.5f);
+ if (ret) {
+ printf("set_master_volume fail\n");
+ } else {
+ printf("set master vol 0.5\n");
+ device->set_master_volume(device, vol);
+ }
+
+#ifdef TV_AUDIO_OUTPUT
+ {
+ struct audio_port_config config;
+
+ memset(&config, 0, sizeof(config));
+ config.id = 2;
+ config.role = AUDIO_PORT_ROLE_SINK;
+ config.type = AUDIO_PORT_TYPE_DEVICE;
+ config.config_mask = AUDIO_PORT_CONFIG_GAIN;
+ /* audio_hal use dB * 100 to keep the accuracy */
+ config.gain.values[0] = gain * 100;
+ printf("set gain to %ddB...\n", gain);
+ ret = device->set_audio_port_config(device, &config);
+ if (ret) {
+ printf("fail\n");
+ } else {
+ printf("success\n");
+ }
+ }
+#endif
+}
+
+#define WRITE_UNIT 4096
+#define min(a, b) ((a) < (b) ? (a) : (b))
+static int test_stream(struct audio_stream_out *stream)
+{
+ int i, ret;
+ int len;
+ unsigned char *data;
+
+ ret = stream->set_volume(stream, 1.0f, 1.0f);
+ if (ret) {
+ fprintf(stderr, "%s %d, ret:%x\n", __func__, __LINE__, ret);
+ return -1;
+ }
+
+ printf("Start output to audio HAL\n");
+ for (i = 0; i < 10; i++) {
+ data = wav_data;
+ len = sizeof(wav_data);
+ while (len > 0) {
+ ssize_t s = stream->write(stream, data, min(len, WRITE_UNIT));
+ if (s < 0) {
+ fprintf(stderr, "stream writing error %d\n", s);
+ break;
+ }
+
+ len -= s;
+ data += s;
+ }
+ }
+
+ return 0;
+}
+
+#define HDMI_ARC_OUTPUT_DD
+
+static void test_output_stream(audio_hw_device_t *device)
+{
+ int ret;
+ struct audio_config config;
+ struct audio_stream_out *stream;
+ char cmd[32];
+
+ memset(&config, 0, sizeof(config));
+ config.sample_rate = 48000;
+ config.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ config.format = AUDIO_FORMAT_PCM_16_BIT;
+
+ printf("Tell audio HAL HDMI ARC is connected\n");
+ ret = device->set_parameters(device, "connect=0x40000");
+ if (ret) {
+ fprintf(stderr, "set_parameters HDMI connected failed\n");
+ }
+
+#ifdef HDMI_ARC_OUTPUT_DD
+ printf("Set HDMI ARC output format to AC3\n");
+ ret = device->set_parameters(device, "hdmi_format=4");
+ if (ret) {
+ fprintf(stderr, "set_parameters failed\n");
+ }
+#else
+ printf("Set HDMI ARC output format to PCM\n");
+ ret = device->set_parameters(device, "hdmi_format=0");
+ if (ret) {
+ fprintf(stderr, "set_parameters failed\n");
+ }
+#endif
+
+#ifdef HDMI_ARC_OUTPUT_DD
+ /*
+ * The following set_parameters calling sequence is needed
+ * to meet the audio HAL internal checking for ARC output:
+ * 1. "HDMI ARC Switch" key is used for UI control switch to enable
+ * ARC output.
+ * 2. "connect" key is used to tell audio HAL the connection status
+ * 3. "speaker_mute" is also checked to make sure ARC output is
+ * effective.
+ */
+ printf("Report UI settings for HDMI ARC enabled\n");
+ ret = device->set_parameters(device, "HDMI ARC Switch=1");
+ if (ret) {
+ fprintf(stderr, "set_parameters failed\n");
+ }
+
+ printf("Report HDMI ARC is connected\n");
+ snprintf(cmd, sizeof(cmd), "connect=%d", AUDIO_DEVICE_OUT_HDMI_ARC);
+ ret = device->set_parameters(device, cmd);
+ if (ret) {
+ fprintf(stderr, "set_parameters failed\n");
+ }
+
+ printf("Mute speaker output\n");
+ ret = device->set_parameters(device, "speaker_mute=1");
+ if (ret) {
+ fprintf(stderr, "set_parameters failed\n");
+ }
+#endif
+
+ printf("open output to HDMI_ARC with direct mode...\n");
+ ret = device->open_output_stream(device,
+ 0, AUDIO_DEVICE_OUT_HDMI_ARC,
+ AUDIO_OUTPUT_FLAG_PRIMARY | AUDIO_OUTPUT_FLAG_DIRECT, &config,
+ &stream, NULL);
+ if (ret) {
+ printf("fail\n");
+ return;
+ } else {
+ printf("success\n");
+ }
+
+ test_stream(stream);
+
+ printf("close output speaker...\n");
+ device->close_output_stream(device, stream);
+}
+
+void process_cec_msg(char * cec_msg,int len)
+{
+ int i=0;
+
+ switch (cec_msg[OPCODE]) {
+ case INITIATE_ARC :
+ printf("Got the Initiate ARC message Amplifeir requesting to start ARC\n");
+ arc_not_initialised = false;
+ write(Cec_fd,CEC_MSG_ARC_INITIATED,2);
+ printf("Sending the ARC initiated message to the Amplifier\n");
+ stop =1;
+ break;
+
+ case CEC_OC_GIVE_PHYSICAL_ADDRESS :
+ printf("CEC_OC_GIVE_PHYSICAL_ADDRESS\n");
+ msg_to_send[0] = CEC_MSG_HDR_BROADCAST;
+ msg_to_send[1] = CEC_OC_REPORT_PHYSICAL_ADDRESS;
+ msg_to_send[2] = 0x00;
+ msg_to_send[3] = 0x00;
+ msg_to_send[4] = 0x00;
+ write(Cec_fd,msg_to_send,5);
+ printf("Sending CEC_OC_REPORT_PHYSICAL_ADDRESS\n");
+ break;
+ default:
+ {
+ printf("CEC msg is ");
+ for(i=0;i< len;i++) {
+ printf(" 0x%x ",cec_msg[i]);
+ }
+ }
+ printf("\n###################");
+ break;
+ }
+}
+
+void* CEC_event_read_fn (void *data)
+{
+ int timeout = -1;
+ unsigned int mask = 0;
+ int read_len =0;
+
+ polling.fd= Cec_fd;
+ polling.events = POLLIN;
+
+ while (!stop) {
+ mask = poll(&polling,1,timeout);
+
+ if (mask & POLLIN || mask & POLLRDNORM) {
+ read_len= read(Cec_fd, &cecmsg, 1);
+ process_cec_msg(cecmsg,read_len);
+ }
+ }
+}
+
+static void sighandler(int sig)
+{
+ printf("Interrupted by signal %d\n", sig);
+ stop= 1;
+ printf("sighandler! Done\n");
+}
+
+int main(int argc, char *argv[])
+{
+ char msg[16];
+ int ret=0;
+ audio_hw_device_t *device;
+ int test_earc = 0;
+
+ if (argc > 1) {
+ test_earc = atoi(argv[1]);
+ if (test_earc) {
+ printf("Test EARC output, CEC communicatin will be skipped\n");
+ }
+ }
+
+ if (!test_earc) {
+ Cec_fd = open (DEV_CEC, O_RDWR);
+
+ if (Cec_fd < 0) {
+ printf ("%s CEC_device opening returned %d",DEV_CEC);
+ return -1;
+ }
+
+ ret = pthread_create(&CEC_Event_Thread, NULL, CEC_event_read_fn, NULL);
+ if (ret) {
+ printf("Unable to create decoder event thread\n");
+ }
+
+ /* setup the signal handler for CTRL-C */
+ signal(SIGINT, sighandler);
+ /*kill -USR1 pid */
+ signal(SIGUSR1, sighandler);
+
+ ioctl(Cec_fd, CEC_IOC_SET_OPTION_SYS_CTRL, 0x8);
+
+ ioctl(Cec_fd, CEC_IOC_ADD_LOGICAL_ADDR, 0x0);
+ msg[HDR]=CEC_MSG_HDR;
+ msg[OPCODE]=REQUEST_ARC_INITIATION;
+ write(Cec_fd,msg,2);
+ printf("sending ARC initialisation \n");
+ }
+
+ ret = audio_hw_load_interface(&device);
+ if (ret) {
+ printf("%s %d error:%d\n", __func__, __LINE__, ret);
+ return ret;
+ }
+ printf("hw version: %x\n", device->common.version);
+ printf("hal api version: %x\n", device->common.module->hal_api_version);
+ printf("module id: %s\n", device->common.module->id);
+ printf("module name: %s\n", device->common.module->name);
+
+ if (device->get_supported_devices) {
+ uint32_t support_dev = 0;
+ support_dev = device->get_supported_devices(device);
+ printf("supported device: %x\n", support_dev);
+ }
+
+ int inited = device->init_check(device);
+ if (inited) {
+ printf("device not inited, quit\n");
+ goto exit;
+ }
+
+ if (!test_earc) {
+ while (!stop) {
+ if (arc_not_initialised) {
+ printf("TV sending Request ARC initialisation to Amplifier \n");
+ write(Cec_fd,msg,2);
+ }
+ sleep(1);
+ }
+ }
+
+ sleep(2);
+
+ #ifdef TV_AUDIO_OUTPUT
+ test_patch(device);
+ #endif
+
+ test_output_stream(device);
+
+ if (!test_earc) {
+ ret = pthread_join(CEC_Event_Thread, NULL);
+ if (ret != 0) {
+ printf("CEC_Event_Thread returned error\n");
+ }
+
+ ioctl(Cec_fd, CEC_IOC_CLR_LOGICAL_ADDR, 0x0);
+ ioctl(Cec_fd, CEC_IOC_SET_OPTION_SYS_CTRL, 0x0);
+
+ close(Cec_fd);
+ }
+
+ /* Audio clean up */
+#ifdef TV_AUDIO_OUTPUT
+ destroy_patch(device);
+#endif
+
+exit:
+ device->common.close(&device->common);
+ audio_hw_unload_interface(device);
+ return 0;
+
+}
+
+
+