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;

+	

+}

+

+

+