update rccd2 for end-system integraton master
authora0220410 <peter-li@ti.com>
Mon, 26 Dec 2016 10:55:10 +0000 (18:55 +0800)
committera0220410 <peter-li@ti.com>
Mon, 26 Dec 2016 10:55:10 +0000 (18:55 +0800)
16 files changed:
rccd2/Android.mk [new file with mode: 0755]
rccd2/Makefile [new file with mode: 0755]
rccd2/android_utils.c [new file with mode: 0755]
rccd2/include/aic3xxx_cfw.h [new file with mode: 0755]
rccd2/include/android_utils.h [new file with mode: 0755]
rccd2/include/host_compile.h [new file with mode: 0755]
rccd2/include/rccd2.h [new file with mode: 0755]
rccd2/include/utils.h [new file with mode: 0755]
rccd2/rccd2.bat [new file with mode: 0755]
rccd2/rccd2.c [new file with mode: 0755]
rccd2/rccd2.sh [new file with mode: 0755]
rccd2/utils.c [new file with mode: 0755]
ti_audio/Android.mk [moved from Android.mk with 81% similarity]
ti_audio/CleanSpec.mk [moved from CleanSpec.mk with 100% similarity]
ti_audio/main.c [moved from main.c with 100% similarity]
ti_audio/ti_audio.h [moved from ti_audio.h with 100% similarity]

diff --git a/rccd2/Android.mk b/rccd2/Android.mk
new file mode 100755 (executable)
index 0000000..a22bf18
--- /dev/null
@@ -0,0 +1,12 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_C_INCLUDES:= external/rccd2/include
+LOCAL_CFLAGS := -O2 -g -W -Wall -D_LARGEFILE_SOURCE -DAIC3XXX_CFW_HOST_BLD -D_FILE_OFFSET_BITS=64
+LOCAL_SRC_FILES:= rccd2.c android_utils.c utils.c
+LOCAL_MODULE := rccd2
+LOCAL_STATIC_LIBRARIES:= libcutils libutils liblog
+LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS += -Werror
+
+include $(BUILD_EXECUTABLE)
diff --git a/rccd2/Makefile b/rccd2/Makefile
new file mode 100755 (executable)
index 0000000..5ba9dce
--- /dev/null
@@ -0,0 +1,57 @@
+ROOT_PATH = ../..
+BUILD := android
+#include ../../common/make.config
+
+RCCD_PORT = 1025
+
+NDK_PLATFORM_VER := 9
+APP_PLATFORM := android-16
+
+ADB = adb
+
+ACX_OBJS = acxrun.$(O) android_utils.$(O) $(C_DIR)/utils.$(O) $(H_DIR)/acx_compile.$(O)  \
+            $(H_DIR)/acx_parser.tab.$(O) $(H_DIR)/lex.yy.$(O) \
+            $(H_DIR)/organize_cmds.$(O) $(H_DIR)/lex.cfg.$(O) \
+            $(H_DIR)/read_cfg.tab.$(O) $(T_DIR)/host_compile.$(O) 
+
+
+RCCD2_OBJS = rccd2.o android_utils.o $(C_DIR)/utils.o
+
+all: rccd2 acxrun
+
+rccd2$(EXE_EXT): $(RCCD2_OBJS)
+       $(CC) $(CFLAGS) $(RCCD2_OBJS)  -o $@ $(LFLAGS)
+       cp rccd2 ../../out/rccd2
+       cp rccd2 ../../devout/rccd2
+
+acxrun$(EXE_EXT): $(ACX_OBJS)
+       $(CC) $(CFLAGS) $(ACX_OBJS)  -o $@ $(LFLAGS)
+
+push: rccd2 force
+       $(ADB) push rccd2 /data
+shell: force
+       $(ADB) shell
+
+rccd: push force
+       $(ADB) shell svc power stayon true
+       $(ADB) forward tcp:$(RCCD_PORT) tcp:$(RCCD_PORT)
+       $(ADB) shell /data/rccd2 -v 10 -p $(RCCD_PORT)
+
+clean:
+       rm -f $(RCCD2_OBJS) rccd2 acxrun $(ACX_OBJS)
+       $(MAKE) -C $(H_DIR)/.. clean
+
+$(H_DIR)/organize_cmds.$(O): $(H_DIR)/init_cram.h
+
+$(H_DIR)/init_cram.h: force
+       $(MAKE) BUILD=$(BUILD) -C $(H_DIR)/.. $(patsubst ../%, %, $@)
+
+$(H_DIR)/%.$(O): force
+       $(MAKE) BUILD=$(BUILD) -C $(H_DIR)/.. $(patsubst ../%, %, $@)
+
+$(T_DIR)/%.$(O): force
+       $(MAKE) BUILD=$(BUILD) -C $(H_DIR)/.. $(patsubst ../%, %, $@)
+
+force:
+       @true
diff --git a/rccd2/android_utils.c b/rccd2/android_utils.c
new file mode 100755 (executable)
index 0000000..56b091e
--- /dev/null
@@ -0,0 +1,526 @@
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
+#include <sys/ioctl.h>\r
+#include <linux/kdev_t.h>\r
+#include <unistd.h>\r
+#include <fcntl.h>\r
+#include <time.h>\r
+#include <errno.h>\r
+#include "utils.h"\r
+#include <stdlib.h>\r
+#include <stdarg.h>\r
+#include <stdio.h>\r
+\r
+#include "aic3xxx_cfw.h"\r
+#include "utils.h"\r
+#include "host_compile.h"\r
+#include "android_utils.h"\r
+\r
+int dump_cmds = 0;\r
+int mode = mode_undef;\r
+\r
+static int dev_fd, dev_no, modern;\r
+\r
+#define DEVICE_ID 98\r
+\r
+int regDumpId;\r
+char regBuffer[512];\r
+\r
+//static char *device;\r
+void diag(int lvl, char *fmt, ...)\r
+{\r
+       va_list ap;\r
+       va_start(ap, fmt);\r
+#ifdef ANDROID\r
+       __android_log_vprint(lvl, PROGRAM, fmt, ap);\r
+#endif\r
+       va_end(ap);\r
+       if (getppid() != 1 && (lvl >= (ANDROID_LOG_ERROR - verbose))) {\r
+               va_start(ap, fmt);\r
+               vfprintf(stderr, fmt, ap);\r
+               va_end(ap);\r
+               fprintf(stderr, "\n");\r
+       }\r
+       if (lvl >= ANDROID_LOG_FATAL)\r
+               exit(1);\r
+}\r
+\r
+const struct { char *node; int cfwb; } devices[] = {\r
+       { "aic3xxx_cfw", 1 },\r
+       { "tiload", 0 },\r
+       { "tiload_node", 0 }\r
+};\r
+int open_device(char *device)\r
+{\r
+       char dfile[64];\r
+       struct stat sbuf;\r
+       int i = 0, fd;\r
+       if (device)  {\r
+               // Possible use on host\r
+               DBGW("Device not null");\r
+               if (stat(device, &sbuf) == 0) {\r
+                       strncpy(dfile, device, sizeof(dfile)-1);\r
+                       goto open;\r
+               }\r
+               DBGW("Could not locate device \"%s\"", device);\r
+               // Switch exclusive to old style device if one is specified (rccd backwards-compatibilty)\r
+               while (devices[i].cfwb)\r
+                       ++i;\r
+       }\r
+       for (; i < ARRAY_LEN(devices); ++i) {\r
+               sprintf(dfile, "/dev/%s", devices[i].node);\r
+               if (stat(dfile, &sbuf) == 0)\r
+                       goto open;\r
+               DBGW("Missing device node \"%s\"\n\tLooking for %s in /proc/devices...", dfile, devices[i].node);\r
+               FILE *fp = fopen("/proc/devices", "r");\r
+               if (!fp)\r
+                       DBGF("Unable to read /proc/devices");\r
+               char ln[4096];\r
+               while (fgets(ln, sizeof(ln), fp)) {\r
+                       if (!strstr(ln, devices[i].node))\r
+                               continue;\r
+                       ln[strlen(ln) - 1] = 0;\r
+                       DBGW("Found node entry \"%s\"", ln);\r
+                       int major = strtol(ln, NULL, 10);\r
+                       DBGW("\tMajor number = %d", major);\r
+                       if (mknod(dfile, S_IFCHR | 0777, MKDEV(major, 0)) < 0)\r
+                               DBGF("Unable to\n\tmknod \"%s\" c %d 0", dfile, major);\r
+                       goto open;\r
+               }\r
+       }\r
+       //This was DBGF  \r
+       DBGW("Unable find entry for codec diagnostic device.  Please check\n"\r
+               "\tcat /proc/devices");\r
+\r
+\r
+       // CUstom code \r
+       //dfile = "/sdcard/RCCD2/Test.dev";\r
+       sprintf(dfile, "/sdcard/RCCD2/Test.dev");\r
+       i = 4;\r
+       DBGW("Device open is redirected to a file now - /sdcard/RCCD2/Test.dev");\r
+       goto open;\r
+\r
+\r
+       return -1;\r
+open:\r
+       if ((fd = open(dfile, O_RDWR, 0)) < 0)\r
+               DBGF("Unable to open device %s", dfile);\r
+       modern = devices[i].cfwb;\r
+       if (!modern) {\r
+               // This stuff below is needed on the old tiload device \r
+               // for purposes I don't fully understand\r
+               char magic[4];\r
+               ioctl(fd, _IOR(0xE0, 3, int), magic);\r
+       }\r
+       dev_fd = fd;\r
+       dev_no = i;\r
+       if (mode == mode_undef)\r
+               mode = devices[i].cfwb ? mode_kernel : mode_user;\r
+       DBG("Opened device %s, mode:%s", dfile, modern ? "modern" : "legacy");\r
+       return fd;\r
+}\r
+\r
+static int cbook = -1, cpage = -1, lock = 0;\r
+\r
+\r
+static void  mread_reg(union cfw_register reg, u8 *buf, int n)\r
+{\r
+       int ncmds = CFW_CMD_BURST_LEN(n);\r
+       int err, sz = CFW_BLOCK_SIZE(ncmds);\r
+       struct cfw_block *blk = ALLOC(sz);\r
+       blk->ncmds = ncmds;\r
+       blk->cmd[0].bhdr.cid = CFW_CMD_RBURST;\r
+       blk->cmd[0].bhdr.len = n;\r
+       blk->cmd[1].reg = reg;\r
+       if ((err = read(dev_fd, blk, sz)) != sz)\r
+               DBGF("Device read error %d", err);\r
+       memcpy(buf, blk->cmd[1].burst.data, n);\r
+}\r
+\r
+static void  mwrite_reg(union cfw_register reg, const u8 *buf, int n)\r
+{\r
+       int ncmds = (n <= 3) ? n : CFW_CMD_BURST_LEN(n);\r
+       int i, err, sz = CFW_BLOCK_SIZE(ncmds);\r
+       struct cfw_block *blk = ALLOC(sz);\r
+       blk->ncmds = ncmds;\r
+       if (n <= 3) {\r
+               for (i = 0; i < n; ++i) {\r
+                       blk->cmd[i].reg = reg;\r
+                       blk->cmd[i].reg.offset = reg.offset + i;\r
+                       blk->cmd[i].reg.data = buf[i + 1];\r
+               }\r
+       }\r
+       else {\r
+               blk->cmd[0].bhdr.cid = CFW_CMD_BURST;\r
+               blk->cmd[0].bhdr.len = n;\r
+               blk->cmd[1].reg = reg;\r
+               memcpy(blk->cmd[1].burst.data, buf + 1, n);\r
+       }\r
+       if ((err = write(dev_fd, blk, sz)) != sz)\r
+               DBGF("Device write error %d", err);\r
+}\r
+\r
+\r
+#define DREAD(reg, b, n) do { \\r
+       int err_ret__;                  \\r
+       DBGI("r 0x%02x 0x%02x, modern:%d", (b)[0], (n), modern); \\r
+       sprintf(regBuffer, "\nr %d %02x %02x%c", DEVICE_ID, (b)[0], (n),'\0'); \\r
+       write(regDumpId, &regBuffer, strlen(regBuffer)); \\r
+if (modern) {\\r
+       mread_reg(reg, (b), n); \\r
+}else if ((err_ret__ = read(dev_fd, b, n)) != n) \\r
+       DBGF("Device read error %d", err_ret__); \\r
+} while (0)\r
+#define DWRITE(reg, b, n) do { \\r
+       int err_ret__, i__;                  \\r
+       DBGI("w 0x%02x 0x%02x", (b)[0], (b)[1]); \\r
+       sprintf(regBuffer, "\nw %d %02x %02x%c", DEVICE_ID, (b)[0], (b)[1], '\0'); \\r
+       write(regDumpId, &regBuffer, strlen(regBuffer)); \\r
+for (i__ = 2; i__ < n; ++i__) \\r
+{DBGI("> 0x%02x", (b)[i__]); \\r
+       sprintf(regBuffer, " %02x%c", (b)[i__],'\0'); \\r
+       write(regDumpId, &regBuffer, strlen(regBuffer)); }\\r
+if (modern) {\\r
+       mwrite_reg(reg, b, n); \\r
+}else if ((err_ret__ = write(dev_fd, b, n)) != n) \\r
+       DBGF("Device write error %d", err_ret__); \\r
+} while (0)\r
+\r
+static void cfw_lock(int l)\r
+{\r
+       if (l && !lock) {\r
+               // FIXME dummy\r
+               lock = 1;\r
+       }\r
+       else if (!l && lock) {\r
+               lock = 0;\r
+       }\r
+}\r
+static int restore_lock;\r
+static void setpb(union cfw_register r)\r
+{\r
+       DBG("Enter setpb");\r
+       u8 data[2];\r
+       restore_lock = lock;\r
+       cfw_lock(1);\r
+       DBG("Set Page/Book: (0x%02x,0x%02x)", r.book, r.page);\r
+       // if (cbook != r.book) {\r
+       if (1){\r
+               //if (cpage != 0) {  \r
+               if (1){\r
+                       data[0] = data[1] = 0;\r
+                       if (!modern)\r
+                               DWRITE(r, data, 2);\r
+                       cpage = 0;\r
+               }\r
+               data[0] = 0x7F; data[1] = r.book;\r
+               if (!modern)\r
+                       DWRITE(r, data, 2);\r
+               cbook = r.book;\r
+               DBG("Set Book: [0x%02x]", r.book);\r
+       }\r
+\r
+       //if (cpage != r.page) {\r
+       if (1){ \r
+               data[0] = 0; data[1] = r.page;\r
+               if (!modern)\r
+                       DWRITE(r, data, 2);\r
+               cpage = r.page;\r
+               DBG("Set Page: [0x%02x]", r.page);\r
+       }\r
+       DBG("Exit setpb");\r
+}\r
+static void unsetpb(void)\r
+{\r
+       DBG("Enter unsetpb");\r
+       cfw_lock(restore_lock);\r
+       DBG("Exit unsetpb");\r
+}\r
+\r
+static u8 reg_read(union cfw_register reg)\r
+{\r
+       u8 ret;\r
+       ret = reg.offset;\r
+       setpb(reg);\r
+       mread_reg(reg, &ret, 1);\r
+\r
+       DREAD(reg, &ret, 1);\r
+       unsetpb();\r
+       return ret;\r
+}\r
+static void reg_write(union cfw_register reg)\r
+{\r
+       u8 data[2];\r
+       data[0] = reg.offset;\r
+       data[1] = reg.data;\r
+       setpb(reg);\r
+       DWRITE(reg, data, 2);\r
+       unsetpb();\r
+}\r
+static void reg_wait(union cfw_register reg, u8 mask, u8 data)\r
+{\r
+       u8 cur = reg_read(reg);\r
+       while ((cur & mask) != data) {\r
+               usleep(2000);\r
+               cur = reg_read(reg);\r
+       }\r
+}\r
+static int set_bits(u8 *data, u8 mask, u8 val)\r
+{\r
+       u8 nd;\r
+       nd = ((*data&(~mask)) | (mask&val));\r
+       if (nd == *data)\r
+               return 0;\r
+       *data = nd;\r
+       return 1;\r
+}\r
+static void cfw_op(unsigned char *var, struct cfw_cmd_op cmd)\r
+{\r
+       u32 op1, op2;\r
+       u32 cid = cmd.cid;\r
+\r
+       op1 = cmd.op1;\r
+       op2 = cmd.op2;\r
+       if (cid&CFW_CMD_OP1_ID)\r
+               op1 = var[op1];\r
+       if (cid&CFW_CMD_OP2_ID)\r
+               op2 = var[op2];\r
+       cid &= ~(CFW_CMD_OP1_ID | CFW_CMD_OP2_ID);\r
+\r
+       switch (cid) {\r
+       case CFW_CMD_OP_ADD: var[cmd.dst] = op1 + op2; break;\r
+       case CFW_CMD_OP_SUB: var[cmd.dst] = op1 - op2; break;\r
+       case CFW_CMD_OP_MUL: var[cmd.dst] = op1*op2; break;\r
+       case CFW_CMD_OP_DIV: var[cmd.dst] = op1 / op2; break;\r
+       case CFW_CMD_OP_AND: var[cmd.dst] = op1 & op2; break;\r
+       case CFW_CMD_OP_OR: var[cmd.dst] = op1 | op2; break;\r
+       case CFW_CMD_OP_SHL: var[cmd.dst] = (op1 << op2); break;\r
+       case CFW_CMD_OP_SHR: var[cmd.dst] = (op1 >> op2); break;\r
+       case CFW_CMD_OP_RR:\r
+               while (op2--) {\r
+                       var[cmd.dst] = (op1 >> 1) | ((op1 & 1) << 7);\r
+               }\r
+               break;\r
+       case CFW_CMD_OP_XOR: var[cmd.dst] = op1 ^ op2; break;\r
+       case CFW_CMD_OP_NOT: var[cmd.dst] = ~op1; break;\r
+       case CFW_CMD_OP_LNOT: var[cmd.dst] = !op1; break;\r
+       default: break;\r
+       }\r
+}\r
+\r
+static int bulk_write(union cfw_register reg, int count, const u8 *buf)\r
+{\r
+       setpb(reg);\r
+       DWRITE(reg, buf - 1, count + 1);\r
+       unsetpb();\r
+       return 0;\r
+}\r
+\r
+static int bulk_read(union cfw_register reg, int count, u8 *buf)\r
+{\r
+       int i;\r
+       if (reg.offset != buf[-1]) {\r
+               DBGW("Mismatched register offset for read (%d != %d)",\r
+                       reg.offset, buf[-1]);\r
+       }\r
+       buf[0] = reg.offset;\r
+\r
+       if (reg.offset == 0xFF && reg.book == 0xFF && reg.page == 0xFF)\r
+       {\r
+               /* To handle Ping*/\r
+               buf[0] = 0x7c;\r
+               buf[1] = 00;\r
+               buf[2] = 01;\r
+               buf[3] = 02;\r
+\r
+               DBGI("..........PING.......");\r
+\r
+       }\r
+       else\r
+       {\r
+\r
+               setpb(reg);\r
+               //DBG("Commenting of DRED");\r
+               DREAD(reg, buf, count);\r
+               unsetpb();\r
+       }\r
+       DBGI("Reading from (%d,%d,%d)... %d bytes", reg.book, reg.page, reg.offset,\r
+               count);\r
+       for (i = 0; i < count; i += 8) {\r
+               switch (count - i) {\r
+               case 1: DBGI("# 0x%02x", buf[i + 0]); break;\r
+               case 2: DBGI("# 0x%02x 0x%02x", buf[i + 0], buf[i + 1]); break;\r
+               case 3: DBGI("# 0x%02x 0x%02x 0x%02x", buf[i + 0], buf[i + 1], buf[i + 2]); break;\r
+               case 4: DBGI("# 0x%02x 0x%02x 0x%02x 0x%02x", buf[i + 0], buf[i + 1], buf[i + 2], buf[i + 3]); break;\r
+               case 5: DBGI("# 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", buf[i + 0], buf[i + 1], buf[i + 2], buf[i + 3], buf[i + 4]); break;\r
+               case 6: DBGI("# 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", buf[i + 0], buf[i + 1], buf[i + 2], buf[i + 3], buf[i + 4], buf[i + 5]); break;\r
+               case 7: DBGI("# 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", buf[i + 0], buf[i + 1], buf[i + 2], buf[i + 3], buf[i + 4], buf[i + 5], buf[i + 6]); break;\r
+               default:DBGI("# 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", buf[i + 0], buf[i + 1], buf[i + 2], buf[i + 3], buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7]); break;\r
+               }\r
+       }\r
+\r
+\r
+       return 0;\r
+}\r
+\r
+static void run_block_slow(struct cfw_block *pb, u8 *var)\r
+{\r
+       int pc = 0;\r
+       int cond = 0;\r
+       u8 data;\r
+//     int i;\r
+       \r
+       DBG("%s: pb->ncmds=%d", __FUNCTION__, pb->ncmds);\r
+       while (pc < pb->ncmds) {\r
+               union cfw_cmd *c = &(pb->cmd[pc]);\r
+               if (c->cid != CFW_CMD_BRANCH_IM &&\r
+                       c->cid != CFW_CMD_BRANCH_ID &&\r
+                       c->cid != CFW_CMD_NOP)\r
+                       cond = 0;\r
+               DBGI("%s: Case No %d:", __FUNCTION__, c->cid);\r
+               switch (c->cid) {\r
+\r
+               case 0 ... (CFW_CMD_NOP - 1) :\r
+                       DBGI("CFW_CMD_NOP-1");\r
+                       reg_write(c->reg);\r
+                       pc += 1;\r
+                       break;\r
+               case CFW_CMD_NOP:\r
+                       DBGI("CFW_CMD_NOP");\r
+                       pc += 1;\r
+                       break;\r
+               case CFW_CMD_DELAY:\r
+                       DBGI("CFW_CMD_DELAY");\r
+                       usleep(c->delay.delay * 1000 + c->delay.delay_fine * 4);\r
+                       pc += 1;\r
+                       break;\r
+               case CFW_CMD_UPDTBITS:\r
+                       DBGI("CFW_CMD_UPDTBITS");\r
+                       c[1].reg.data = reg_read(c[1].reg);\r
+                       set_bits(&data, c->bitop.mask, c[1].reg.data);\r
+                       reg_write(c[1].reg);\r
+                       pc += 2;\r
+                       break;\r
+               case CFW_CMD_WAITBITS:\r
+                       DBGI("CFW_CMD_WAITBITS");\r
+                       reg_wait(c[1].reg, c->bitop.mask, c[1].reg.data);\r
+                       pc += 2;\r
+                       break;\r
+               case CFW_CMD_LOCK:\r
+                       DBGI("CFW_CMD_LOCK");\r
+                       cfw_lock(c->lock.lock);\r
+                       pc += 1;\r
+                       break;\r
+               case CFW_CMD_BURST:\r
+                       DBGI("CFW_CMD_BURST");\r
+                       bulk_write(c[1].reg, c->bhdr.len,\r
+                               c[1].burst.data);\r
+                       pc += CFW_CMD_BURST_LEN(c->bhdr.len);\r
+                       break;\r
+               case CFW_CMD_RBURST:\r
+                       DBGI("CFW_CMD_RBURST");\r
+                       bulk_read(c[1].reg, c->bhdr.len,\r
+                               c[1].burst.data);\r
+                       pc += CFW_CMD_BURST_LEN(c->bhdr.len);\r
+                       break;\r
+               case CFW_CMD_LOAD_VAR_IM:\r
+                       set_bits(&var[c->ldst.dvar],\r
+                               c->ldst.mask, c->ldst.svar);\r
+                       pc += 1;\r
+                       break;\r
+               case CFW_CMD_LOAD_VAR_ID:\r
+                       if (c->ldst.svar != c->ldst.dvar) {\r
+                               set_bits(&var[c->ldst.dvar],\r
+                                       c->ldst.mask, var[c->ldst.svar]);\r
+                               pc += 1;\r
+                       }\r
+                       else {\r
+                               data = reg_read(c[1].reg);\r
+                               set_bits(&var[c->ldst.dvar],\r
+                                       c->ldst.mask, data);\r
+                               pc += 2;\r
+                       }\r
+                       break;\r
+               case CFW_CMD_STORE_VAR:\r
+                       if (c->ldst.svar != c->ldst.dvar) {\r
+                               c[1].reg.data = reg_read(c[1].reg);\r
+                               set_bits(&(c[1].reg.data),\r
+                                       var[c->ldst.dvar],\r
+                                       var[c->ldst.svar]);\r
+                               reg_write(c[1].reg);\r
+                       }\r
+                       else {\r
+                               c[1].reg.data = reg_read(c[1].reg);\r
+                               set_bits(&data, c->ldst.mask,\r
+                                       var[c->ldst.svar]);\r
+                               reg_write(c[1].reg);\r
+                       }\r
+                       pc += 2;\r
+                       break;\r
+               case CFW_CMD_COND:\r
+                       cond = var[c->cond.svar] & c->cond.mask;\r
+                       pc += 1;\r
+                       break;\r
+               case CFW_CMD_BRANCH:\r
+                       pc = c->branch.address;\r
+                       break;\r
+               case CFW_CMD_BRANCH_IM:\r
+                       if (c->branch.match == cond)\r
+                               pc = c->branch.address;\r
+                       else\r
+                               pc += 1;\r
+                       break;\r
+               case CFW_CMD_BRANCH_ID:\r
+                       if (var[c->branch.match] == cond)\r
+                               pc = c->branch.address;\r
+                       else\r
+                               pc += 1;\r
+                       break;\r
+               case CFW_CMD_PRINT:\r
+               {\r
+                                                         union cfw_cmd *parglist = c + CFW_CMD_PRINT_ARG(c->print);\r
+#ifdef ANDROID\r
+                                                         DBGI(c->print.fmt,\r
+                                                                 var[parglist->print_arg[0]],\r
+                                                                 var[parglist->print_arg[1]],\r
+                                                                 var[parglist->print_arg[2]],\r
+                                                                 var[parglist->print_arg[3]]);\r
+#else\r
+                                                         printf(c->print.fmt,\r
+                                                                 var[parglist->print_arg[0]],\r
+                                                                 var[parglist->print_arg[1]],\r
+                                                                 var[parglist->print_arg[2]],\r
+                                                                 var[parglist->print_arg[3]]);\r
+#endif\r
+                                                         pc += CFW_CMD_PRINT_LEN(c->print);\r
+               }\r
+                       break;\r
+               case CFW_CMD_OP_START ... CFW_CMD_OP_END:\r
+                       cfw_op(var, c->op);\r
+                       pc += 1;\r
+                       break;\r
+               default:\r
+                       DBGW("Unknown cmd command %x. Skipped", c->cid);\r
+                       pc += 1;\r
+                       break;\r
+               }\r
+       }\r
+\r
+}\r
+\r
+void run_block(struct cfw_block *pb, u8 *var)\r
+{\r
+       char *filePath = "/sdcard/RCCD2/regDump.txt";\r
+       if (!modern || (mode != mode_kernel)) {\r
+               DBGI("Calling run block slow");\r
+               regDumpId = open(filePath, O_RDWR | O_APPEND | O_CREAT, 0644);\r
+               run_block_slow(pb, var);\r
+               close(regDumpId);\r
+               return;\r
+       }\r
+       int r, n = CFW_BLOCK_SIZE(pb->ncmds);\r
+       DBGI("Calling write, ncmds %d, len %d, %x, size of union cfw_cmd %d ", n, CFW_BLOCK_SIZE(pb->ncmds - 1), pb->cmd[0].reg.data, sizeof(union cfw_cmd));\r
+       if ((r = write(dev_fd, pb, n)) != n)\r
+               DBGF("Device write error %d", r);\r
+\r
+}\r
diff --git a/rccd2/include/aic3xxx_cfw.h b/rccd2/include/aic3xxx_cfw.h
new file mode 100755 (executable)
index 0000000..09922d9
--- /dev/null
@@ -0,0 +1,498 @@
+/**
+* \file Codec Firmware Declarations
+*/
+#ifndef CFW_FIRMWARE_H_
+#define CFW_FIRMWARE_H_
+
+/** \defgroup bt Basic Types */
+/* @{ */
+#ifndef AIC3XXX_CFW_HOST_BLD
+#include <asm-generic/int-ll64.h>
+#else
+//typedef unsigned char u8;
+//typedef unsigned short int u16;
+//typedef unsigned long  int u32;
+//typedef unsigned int u32;
+#endif
+//typedef signed char i8;
+//typedef signed short int i16;
+//typedef signed long  int i32;
+
+#define CFW_FW_MAGIC 0xC0D1F1ED
+/** \defgroup pd Arbitrary Limitations */
+/* @{ */
+#ifndef CFW_MAX_ID
+# define CFW_MAX_ID (64) /**<Max length of string identifies*/
+# define CFW_MAX_VARS (256) /**<Number of "variables" alive at the*/
+/**<same time in an acx file*/
+#endif
+/* @} */
+/** \defgroup st Enums, Flags, Macros and Supporting Types */
+/* @{ */
+/**
+* Device Family Identifier
+*
+*/
+enum __attribute__((__packed__)) cfw_dfamily{
+    CFW_DFM_TYPE_A,
+    CFW_DFM_TYPE_B,
+    CFW_DFM_TYPE_C
+};
+/**
+* Device Identifier
+*
+*/
+enum __attribute__((__packed__)) cfw_device{
+    CFW_DEV_DAC3120,
+    CFW_DEV_DAC3100,
+    CFW_DEV_AIC3120,
+    CFW_DEV_AIC3100,
+    CFW_DEV_AIC3110,
+    CFW_DEV_AIC3111,
+    CFW_DEV_AIC36,
+    CFW_DEV_AIC3206,
+    CFW_DEV_AIC3204,
+    CFW_DEV_AIC3254,
+    CFW_DEV_AIC3256,
+    CFW_DEV_AIC3253,
+    CFW_DEV_AIC3212,
+    CFW_DEV_AIC3262,
+    CFW_DEV_AIC3017,
+    CFW_DEV_AIC3008,
+    CFW_DEV_AIC3266,
+    CFW_DEV_AIC3285,
+};
+/**
+* Transition Sequence Identifier
+*
+*/
+enum cfw_transition_t {
+    CFW_TRN_INIT,
+    CFW_TRN_RESUME,
+    CFW_TRN_NEUTRAL,
+    CFW_TRN_A_MUTE,
+    CFW_TRN_D_MUTE,
+    CFW_TRN_AD_MUTE,
+    CFW_TRN_A_UNMUTE,
+    CFW_TRN_D_UNMUTE,
+    CFW_TRN_AD_UNMUTE,
+    CFW_TRN_SUSPEND,
+    CFW_TRN_EXIT,
+    CFW_TRN_N
+};
+#ifndef __cplusplus
+static const char *const cfw_transition_id[] = {
+    [CFW_TRN_INIT] = "INIT",
+    [CFW_TRN_RESUME] = "RESUME",
+    [CFW_TRN_NEUTRAL] = "NEUTRAL",
+    [CFW_TRN_A_MUTE] = "A_MUTE",
+    [CFW_TRN_D_MUTE] = "D_MUTE",
+    [CFW_TRN_AD_MUTE] = "AD_MUTE",
+    [CFW_TRN_A_UNMUTE] = "A_UNMUTE",
+    [CFW_TRN_D_UNMUTE] = "D_UNMUTE",
+    [CFW_TRN_AD_UNMUTE] = "AD_UNMUTE",
+    [CFW_TRN_SUSPEND] = "SUSPEND",
+    [CFW_TRN_EXIT] = "EXIT",
+};
+#endif
+/* @} */
+/** \defgroup ds Data Structures */
+/* @{ */
+/**
+* CFW Command
+* These commands do not appear in the register
+* set of the device.
+*/
+enum __attribute__((__packed__)) cfw_cmd_id{
+    CFW_CMD_NOP = 0x80,
+    CFW_CMD_DELAY,
+    CFW_CMD_UPDTBITS,
+    CFW_CMD_WAITBITS,
+    CFW_CMD_LOCK,
+    CFW_CMD_BURST,
+    CFW_CMD_RBURST,
+    CFW_CMD_LOAD_VAR_IM,
+    CFW_CMD_LOAD_VAR_ID,
+    CFW_CMD_STORE_VAR,
+    CFW_CMD_COND,
+    CFW_CMD_BRANCH,
+    CFW_CMD_BRANCH_IM,
+    CFW_CMD_BRANCH_ID,
+    CFW_CMD_PRINT,
+    CFW_CMD_OP_ADD = 0xC0,
+    CFW_CMD_OP_SUB,
+    CFW_CMD_OP_MUL,
+    CFW_CMD_OP_DIV,
+    CFW_CMD_OP_AND,
+    CFW_CMD_OP_OR,
+    CFW_CMD_OP_SHL,
+    CFW_CMD_OP_SHR,
+    CFW_CMD_OP_RR,
+    CFW_CMD_OP_XOR,
+    CFW_CMD_OP_NOT,
+    CFW_CMD_OP_LNOT,
+};
+/**
+* CFW Delay
+* Used for the cmd command delay
+* Has one parameter of delay time in ms
+*/
+struct cfw_cmd_delay {
+    u16 delay;
+    u8 cid;
+    //enum cfw_cmd_id cid;
+    u8 delay_fine;
+};
+/**
+* CFW Lock
+* Take codec mutex to avoid clashing with DAPM operations
+*/
+struct cfw_cmd_lock {
+    u16 lock;
+    u8 cid;
+    //enum cfw_cmd_id cid;
+    u8 unused;
+};
+/**
+* CFW UPDTBITS, WAITBITS, CHKBITS
+* Both these cmd commands have same arguments
+* cid will be used to specify which command it is
+* has parameters of book, page, offset and mask
+*/
+struct cfw_cmd_bitop {
+    u16 unused1;
+    u8 cid;
+    //enum cfw_cmd_id cid;
+    u8 mask;
+};
+/**
+* CFW CMD Burst header
+* Burst writes inside command array
+* Followed by burst address, first byte
+*/
+struct cfw_cmd_bhdr {
+    u16 len;
+    u8 cid;
+    //enum cfw_cmd_id cid;
+    u8 unused;
+};
+/**
+* CFW CMD Burst
+* Burst writes inside command array
+* Followed by data to the extent indicated in previous len
+* Can be safely cast to cfw_burst
+*/
+struct cfw_cmd_burst {
+//     u8 slave_id;
+    u8 book;
+    u8 page;
+    u8 offset;
+    u8 data[1];
+};
+#define CFW_CMD_BURST_LEN(n) (2 + ((n) - 1 + 3)/4)
+/**
+* CFW CMD Scratch register
+* For load
+* if (svar != dvar)
+* dvar = setbits(svar, mask) // Ignore reg
+* else
+* dvar = setbits(reg, mask)
+* For store
+* if (svar != dvar)
+* reg = setbits(svar, dvar)
+* else
+* reg = setbits(svar, mask)
+*
+*/
+struct cfw_cmd_ldst {
+    u8 dvar;
+    u8 svar;
+    u8 cid;
+    //enum cfw_cmd_id cid;
+    u8 mask;
+};
+/**
+* CFW CMD Conditional
+* May only precede branch. Followed by nmatch+1 jump
+* instructions
+* cond = svar&mask
+* At each of the following nmatch+1 branch command
+* if (cond == match)
+* take the branch
+*/
+struct cfw_cmd_cond {
+    u8 svar;
+    u8 nmatch;
+    u8 cid;
+    //enum cfw_cmd_id cid;
+    u8 mask;
+};
+#define CFW_CMD_COND_LEN(nm) (1 + ((nm)+1))
+/**
+* CFW CMD Goto
+* For branch, break, continue and stop
+*/
+struct cfw_cmd_branch {
+    u16 address;
+    u8 cid;
+    //enum cfw_cmd_id cid;
+    u8 match;
+};
+/**
+* CFW Debug print
+* For diagnostics
+*/
+struct cfw_cmd_print {
+    u8 fmtlen;
+    u8 nargs;
+    u8 cid;
+    //enum cfw_cmd_id cid;
+    char fmt[1];
+};
+#define CFW_CMD_PRINT_LEN(p) (1 + ((p).fmtlen/4) + (((p).nargs + 3)/4))
+#define CFW_CMD_PRINT_ARG(p) (1 + ((p).fmtlen/4))
+/**
+* CFW Arithmetic and logical operations
+* Bit 5 indicates if op1 is indirect
+* Bit 6 indicates if op2 is indirect
+*/
+struct cfw_cmd_op {
+    u8 op1;
+    u8 op2;
+    u8 cid;
+    //enum cfw_cmd_id cid;
+    u8 dst;
+};
+#define CFW_CMD_OP1_ID (1u<<5)
+#define CFW_CMD_OP2_ID (1u<<4)
+#define CFW_CMD_OP_START CFW_CMD_OP_ADD
+#define CFW_CMD_OP_END (CFW_CMD_OP_LNOT|CFW_CMD_OP1_ID|CFW_CMD_OP2_ID)
+#define CFW_CMD_OP_IS_UNARY(x) \
+    (((x) == CFW_CMD_OP_NOT) || ((x) == CFW_CMD_OP_LNOT))
+/**
+* CFW Register
+*
+* A single reg write
+*
+*/
+union cfw_register {
+    struct {
+       //      u8 slave_id;
+        u8 book;
+        u8 page;
+        u8 offset;
+        u8 data;
+    };
+    u32 bpod;
+};
+/**
+* CFW Command
+*
+* Can be a either a
+* -# single register write, or
+* -# command
+*
+*/
+union cfw_cmd {
+    struct {
+        u16 unused1;
+        u8 cid;
+        //enum cfw_cmd_id cid;
+        u8 unused2;
+    };
+    union cfw_register reg;
+    struct cfw_cmd_delay delay;
+    struct cfw_cmd_lock lock;
+    struct cfw_cmd_bitop bitop;
+    struct cfw_cmd_bhdr bhdr;
+    struct cfw_cmd_burst burst;
+    struct cfw_cmd_ldst ldst;
+    struct cfw_cmd_cond cond;
+    struct cfw_cmd_branch branch;
+    struct cfw_cmd_print print;
+    u8 print_arg[4];
+    struct cfw_cmd_op op;
+};
+#define CFW_REG_IS_CMD(x) ((x).cid >= CFW_CMD_DELAY)
+/**
+* CFW Block Type
+*
+* Block identifier
+*
+*/
+enum __attribute__((__packed__)) cfw_block_t{
+    CFW_BLOCK_SYSTEM_PRE,
+    CFW_BLOCK_A_INST,
+    CFW_BLOCK_A_A_COEF,
+    CFW_BLOCK_A_B_COEF,
+    CFW_BLOCK_A_F_COEF,
+    CFW_BLOCK_D_INST,
+    CFW_BLOCK_D_A1_COEF,
+    CFW_BLOCK_D_B1_COEF,
+    CFW_BLOCK_D_A2_COEF,
+    CFW_BLOCK_D_B2_COEF,
+    CFW_BLOCK_D_F_COEF,
+    CFW_BLOCK_SYSTEM_POST,
+    CFW_BLOCK_N,
+    CFW_BLOCK_INVALID,
+};
+#define CFW_BLOCK_D_A_COEF CFW_BLOCK_D_A1_COEF
+#define CFW_BLOCK_D_B_COEF CFW_BLOCK_D_B1_COEF
+
+/**
+ * CFW Register
+ *
+ * A single reg write
+ *
+ */
+union aic_register {
+        struct {
+                u8 book;
+                u8 page;
+                u8 offset;
+                u8 data;
+        };
+        u32 bpod;
+};
+
+/**
+* CFW Block
+*
+* A block of logically grouped sequences/commands/cmd-commands
+*
+*/
+struct cfw_block {
+    u8 type;
+    //enum cfw_block_t type;
+    int ncmds;
+    union cfw_cmd cmd[];
+};
+#define CFW_BLOCK_SIZE(ncmds) (sizeof(struct cfw_block) + \
+    ((ncmds)*sizeof(union cfw_cmd)))
+/**
+* CFW Image
+*
+* A downloadable image
+*/
+struct cfw_image {
+    char name[CFW_MAX_ID]; /**< Name of the pfw/overlay/configuration*/
+    char *desc; /**< User string*/
+    int mute_flags;
+    struct cfw_block *block[CFW_BLOCK_N];
+};
+/**
+* CFW PLL
+*
+* PLL configuration sequence and match critirea
+*/
+struct cfw_pll {
+    char name[CFW_MAX_ID]; /**< Name of the PLL sequence*/
+    char *desc; /**< User string*/
+    struct cfw_block *seq;
+};
+/**
+* CFW Control
+*
+* Run-time control for a process flow
+*/
+struct cfw_control {
+    char name[CFW_MAX_ID]; /**< Control identifier*/
+    char *desc; /**< User string*/
+    int mute_flags;
+    int min; /**< Min value of control (*100)*/
+    int max; /**< Max value of control (*100)*/
+    int step; /**< Control step size (*100)*/
+    int imax; /**< Max index into controls array*/
+    int ireset; /**< Reset control to defaults*/
+    int icur; /**< Last value set*/
+    struct cfw_block **output; /**< Array of sequences to send*/
+};
+/**
+* Process flow
+*
+* Complete description of a process flow
+*/
+struct cfw_pfw {
+    char name[CFW_MAX_ID]; /**< Name of the process flow*/
+    char *desc; /**< User string*/
+    u32 version;
+    u8 prb_a;
+    u8 prb_d;
+    int novly; /**< Number of overlays (1 or more)*/
+    int ncfg; /**< Number of configurations (0 or more)*/
+    int nctrl; /**< Number of run-time controls*/
+    struct cfw_image *base; /**< Base sequence*/
+    struct cfw_image **ovly_cfg; /**< Overlay and cfg*/
+    /**< patches (if any)*/
+    struct cfw_control **ctrl; /**< Array of run-time controls*/
+};
+#define CFW_OCFG_NDX(p, o, c) (((o)*(p)->ncfg)+(c))
+/**
+* Process transition
+*
+* Sequence for specific state transisitions within the driver
+*
+*/
+struct cfw_transition {
+    char name[CFW_MAX_ID]; /**< Name of the transition*/
+    char *desc; /**< User string*/
+    struct cfw_block *block;
+};
+/**
+* Device audio mode
+*
+* Link operating modes to process flows,
+* configurations and sequences
+*
+*/
+struct cfw_mode {
+    char name[CFW_MAX_ID];
+    char *desc; /**< User string*/
+    u32 flags;
+    u8 pfw;
+    u8 ovly;
+    u8 cfg;
+    u8 pll;
+    struct cfw_block *entry;
+    struct cfw_block *exit;
+};
+struct cfw_asoc_toc_entry {
+    char etext[CFW_MAX_ID];
+    int mode;
+    int cfg;
+};
+struct cfw_asoc_toc {
+    int nentries;
+    struct cfw_asoc_toc_entry entry[];
+};
+/**
+* CFW Project
+*
+* Top level structure describing the CFW project
+*/
+struct cfw_project {
+    u32 magic; /**< magic number for identifying F/W file*/
+    u32 if_id; /**< Interface match code */
+    u32 size; /**< Total size of the firmware (including this header)*/
+    u32 cksum; /**< CRC32 of the pickled firmware */
+    u32 version; /**< Firmware version (from CFD file)*/
+    u32 tstamp; /**< Time stamp of firmware build (epoch seconds)*/
+    char name[CFW_MAX_ID]; /**< Project name*/
+    char *desc; /**< User string*/
+    enum cfw_dfamily dfamily; /**< Device family*/
+    enum cfw_device device; /**< Device identifier*/
+    u32 flags; /**< CFW flags*/
+    struct cfw_transition **transition; /**< Transition sequences*/
+    u16 npll; /**< Number of PLL settings*/
+    struct cfw_pll **pll; /**< PLL settings*/
+    u16 npfw; /**< Number of process flows*/
+    struct cfw_pfw **pfw; /**< Process flows*/
+    u16 nmode; /**< Number of operating modes*/
+    struct cfw_mode **mode; /**< Modes*/
+    struct cfw_asoc_toc *asoc_toc; /**< list of amixer controls*/
+};
+void run_block(struct cfw_block *pb, u8 *var);
+/* @} */
+/* **CFW_INTERFACE_ID=0x3FA6D547** */
+#endif /* CFW_FIRMWARE_H_ */
+
diff --git a/rccd2/include/android_utils.h b/rccd2/include/android_utils.h
new file mode 100755 (executable)
index 0000000..2ab1e18
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef ANDROID_UTILS_H_
+#define ANDROID_UTILS_H_
+
+#include "host_compile.h"
+
+#ifdef ANDROID
+#include <android/log.h>
+#include <cutils/log.h>
+#else
+
+typedef enum android_LogPriority {
+    ANDROID_LOG_UNKNOWN = 0,
+    ANDROID_LOG_DEFAULT,    /* only for SetMinPriority() */
+    ANDROID_LOG_VERBOSE,
+    ANDROID_LOG_DEBUG,
+    ANDROID_LOG_INFO,
+    ANDROID_LOG_WARN,
+    ANDROID_LOG_ERROR,
+    ANDROID_LOG_FATAL,
+    ANDROID_LOG_SILENT,     /* only for SetMinPriority(); must be last */
+} android_LogPriority;
+
+#endif
+
+/* TAS MACROS */
+#define TAS2560_REG(book,page,reg)     (((unsigned int)book * 256 *128) + ((unsigned int)page * 128) + reg)
+#define TAS2560_BOOK_ID(reg)           ((unsigned char)(reg / (256*128)))
+#define TAS2560_PAGE_ID(reg)           ((unsigned char)((reg % (256 * 128)) / 128))
+#define TAS2560_REG_ID(reg)                    ((unsigned char)((reg % (256 * 128)) % 128))
+
+int open_device(char *device);
+void diag(int lvl, char *fmt, ...);
+extern int dump_cmds;
+enum { mode_undef, mode_user, mode_kernel };
+extern int mode;
+
+#ifndef PROGRAM
+#   define PROGRAM "aic3xxx"
+#endif
+
+
+#undef DBG
+#undef DBGF
+
+#define DBGD(fmt, ...)  do { \
+                            if (dump_cmds) \
+                                LOG(ANDROID_LOG_DEBUG, fmt, ##__VA_ARGS__); \
+                        } while (0)
+#define DBG(fmt, ...)   LOG(ANDROID_LOG_DEBUG, "[%s:%d] " fmt, __FILE__, \
+                                            __LINE__, ##__VA_ARGS__)
+#define DBGI(fmt, ...)  LOG(ANDROID_LOG_INFO, fmt, ##__VA_ARGS__)
+#define DBGW(fmt, ...)  LOG(ANDROID_LOG_WARN, fmt, ##__VA_ARGS__)
+#define DBGF(fmt, ...)  LOG(ANDROID_LOG_FATAL, fmt, ##__VA_ARGS__)
+#define LOG(lvl, fmt, ...) diag(lvl, fmt, ##__VA_ARGS__)
+#endif
diff --git a/rccd2/include/host_compile.h b/rccd2/include/host_compile.h
new file mode 100755 (executable)
index 0000000..794a8c3
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef HOST_COMPILE_H_
+#define HOST_COMPILE_H_
+
+#define printk warn
+#define MODULE_DESCRIPTION(x) 
+#define MODULE_LICENSE(x) 
+#define MODULE_AUTHOR(x) 
+
+//#include <asm-generic/int-ll64.h>
+typedef unsigned char u8;
+typedef unsigned short int u16;
+//typedef unsigned long int u32;
+typedef unsigned int u32;
+typedef signed char i8;
+typedef signed short int i16;
+typedef signed long int i32;
+//#define crc32  aic_crc32
+struct aic_firmware *aic_unpickle(void *pcfw, int n);
+unsigned int crc32_local(unsigned int *pdata, int n);
+#if 0
+static inline unsigned int crc32(unsigned int seed, unsigned int *pdata, int n)
+{
+    return  crc32_local(pdata, n);
+}
+#endif
+#   define _GNU_SOURCE
+#   include <stdlib.h>
+#   include "utils.h"
+#   include <string.h>
+#   include <assert.h>
+#ifndef EINVAL
+#   define EINVAL 1
+#endif
+
+// Hack, Hack
+#ifndef AIC3XX_COPS_MDSP_D
+#define AIC3XX_COPS_MDSP_D  (0x00000003u)
+#define AIC3XX_COPS_MDSP_A  (0x00000030u)
+#endif
+
+#endif
diff --git a/rccd2/include/rccd2.h b/rccd2/include/rccd2.h
new file mode 100755 (executable)
index 0000000..f26aa71
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef RCCD2_H_
+#define RCCD2_H_
+
+#define FW_ID_ADDRESS   0x1FBC
+
+#define TARGET_I2C          5
+#define RCCD_MAGIC          "TICC"
+#define RCCD_PING           "PING"
+#define DEFAULT_FWID        "FWIDTLV320AIC3262EVM-U"    
+#define RCCD_MAX_PACKET     (32*1024)
+#define RCCD_MAX_STREAMS    (8)
+
+enum __attribute__ ((__packed__)) rccd_cmd_id {
+    RCCD_CMD_WRITE      = 0x02,
+    RCCD_CMD_READ       = 0x03,
+    RCCD_CMD_FWID       = 0x05,
+    RCCD_CMD_SLAVE      = 0x06,
+
+    RCCD_CMD_BLOCK      = 0x80,
+    RCCD_CMD_OPEN,
+    RCCD_CMD_CLOSE,
+    RCCD_CMD_PLAY,
+    RCCD_CMD_CAPTURE,
+    RCCD_CMD_START,
+    RCCD_CMD_STOP,
+    RCCD_CMD_MGET,
+    RCCD_CMD_MSET,
+    RCCD_CMD_NCTLS,
+    RCCD_CMD_CTL
+};
+
+struct rccd_cmd {
+    u8 len;
+    enum rccd_cmd_id cid;
+    u8 options;
+    u8 data[];
+};
+struct rccd_cmd_alsa {
+    u8 len;
+    enum rccd_cmd_id cid;
+    u8 stream;
+    u8 device;
+    unsigned int flags;
+    unsigned int buffer_size;
+    unsigned int channels;
+    unsigned int rate;
+    unsigned int period_size;
+    unsigned int period_count;
+    unsigned int format;
+    u8 data[];
+};
+
+struct rccd_request {
+    u8 magic[4];
+    u8 len;
+    u8 app;
+    u8 target;
+    u8 result;
+    struct rccd_cmd cmd[];
+};
+
+#endif
diff --git a/rccd2/include/utils.h b/rccd2/include/utils.h
new file mode 100755 (executable)
index 0000000..486d77b
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef UTILS_H_
+#define UTILS_H_
+
+#include <stdio.h>
+#include <getopt.h>
+
+#include "host_compile.h"
+
+extern int verbose;
+void error(char *fmt, ...);
+void warn(char *fmt, ...);
+void dbg(const char *f, int ln, char *fmt, ...);
+
+#define warn_once(f, ...) do {                              \
+                                static int prn_out__ = 0;   \
+                                if (!prn_out__)  {          \
+                                    warn(f, ##__VA_ARGS__); \
+                                    prn_out__ = 1;          \
+                                }                           \
+                            } while (0)
+
+    
+#define DBG(f, ...) dbg(__FILE__, __LINE__, f, ##__VA_ARGS__)
+#define DBGF(f, ...) dbg(__FUNCTION__, __LINE__, f, ##__VA_ARGS__)
+
+#define ARRAY_LEN(x) ((int)(sizeof(x)/sizeof((x)[0])))
+#define MAX2(x, y)(((x)>(y))?(x):(y))
+#define MIN2(x, y)(((x)<(y))?(x):(y))
+
+
+#ifdef WIN32
+char *strcasestr(const char *haystack, const char *needle);
+#endif
+
+#define ALLOC(x) safe_alloc(__FUNCTION__, __FILE__, __LINE__, x)
+#define REALLOC(x, n) do { \
+        (x) = realloc((x), n); \
+        if (!(x)) { \
+            error("out of memory: request for %d bytes in %s() [%s:%d]", \
+                n, __FUNCTION__, __FILE__, __LINE__); \
+        } \
+    } while (0)
+
+void *safe_alloc(const char *fn, const char *file,  int ln, int n);
+void safe_snprintf(char *str, size_t size, const char *format, ...);
+
+int flt2fix(char *s);
+void *slurp(const char *f, int *np);
+
+char *make_opts(const struct option *opts);
+char *change_extn(const char *fname, char *ext);
+char *get_extn(const char *fname);
+double clkspec(const char *mclk);
+
+void add_path(char *path);
+FILE *loc_and_open(char *file);
+int file_exists(const char *path);
+
+int split(const char *s, char ***flds);
+void free_flds(char **flds, int n);
+
+
+#ifndef __ARMEL__
+// No regexp library installed for Linux/Android
+//int grok_reg_spec(const char *exp, union aic_register *r);
+#endif
+
+#endif
diff --git a/rccd2/rccd2.bat b/rccd2/rccd2.bat
new file mode 100755 (executable)
index 0000000..d87a3dc
--- /dev/null
@@ -0,0 +1,141 @@
+@ECHO OFF
+:: Default options
+set ADB=adb.exe
+set RCCD2=rccd2
+set PORT=80
+set SAFE=
+set CARD=0
+set LOGCAT=OFF
+set DEBUG=OFF
+
+goto GETOPTS
+
+:USAGE
+echo.
+echo.   rccd2.bat  -- Start RCCD server on target Android phone
+echo.
+echo.   Usage: rccd2 [/help] [/safe] [/supersafe] [/card:N] [/port:N] 
+echo.                     [/adb:ADB] [/rccd2:RCCD2] [/logcat]
+echo.
+echo.   Options:
+echo.
+echo.       /help           Display this help text and exit
+echo.       /port:N         Set port number to N (Default: %PORT%)
+echo.       /card:N         Select sound card N (Default: %CARD%)
+echo.       /adb:ADB        Use ADB as the adb executable
+echo.                       (Default: %ADB%)
+echo.       /rccd2:RCCD2    Use RCCD2 as the target rccd2 executable
+echo.                       (Default: %RCCD2%)
+echo.       /logcat         Start adb logcat at the end
+echo.       /debug          Output debug information
+echo.
+goto END
+
+
+:GETOPTS
+    set SWITCHOPT=%1
+    if [%SWITCHOPT%] == [] goto START
+
+    for /F "tokens=1,2 delims=: " %%a IN ("%SWITCHOPT%") DO SET SWITCH=%%a&set VALUE=%%b
+   
+    shift
+
+    if [%SWITCH%] == [/h] goto USAGE
+    if [%SWITCH%] == [/H] goto USAGE
+    if [%SWITCH%] == [/?] goto USAGE
+    if [%SWITCH%] == [/help] goto USAGE
+    if [%SWITCH%] == [/HELP] goto USAGE
+
+    if [%SWITCH%] == [/safe] goto SET_SAFE_ON
+    if [%SWITCH%] == [/SAFE] goto SET_SAFE_ON
+    if [%SWITCH%] == [/supersafe] goto SET_SSAFE_ON
+    if [%SWITCH%] == [/SUPERSAFE] goto SET_SSAFE_ON
+
+    if [%SWITCH%] == [/card] goto SET_CARD
+    if [%SWITCH%] == [/CARD] goto SET_CARD
+
+    if [%SWITCH%] == [/port] goto SET_PORT
+    if [%SWITCH%] == [/PORT] goto SET_PORT
+
+    if [%SWITCH%] == [/adb] goto SET_ADB
+    if [%SWITCH%] == [/ADB] goto SET_ADB
+
+    if [%SWITCH%] == [/rccd2] goto SET_RCCD2
+    if [%SWITCH%] == [/RCCD2] goto SET_RCCD2
+
+    if [%SWITCH%] == [/logcat] goto SET_LOGCAT_ON
+    if [%SWITCH%] == [/LOGCAT] goto SET_LOGCAT_ON
+
+    if [%SWITCH%] == [/debug] goto SET_DEBUG_ON
+    if [%SWITCH%] == [/DEBUG] goto SET_DEBUG_ON
+
+
+    echo. Unknown option %SWITCH%. Ignored
+goto GETOPTS
+
+
+:SET_SAFE_ON
+    set SAFE=-s
+goto GETOPTS
+
+:SET_SSAFE_ON
+    set SAFE=-S
+goto GETOPTS
+
+:SET_PORT
+    set PORT=%VALUE%
+goto GETOPTS
+
+:SET_CARD
+    set CARD=%VALUE%
+goto GETOPTS
+
+:SET_ADB
+    set ADB=%VALUE%
+goto GETOPTS
+
+:SET_RCCD2
+    set RCCD2=%VALUE%
+goto GETOPTS
+
+:SET_LOGCAT_ON
+    set LOGCAT=ON
+goto GETOPTS
+
+
+:SET_DEBUG_ON
+    REM echo ON
+    set DEBUG=ON
+goto GETOPTS
+
+:START
+
+if [%DEBUG%] == [OFF] goto RUN
+    echo. "Starting RCCD..."
+    echo. SAFE=%SAFE%
+    echo. PORT=%PORT%
+    echo. CARD=%CARD%
+    echo. ADB=%ADB%
+    echo. RCCD2=%RCCD2%
+    echo. LOGCAT=%LOGCAT%
+
+:RUN
+
+%ADB% root
+%ADB% remount
+%ADB% shell svc power stayon true
+ping localhost > NUL
+%ADB% push %RCCD2% /system/bin/rccd2
+%ADB% shell chmod 0777 /system/bin/rccd2
+%ADB% forward tcp:%PORT% tcp:%PORT%
+%ADB% shell /system/bin/rccd2 -k
+%ADB% shell /system/bin/rccd2 -p %PORT% -r %CARD% %SAFE%
+
+if [%DEBUG%] == [ON] echo "RCCD2 is running..."
+
+if [%LOGCAT%] == [OFF] goto END
+    %ADB% logcat -s aic3xxx
+
+:END
+
+
diff --git a/rccd2/rccd2.c b/rccd2/rccd2.c
new file mode 100755 (executable)
index 0000000..eb0e3b6
--- /dev/null
@@ -0,0 +1,654 @@
+#include <stdio.h>\r
+#include <stddef.h>\r
+#include <string.h>\r
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
+#include <sys/wait.h>\r
+#include <dirent.h>\r
+#include <pthread.h>\r
+#include <sys/socket.h>\r
+#include <sys/ioctl.h>\r
+#include <arpa/inet.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <unistd.h>\r
+#include <signal.h>\r
+#include <netinet/in.h>\r
+#include <fcntl.h>\r
+#include <time.h>\r
+#include <getopt.h>\r
+#include "utils.h"\r
+#include "android_utils.h"\r
+#include "rccd2.h"\r
+#include "aic3xxx_cfw.h"\r
+\r
+/* Max connection requests */\r
+#define MAXPENDING      (16)\r
+#define BUFFSIZE        (256)\r
+#define DEFAULT_PORT    (80)\r
+\r
+/* State of each independent connection */\r
+struct rccd_hdl {\r
+       u32 pcounter;\r
+       char fwid[32];\r
+       int clientsock;\r
+       int fCtrl;\r
+       pthread_mutex_t *mutex;\r
+       int slave_id,book, page;\r
+       u8 buffer[RCCD_MAX_PACKET];\r
+       struct cfw_block block;\r
+};\r
+\r
+#define CRITICAL(code_section__) do {           \\r
+if (pthread_mutex_lock(pc->mutex))          \\r
+       DBGF("Error obtaining mutex lock");     \\r
+       \\r
+       code_section__;                             \\r
+       \\r
+if (pthread_mutex_unlock(pc->mutex))        \\r
+       DBGF("Error releasing mutex lock");     \\r
+} while (0)\r
+\r
+void legacy_read(struct rccd_hdl *pc, u8 *buf, int n)\r
+{\r
+       pc->block.ncmds = CFW_CMD_BURST_LEN(n);\r
+       pc->block.cmd[0].bhdr.cid = CFW_CMD_RBURST;\r
+       pc->block.cmd[0].bhdr.len = n;\r
+       //pc->block.cmd[1].burst.slave_id = pc->slave_id;\r
+       pc->block.cmd[1].burst.book = pc->book;\r
+       pc->block.cmd[1].burst.page = pc->page;\r
+       pc->block.cmd[1].burst.offset = buf[0];\r
+       DBG("legacy_read: (%d,%d,%d) %d bytes", pc->book, pc->page, buf[0], n);\r
+       CRITICAL(run_block(&(pc->block), NULL));\r
+       memcpy(buf + 1, pc->block.cmd[1].burst.data, n);\r
+}\r
+\r
+void legacy_write(struct rccd_hdl *pc, u8 *buf, int n)\r
+{\r
+       u8 *pd = buf;\r
+       if (buf[0] == 127) {\r
+               pc->book = buf[1];\r
+               if (n != 2)\r
+                       DBGW("Received book change as part of burst command.  "\r
+                       "Additional writes have been ignored (n=%d)", n);\r
+               return;\r
+       }\r
+       if (buf[0] == 0) {\r
+               pc->page = buf[1];\r
+               --n;\r
+               if (n <= 1)\r
+                       return;\r
+               ++pd;\r
+               pd[0] = 1;\r
+       }\r
+       pc->block.ncmds = CFW_CMD_BURST_LEN(n - 1);\r
+       pc->block.cmd[0].bhdr.cid = CFW_CMD_BURST;\r
+       pc->block.cmd[0].bhdr.len = n - 1;\r
+       //pc->block.cmd[1].burst.slave_id = pc->slave_id;\r
+       pc->block.cmd[1].burst.book = pc->book;\r
+       pc->block.cmd[1].burst.page = pc->page;\r
+       pc->block.cmd[1].burst.offset = pd[0];\r
+       memcpy(pc->block.cmd[1].burst.data, &pd[1], n - 1);\r
+       DBG("legacy_write: (%d,%d,%d) %d bytes", pc->book, pc->page, pd[0], n - 1);\r
+       CRITICAL(run_block(&(pc->block), NULL));\r
+}\r
+\r
+int rccd_cmd(struct rccd_hdl *pc, struct rccd_cmd *cmd, int len)\r
+{\r
+       DBG("Getting into rccd_cmd");\r
+       const char * const cid_str[] = {\r
+               [RCCD_CMD_READ] = "RCCD_CMD_READ",\r
+               [RCCD_CMD_WRITE] = "RCCD_CMD_WRITE",\r
+               [RCCD_CMD_SLAVE] = "RCCD_CMD_SLAVE",\r
+               [RCCD_CMD_FWID] = "RCCD_CMD_FWID",\r
+               [RCCD_CMD_BLOCK] = "RCCD_CMD_BLOCK",\r
+               [RCCD_CMD_OPEN] = "RCCD_CMD_OPEN",\r
+               [RCCD_CMD_CLOSE] = "RCCD_CMD_CLOSE",\r
+               [RCCD_CMD_PLAY] = "RCCD_CMD_PLAY",\r
+               [RCCD_CMD_CAPTURE] = "RCCD_CMD_CAPTURE",\r
+               [RCCD_CMD_START] = "RCCD_CMD_START",\r
+               [RCCD_CMD_STOP] = "RCCD_CMD_STOP",\r
+               [RCCD_CMD_MGET] = "RCCD_CMD_MGET",\r
+               [RCCD_CMD_MSET] = "RCCD_CMD_MSET",\r
+               [RCCD_CMD_NCTLS] = "RCCD_CMD_NCTLS",\r
+               [RCCD_CMD_CTL] = "RCCD_CMD_CTL",\r
+       };\r
+\r
+       DBG("%s: cid=%0x \"%s\"  len=%d", __FUNCTION__, cmd->cid, cid_str[cmd->cid],\r
+               cmd->len);\r
+\r
+       //if (!pc->mixer && cmd->cid > RCCD_CMD_BLOCK)\r
+       //      DBGF("Attempt to do ALSA operation when no sound card is present");\r
+\r
+       switch (cmd->cid) {\r
+       case RCCD_CMD_READ:\r
+               DBG("rccd:RCCD_CMD_READ");\r
+               if (cmd->len < 4)\r
+                       break;\r
+               legacy_read(pc, cmd->data, cmd->len - 4);\r
+               break;\r
+       case RCCD_CMD_WRITE:\r
+               DBG("rccd:RCCD_CMD_WRITE");\r
+               if (cmd->len < 4)\r
+                       break;\r
+               legacy_write(pc, cmd->data, cmd->len - 4 + 1);\r
+               break;\r
+       case RCCD_CMD_BLOCK:\r
+       {\r
+               DBG("rccd:RCCD_CMD_BLOCK");\r
+               u8 var[256];\r
+               struct cfw_block *b = (void *)cmd->data;\r
+               len = CFW_BLOCK_SIZE(b->ncmds) + sizeof(struct rccd_cmd);\r
+               CRITICAL(run_block(b, var));\r
+       }\r
+               break;\r
+       case RCCD_CMD_OPEN:\r
+               DBG("rccd:RCCD_CMD_OPEN - : NOT SUPPORTED");\r
+               break;\r
+       case RCCD_CMD_CLOSE:\r
+               DBG("rccd:RCCD_CMD_CLOSE - : NOT SUPPORTED");\r
+               break;\r
+       case RCCD_CMD_PLAY:\r
+               DBG("rccd:RCCD_CMD_PLAY - : NOT SUPPORTED");\r
+               break;\r
+\r
+       case RCCD_CMD_CAPTURE:\r
+               DBG("rccd:RCCD_CMD_CAPTURE - : NOT SUPPORTED");\r
+               break;\r
+\r
+       case RCCD_CMD_START:\r
+               DBG("rccd:RCCD_CMD_START - : NOT SUPPORTED");\r
+               break;\r
+\r
+       case RCCD_CMD_STOP:\r
+               DBG("rccd:RCCD_CMD_STOP - : NOT SUPPORTED");\r
+               break;\r
+       case RCCD_CMD_MGET:\r
+               DBG("rccd:RCCD_CMD_MGET - : NOT SUPPORTED");\r
+               break;\r
+\r
+       case RCCD_CMD_MSET:\r
+               DBG("rccd:RCCD_CMD_MSET - : NOT SUPPORTED");\r
+               break;\r
+\r
+       case RCCD_CMD_NCTLS:\r
+               DBG("rccd:RCCD_CMD_NCTLS - : NOT SUPPORTED");\r
+               break;\r
+\r
+       case RCCD_CMD_CTL:\r
+               DBG("rccd:RCCD_CMD_CTL - : NOT SUPPORTED");\r
+               break;\r
+\r
+       case RCCD_CMD_FWID:\r
+       {\r
+               DBG("rccd:RCCD_CMD_FWID");\r
+               //u32 addr = (cmd->data[1] << 8) | (cmd->data[2]);\r
+               strcpy((char *)(cmd->data + 3), pc->fwid);\r
+       }\r
+               break;\r
+       case RCCD_CMD_SLAVE:\r
+       {\r
+               u8 slave = cmd->data[0];\r
+               int client = slave;\r
+               ioctl(pc->fCtrl, _IOW(0xE0, 5, int), &client);\r
+               DBG("Setting slave : 0x%x", slave);\r
+       }\r
+               break;\r
+       default:\r
+               DBGW("HandleI2CCmd: unsupported command: %d",\r
+                       cmd->cid);\r
+       }\r
+       DBG("Getting out of rccd_cmd");\r
+       return len;\r
+}\r
+\r
+void dump_pkt(u8 *b, int nLength)\r
+{\r
+       int i;\r
+       DBG("Packet[length=%d]", nLength);\r
+       for (i = 0; i < nLength; i += 8) {\r
+               switch (nLength - i) {\r
+               case 1: DBG(" 0x%02x", b[i + 0]); break;\r
+               case 2: DBG(" 0x%02x 0x%02x", b[i + 0], b[i + 1]); break;\r
+               case 3: DBG(" 0x%02x 0x%02x 0x%02x", b[i + 0], b[i + 1], b[i + 2]); break;\r
+               case 4: DBG(" 0x%02x 0x%02x 0x%02x 0x%02x", b[i + 0], b[i + 1], b[i + 2], b[i + 3]); break;\r
+               case 5: DBG(" 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", b[i + 0], b[i + 1], b[i + 2], b[i + 3], b[i + 4]); break;\r
+               case 6: DBG(" 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", b[i + 0], b[i + 1], b[i + 2], b[i + 3], b[i + 4], b[i + 5]); break;\r
+               case 7: DBG(" 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", b[i + 0], b[i + 1], b[i + 2], b[i + 3], b[i + 4], b[i + 5], b[i + 6]); break;\r
+               default:DBG(" 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", b[i + 0], b[i + 1], b[i + 2], b[i + 3], b[i + 4], b[i + 5], b[i + 6], b[i + 7]); break;\r
+               }\r
+       }\r
+}\r
+\r
+void write_pkt(u8 *b, int nLength, char *filePath)\r
+{\r
+       int i;\r
+       int output_fd, ret_out;\r
+       char buffer[512];\r
+\r
+       output_fd = open(filePath, O_RDWR | O_APPEND | O_CREAT, 0644);\r
+\r
+       sprintf(buffer, "Packet[length=%d]%c", nLength,'\0');\r
+       ret_out = write(output_fd, &buffer, strlen(buffer));\r
+       for (i = 0; i < nLength; i += 8) {\r
+               switch (nLength - i) {\r
+               case 1: sprintf(buffer, " 0x%02x%c", b[i + 0],'\0'); break;\r
+               case 2: sprintf(buffer, " 0x%02x 0x%02x%c", b[i + 0], b[i + 1],'\0'); break;\r
+               case 3: sprintf(buffer, " 0x%02x 0x%02x 0x%02x%c", b[i + 0], b[i + 1], b[i + 2],'\0'); break;\r
+               case 4: sprintf(buffer, " 0x%02x 0x%02x 0x%02x 0x%02x%c", b[i + 0], b[i + 1], b[i + 2], b[i + 3],'\0'); break;\r
+               case 5: sprintf(buffer, " 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x%c", b[i + 0], b[i + 1], b[i + 2], b[i + 3], b[i + 4],'\0'); break;\r
+               case 6: sprintf(buffer, " 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x%c", b[i + 0], b[i + 1], b[i + 2], b[i + 3], b[i + 4], b[i + 5], '\0'); break;\r
+               case 7: sprintf(buffer, " 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x%c", b[i + 0], b[i + 1], b[i + 2], b[i + 3], b[i + 4], b[i + 5], b[i + 6], '\0'); break;\r
+               default:sprintf(buffer, " 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x%c", b[i + 0], b[i + 1], b[i + 2], b[i + 3], b[i + 4], b[i + 5], b[i + 6], b[i + 7], '\0'); break;\r
+               }\r
+               ret_out = write(output_fd, &buffer, strlen(buffer));\r
+       }\r
+       sprintf(buffer, "\n%c",'\0');\r
+       ret_out = write(output_fd, &buffer, strlen(buffer));\r
+       close(output_fd);\r
+}\r
+\r
+static int get_packet(struct rccd_hdl *pc, u8 *p, int max, int *is_ping)\r
+{\r
+       int ret;\r
+       int sock = pc->clientsock;\r
+       if ((ret = recv(sock, p, max, 0)) <= 0)\r
+               goto err;\r
+       struct rccd_request *preq = (void *)p;\r
+       ++pc->pcounter;\r
+       DBG("[%8d] Received PKT %d bytes", pc->pcounter, ret);\r
+       dump_pkt(p, ret);\r
+       write_pkt(p, ret, "/sdcard/RCCD2/bytes.txt");\r
+       if (preq->target != TARGET_I2C)\r
+               DBGF("Unsupported Target ID: %d\n", preq->target);\r
+       if (preq->len < 8) {\r
+               DBGW("Packet too short");\r
+               goto err;\r
+       }\r
+\r
+       DBG("MAGIC %s", preq->magic);\r
+       if (!memcmp(preq->magic, RCCD_PING, sizeof(preq->magic)))\r
+       {\r
+               DBG("PING... ");\r
+               *is_ping = 1;\r
+               return ret;\r
+       }\r
+\r
+       if (memcmp(preq->magic, RCCD_MAGIC, sizeof(preq->magic))) {\r
+               DBGW("Incorrect signature: %c%c%c%c", preq->magic[0],\r
+                       preq->magic[1], preq->magic[2], preq->magic[3]);\r
+               goto err;\r
+       }\r
+       if (!(preq->cmd[0].cid&RCCD_CMD_BLOCK) &&\r
+               (ret != (int)(preq->len + strlen(RCCD_MAGIC)))) {\r
+               DBGW("Incorrect total length: %d,%d for cid=%02x", preq->len, ret, preq->cmd[0].cid);\r
+               goto err;\r
+       }\r
+\r
+       if (preq->cmd[0].cid < RCCD_CMD_BLOCK)\r
+               return ret;\r
+\r
+       int sz = sizeof(struct rccd_request);\r
+       DBG("[%d] rccd_request size = %d\n", pc->pcounter,sz);\r
+       struct rccd_cmd_alsa *a = (void *)(preq->cmd);\r
+       struct cfw_block *b = (void *)(preq->cmd[0].data);\r
+       switch (preq->cmd[0].cid) {\r
+       case RCCD_CMD_BLOCK:\r
+               sz += sizeof(struct rccd_cmd) + CFW_BLOCK_SIZE(b->ncmds);\r
+               DBG("[%d] cid = RCCD_CMD_BLOCK size = %d\n", pc->pcounter,sz);\r
+               break;\r
+       case RCCD_CMD_OPEN:\r
+       case RCCD_CMD_CLOSE:\r
+       case RCCD_CMD_START:\r
+       case RCCD_CMD_STOP:\r
+       case RCCD_CMD_CAPTURE:\r
+               sz += sizeof(struct rccd_cmd_alsa);\r
+               DBG("[%d] cid = RCCD_CMD_CAPTURE size = %d\n", pc->pcounter,sz);\r
+               break;\r
+       case RCCD_CMD_PLAY:\r
+               sz += sizeof(struct rccd_cmd_alsa) + a->buffer_size;\r
+               DBG("[%d] cid = RCCD_CMD_PLAY size = %d\n", pc->pcounter,sz);\r
+               break;\r
+       case RCCD_CMD_MGET:\r
+       case RCCD_CMD_MSET:\r
+       case RCCD_CMD_NCTLS:\r
+       case RCCD_CMD_CTL:\r
+               sz += sizeof(struct rccd_cmd_alsa) + 256 * 2;\r
+               DBG("[%d] cid = RCCD_CMD_MGET size = %d\n", pc->pcounter,sz);\r
+               break;\r
+       default:\r
+               DBGW("Unknown command cid=%02x", preq->cmd[0].cid);\r
+               goto err;\r
+       }\r
+       if (sz > max)\r
+               goto err;\r
+       p += ret;\r
+       DBG("[%d] Got %d out of %d bytes", pc->pcounter, ret, sz);\r
+       \r
+#if 0  \r
+       while (ret < sz) {\r
+               DBG("\t%d bytes left", sz - ret);\r
+               int rsz;\r
+               if ((rsz = recv(sock, p, sz - ret, 0)) <= 0)\r
+                       goto err;\r
+               ret += rsz;\r
+       }\r
+#endif \r
+       return ret;\r
+err:\r
+       if (ret < 0)\r
+               return ret;\r
+       return 0;\r
+}\r
+\r
+void *handle_client(void *p)\r
+{\r
+       struct rccd_hdl *pc = p;\r
+       int sock = pc->clientsock;\r
+       u8 *buffer = pc->buffer;\r
+       int n;\r
+\r
+       DBGI("Client thread started");\r
+       int is_ping = 0;\r
+\r
+       /* Receive message */\r
+       while ((n = get_packet(pc, buffer, RCCD_MAX_PACKET, &is_ping)) > 0)\r
+       {\r
+\r
+               struct rccd_request *preq = (void *)buffer;\r
+               int off = offsetof(struct rccd_request, cmd);\r
+               if (is_ping == 0){\r
+                       DBGI("Processing Packet");\r
+\r
+                       int c = rccd_cmd(pc, (struct rccd_cmd *)(buffer + off), n - off);\r
+                       send(sock, buffer, off + c, 0);\r
+               }\r
+               else\r
+               {\r
+                       DBGI("Pinging ..");\r
+                       int len = sizeof(preq->magic);\r
+                       struct rccd_cmd *cmd = (struct rccd_cmd *)(buffer + off);\r
+                       memcpy(&(cmd->data[1]), preq->magic, len);\r
+                       send(sock, buffer, off + len, 0);\r
+               }\r
+               is_ping = 0;\r
+       }\r
+       close(sock);\r
+\r
+       DBGI("Client disconnected");\r
+       \r
+       free(pc);\r
+       return NULL;\r
+}\r
+\r
+void sig_exit(int sig)\r
+{\r
+       DBGW("SIGTERM received. Exiting.0x%x",sig);\r
+       exit(0);\r
+}\r
+\r
+void daemonize(char *const argv[])\r
+{\r
+       int i, err, pid;\r
+       DBGI("%s", argv[0]);\r
+       if (getppid() == 1) {\r
+               DBGI("RCCD2 running in background (PID %d)", getpid());\r
+               /* already a daemon */\r
+               return;\r
+       }\r
+       for (;;) {\r
+               if ((pid = fork()) < 0)\r
+                       DBGF("Fork error");\r
+               if (pid <= 0)\r
+                       break;\r
+               // Parent\r
+               sleep(1);\r
+               if ((err = waitpid(pid, NULL, WNOHANG)) == 0) {\r
+                       DBGW("Parent: Fork successful.  Exiting");\r
+                       exit(0);\r
+               }\r
+               if (err < 0) {\r
+                       DBGF("Unknown error");\r
+               }\r
+\r
+               DBGW("Android killed my baby! Baby's ID = %d",pid);\r
+       }\r
+       if (setsid() < 0)\r
+               error("Unable to daemonize");\r
+       DBGI("Child running %d", getpid());\r
+       setsid();\r
+       DBGI("setsid done");\r
+       /* close standard I/O */\r
+       for (i = 0; i <= 2; ++i)\r
+               close(i);\r
+       if (0 != open("/dev/null", O_RDWR))\r
+               DBGF("Unexpected error");\r
+       dup(0); dup(0);\r
+       DBG("Closed all descriptors");\r
+\r
+\r
+       signal(SIGCHLD, SIG_IGN);\r
+       signal(SIGTSTP, SIG_IGN);\r
+       signal(SIGTTOU, SIG_IGN);\r
+       signal(SIGTTIN, SIG_IGN);\r
+       signal(SIGHUP, SIG_IGN);\r
+       /* catch kill signal */\r
+       signal(SIGTERM, sig_exit);\r
+}\r
+\r
+int read_pid(char *dname)\r
+{\r
+       int ret;\r
+       char *e, *b = strrchr(dname, '/');\r
+       if (b)\r
+               b++;\r
+       else\r
+               b = dname;\r
+       ret = strtol(b, &e, 10);\r
+       if (*e)\r
+               return -1;\r
+       return ret;\r
+}\r
+\r
+int find_server(void)\r
+{\r
+       DIR *fd;\r
+       struct dirent *fdf;\r
+       static int found = 0;\r
+       int  pid;\r
+       char ln[64];\r
+       FILE *fp;\r
+\r
+       if (!(fd = opendir("/proc")))\r
+               error("Unable to open /proc");\r
+       while ((fdf = readdir(fd))) {\r
+               if ((pid = read_pid(fdf->d_name)) < 0)\r
+                       continue;\r
+               if (pid == getpid())\r
+                       continue;\r
+               sprintf(ln, "/proc/%d/cmdline", pid);\r
+               if (!(fp = fopen(ln, "rb")))\r
+                       continue;\r
+               if (!fgets(ln, sizeof(ln), fp)) {\r
+                       fclose(fp);\r
+                       continue;\r
+               }\r
+               if (strstr(ln, "rccd2")) {\r
+                       DBGW("Found rccd process with pid %d", pid);\r
+                       ++found;\r
+                       return pid;\r
+               }\r
+       }\r
+       closedir(fd);\r
+       DBGI("No %srunning rccd2 processes found", found ? "more " : "");\r
+       return 0;\r
+}\r
+\r
+void kill_server(void)\r
+{\r
+       int pid;\r
+\r
+       while ((pid = find_server())) {\r
+               DBGW("Killing rccd process with pid %d", pid);\r
+               kill(pid, SIGTERM);\r
+       }\r
+       exit(0);\r
+}\r
+\r
+const struct option options[] = {\r
+       { "help", 0, 0, 'h' },\r
+       { "verbose", 1, 0, 'v' },\r
+       { "device", 1, 0, 'd' },\r
+       { "codec-device", 0, 0, 'c' },\r
+       { "port", 1, 0, 'p' },\r
+       { "kill-server", 0, 0, 'k' },\r
+       { "safe-mode", 0, 0, 's' },\r
+       { "super-safe", 0, 0, 'S' },\r
+       { "dump", 0, 0, 'D' },\r
+       { 0, 0, 0, 0 }\r
+};\r
+\r
+void usage(int ret)\r
+{\r
+       FILE *f = stdout;\r
+       if (ret)\r
+               f = stderr;\r
+       fprintf(f,\r
+               "Usage: rccd2 [OPTIONS]\n"\r
+               "        Start the Remote CodecControl Server Daemon\n"\r
+               "Options:\n"\r
+               "    --help, -h              Print this help\n"\r
+               "    --verbose=N, -v N       Set verbose level\n"\r
+               "    --safe-mode, -s         Use safe mode (do not fork())\n"\r
+               "    --super-safe, -S        Play super safe.\n"\r
+               "                               No fork(), no concurrent connections\n"\r
+               "    --port=N, -p N          Port number on which to listen\n"\r
+               "                                (Default: %d)\n"\r
+               "    --kill-server, -k       Kill any running instance of rccd2\n"\r
+               "    --dump, -D              Provide a log of commands as they are executed.\n"\r
+               "    --device=<dev>          Open <dev> as the device node\n"\r
+               "        -d <dev>\n"\r
+               "    --fwid=<id>, -f <id>    Set firmware id\n"\r
+               "                                (Default: \"%s\")\n"\r
+               "\n"\r
+               "    [See \"acxrun -h\" for additional help on \"--device\" and]\n"\r
+               "    [\"--codec-device\" options.                              ]\n",\r
+               DEFAULT_PORT, DEFAULT_FWID);\r
+       exit(ret);\r
+}\r
+\r
+int main(int argc, char *argv[])\r
+{\r
+       int serversock, clientsock;\r
+       struct sockaddr_in echoserver, echoclient;\r
+       int fCtrl, i = 0, opt, safe = 0, card = 0;\r
+       int port = DEFAULT_PORT;\r
+       char *device = NULL, *fwid = DEFAULT_FWID;\r
+       char *opts = make_opts(options);\r
+       pthread_mutex_t *mutex = ALLOC(sizeof(pthread_mutex_t));\r
+       pthread_mutex_init(mutex, NULL);\r
+\r
+       DBGI("[DMSG] %s pid=%d ppid=%d", argv[0], getpid(), getppid());\r
+       while ((opt = getopt_long(argc, argv, opts, options, &i)) != -1) {\r
+               switch (opt) {\r
+               case 'h':\r
+                       usage(0);\r
+                       break;\r
+               case 'v':\r
+                       verbose = atoi(optarg);\r
+                       break;\r
+               case 'd':\r
+                       device = strdup(optarg);\r
+                       break;\r
+               case 'p':\r
+                       port = atoi(optarg);\r
+                       break;\r
+               case 'k':\r
+                       kill_server();\r
+                       break;\r
+               case 's':\r
+                       safe = 1;\r
+                       break;\r
+               case 'D':\r
+                       dump_cmds = 1;\r
+                       break;\r
+               case 'S':\r
+                       safe = 2;\r
+                       break;\r
+               case 'r':\r
+                       card = atoi(optarg);\r
+                       break;\r
+               case 'f':\r
+                       fwid = strdup(optarg);\r
+                       break;\r
+               default:\r
+                       usage(1);\r
+               }\r
+       }\r
+       while (optind < argc)\r
+               DBGW("Extra command line argument \"%s\".  Ignored", argv[optind++]);\r
+       \r
+       if (getppid() != 1 && (i = find_server()))\r
+               DBGF("RCCD2 is already running (pid %d)", i);\r
+\r
+       if (!safe) {\r
+               daemonize(argv);\r
+               DBG("Running as daemon");\r
+       }\r
+\r
+       DBGW("Opening Device");\r
+       //vishnu\r
+       fCtrl = open_device(device);\r
+       \r
+       /* Create the TCP socket */\r
+       if ((serversock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)\r
+               DBGF("Failed to create socket");\r
+       /* Construct the server sockaddr_in structure */\r
+       /* Clear struct */\r
+       memset(&echoserver, 0, sizeof(echoserver));\r
+       /* Internet/IP */\r
+       echoserver.sin_family = AF_INET;\r
+       /* Incoming addr */\r
+       echoserver.sin_addr.s_addr = htonl(INADDR_ANY);\r
+       /* server port */\r
+       echoserver.sin_port = htons(port);\r
+\r
+       /* Bind the server socket */\r
+       DBGW("Bind Server Socket");\r
+       if (bind(serversock, (struct sockaddr *)&echoserver, sizeof(echoserver)) < 0)\r
+               DBGF("Failed to bind the server socket");\r
+\r
+       /* Listen on the server socket */\r
+       if (listen(serversock, MAXPENDING) < 0)\r
+               DBGF("Failed to listen on server socket");\r
+\r
+       /* Run until cancelled */\r
+       while (1) {\r
+               socklen_t clientlen = sizeof(echoclient);\r
+               DBGI("Waiting for client connection...");\r
+               /* Wait for client connection */\r
+               if ((clientsock = accept(serversock, (struct sockaddr *) &echoclient,\r
+                       &clientlen)) < 0)\r
+                       DBGF("Failed to accept client connection");\r
+               DBGI("Client connected: %s", inet_ntoa(echoclient.sin_addr));\r
+               struct rccd_hdl *p = ALLOC(sizeof(struct rccd_hdl) + sizeof(union cfw_cmd)*BUFFSIZE);\r
+               pthread_t tid;\r
+               strcpy(p->fwid, fwid);\r
+               p->clientsock = clientsock;\r
+               p->fCtrl = fCtrl;\r
+               p->mutex = mutex;\r
+               /* Pass mutex  as well */ \r
+               if (safe > 1)\r
+               {\r
+                       DBG("Entering Safe Mode");\r
+                       handle_client(p);\r
+               }\r
+               else\r
+               {\r
+                       DBG("Starting in thread");\r
+\r
+                       if (pthread_create(&tid, NULL, handle_client, p) != 0)\r
+                               DBGF("Error creating thread");\r
+               }\r
+       }\r
+}\r
diff --git a/rccd2/rccd2.sh b/rccd2/rccd2.sh
new file mode 100755 (executable)
index 0000000..3b2fcc2
--- /dev/null
@@ -0,0 +1,59 @@
+#!/bin/sh
+
+ADB=adb
+RCCD2=rccd2
+PORT=5000
+CARD=0
+DEBUG=1
+LOGCAT=1
+SAFE=""
+DEBUG_OPTS=
+
+usage()  {
+    echo "usage goes here"
+    exit 0
+}
+
+while getopts "p:c:a:r:dlsh" opt; do
+    case $opt in
+        h) usage ;;
+        p) PORT=$OPTARG ;;
+        c) CARD=$OPTARG ;;
+        a) ADB=$OPTARG ;;
+        r) RCCD2=$OPTARG ;;
+        d) DEBUG=1 ; DEBUG_OPTS="-v 10";;
+        l) LOGCAT=1 ;;
+        s) SAFE=-s ;;
+    esac
+done
+
+if [ "$DEBUG" -eq "1" ]
+then
+    echo "PORT=$PORT"
+    echo "CARD=$CARD"
+    echo "ADB=$ADB"
+    echo "RCCD2=$RCCD2"
+    echo "SAFE=$SAFE"
+    echo "LOGCAT=$LOGCAT"
+fi
+
+${ADB} root
+${ADB} remount
+${ADB} shell svc power stayon true
+sleep 3
+${ADB} push "$RCCD2" /system/bin/rccd2
+${ADB} shell chmod 0777 /system/bin/rccd2
+${ADB} forward tcp:${PORT} tcp:${PORT}
+${ADB} shell rccd2 -k
+${ADB} shell rccd2 --port=${PORT} --card=${CARD} ${SAFE} ${DEBUG_OPTS} -v 4
+if [ "$DEBUG" -eq "1" ]
+then
+    echo "RCCD2 is running..."
+fi
+
+if [ "$LOGCAT" -eq "1" ]
+then
+    ${ADB} logcat -s aic3xxx
+fi
+
+
diff --git a/rccd2/utils.c b/rccd2/utils.c
new file mode 100755 (executable)
index 0000000..7495a66
--- /dev/null
@@ -0,0 +1,79 @@
+#define _GNU_SOURCE
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <math.h>
+
+#include "utils.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+int verbose = 1;
+void error(char *fmt, ...)
+{
+    va_list ap;
+    fprintf(stderr, "error: ");
+    va_start(ap, fmt);
+    vfprintf(stderr, fmt, ap);
+    va_end(ap);
+    fprintf(stderr, "\n");
+    exit(2);
+}
+void warn(char *fmt, ...)
+{
+    va_list ap;
+    if (verbose <= 0)
+        return;
+    fprintf(stderr, "warning: ");
+    va_start(ap, fmt);
+    vfprintf(stderr, fmt, ap);
+    va_end(ap);
+    fprintf(stderr, "\n");
+}
+void dbg(const char *f, int ln, char *fmt, ...)
+{
+    va_list ap;
+    if (getenv("MKCFW_VERBOSITY"))
+        verbose = atoi(getenv("MKCFW_VERBOSITY"));
+    if (verbose <= 1)
+        return;
+    fprintf(stderr, "DBG[%16s:%3d]: ", f, ln);
+    va_start(ap, fmt);
+    vfprintf(stderr, fmt, ap);
+    va_end(ap);
+    fprintf(stderr, "\n");
+}
+void *safe_alloc(const char *fn, const char *file,  int ln, int n)
+{
+    void *ret = calloc(n, 1);
+    if (!ret)
+        error("out of memory: request for %d bytes from function %s() [%s:%d]",
+                n, fn, file, ln);
+    return ret;
+}
+void safe_snprintf(char *str, size_t size, const char *format, ...)
+{
+    char *t = ALLOC(size);
+    va_list ap;
+    va_start(ap, format);
+    vsnprintf(t, size, format, ap);
+    va_end(ap);
+    strcpy(str, t);
+    free(t);
+}
+char *make_opts(const struct option *options)
+{
+    int i = 0;
+    static char opts[256];
+    while (options[i].name) {
+        safe_snprintf(opts, sizeof(opts), "%s%c%s%s", opts, options[i].val,
+                options[i].has_arg?":":"",
+                (options[i].has_arg == 2)?":":"");
+        ++i;
+    }
+    return opts;
+}
similarity index 81%
rename from Android.mk
rename to ti_audio/Android.mk
index f1638c9de3e5fc94c1137cbb623da2ae783815c9..6597f47d903219169231aca4fa91abbc60a4127c 100755 (executable)
@@ -6,11 +6,11 @@ include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := main.c
 
-LOCAL_C_INCLUDES := external/ti_audio_s/
+LOCAL_C_INCLUDES := external/ti_audio/
 
 LOCAL_CFLAGS := -O2 -g -W -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
 
-LOCAL_MODULE := ti_audio_s
+LOCAL_MODULE := ti_audio
 LOCAL_MODULE_TAGS := debug
 LOCAL_SYSTEM_SHARED_LIBRARIES := libc libm
 
similarity index 100%
rename from CleanSpec.mk
rename to ti_audio/CleanSpec.mk
similarity index 100%
rename from main.c
rename to ti_audio/main.c
similarity index 100%
rename from ti_audio.h
rename to ti_audio/ti_audio.h