void aic3008_CodecInit()
{
	AUD_DBG("aic3008_CodecInit: start\n");
	pwr_up_time = ktime_to_ms(ktime_get());

	pr_device_power_on();

	// aic3008 power up
	aic3008_power_ctl->powerinit();

	// close mic
	aic3008_MicSwitch(0);

	spi_write_table_parsepage(POWER_UP_SEQ, ARRAY_SIZE(POWER_UP_SEQ));
	AUD_DBG("***** SPI CMD: Power Up Seq *****\n");

	AUD_DBG("Audio Codec Power Up takes %lld ms\n",
			ktime_to_ms(ktime_get()) - pwr_up_time);
#if AUDIO_DEBUG_BEEP
	mdelay(100);
	spi_write_table_parsepage(GENERATE_BEEP_LEFT_SPK, ARRAY_SIZE(GENERATE_BEEP_LEFT_SPK));

	AUD_DBG("***** SPI CMD: BEEP *****\n");
	mdelay(300);
	spi_write_table_parsepage(CODEC_SW_RESET, ARRAY_SIZE(CODEC_SW_RESET));
#endif

	aic3008_rx_mode = DOWNLINK_PATH_OFF;
	aic3008_tx_mode = UPLINK_PATH_OFF;
}
/* Access function pointed by ctl_ops to call control operations */
static int aic3008_config(CODEC_SPI_CMD *cmds, int size)
{
	int i, retry, ret;
	unsigned char data;
	if(!aic3008_power_ctl->isPowerOn)
	{
		AUD_INFO("aic3008_config: AIC3008 is power off now");
		return -EINVAL;
	}

	if (!codec_spi_dev) {
		AUD_ERR("no spi device\n");
		return -EFAULT;
	}

	if (cmds == NULL) {
		AUD_ERR("invalid spi parameters\n");
		return -EINVAL;
	}

	/* large dsp image use bulk mode to transfer */
	if (size < 1000) {
		for (i = 0; i < size; i++) {
			switch (cmds[i].act) {
			case 'w':
				codec_spi_write(cmds[i].reg, cmds[i].data, true);
				break;
			case 'r':
				for (retry = AIC3008_MAX_RETRY; retry > 0; retry--) {
					ret = codec_spi_read(cmds[i].reg, &data, true);
					if (ret < 0) {
						AUD_ERR("read fail %d, retry\n", ret);
						hr_msleep(1);
					} else if (data == cmds[i].data) {
						AUD_DBG("data == cmds\n");
						break;
					}
				}
				if (retry <= 0)
					AUD_DBG("3008 power down procedure,"
							" flag 0x%02X=0x%02X(0x%02X)\n",
							cmds[i].reg, ret, cmds[i].data);
				break;
			case 'd':
				msleep(cmds[i].data);
				break;
			default:
				break;
			}
		}
	} else {
		/* use bulk to transfer large data */
		spi_write_table_parsepage(cmds, size);
		AUD_DBG("Here is bulk mode\n");
	}
	return 0;
}
static int aic3254_config(CODEC_SPI_CMD *cmds, int size)
{
	int i, retry, ret;
	unsigned char data;

	if (ctl_ops->spibus_enable)
		ctl_ops->spibus_enable(1);

	if (!codec_dev) {
		pr_aud_err("%s: no spi device\n", __func__);
		return -EFAULT;
	}

	if (cmds == NULL) {
		pr_aud_err("%s: invalid spi parameters\n", __func__);
		return -EINVAL;
	}

	/* when LCM power is off, spi transmission would fail sometime */
	if (suspend_flag && ctl_ops->panel_sleep_in) {
		ret = ctl_ops->panel_sleep_in();
		suspend_flag = 0;
		if (ret < 0)
			pr_aud_err("%s: cannot make panel awake,"
				"it might failed on transmit SPI command\n"
				, __func__);
		else
			pr_aud_info("%s: success on invoking panel_sleep_in\n"
				, __func__);
	}
	/* large dsp image use bulk mode to transfer */
	/* avoid to bulk transfer on spi use ext_gpio_cs project */
	if (size < 1000) {
		for (i = 0; i < size; i++) {
			switch (cmds[i].act) {
			case 'w':
				codec_spi_write(cmds[i].reg, cmds[i].data);
				break;
			case 'r':
				for (retry = AIC3254_MAX_RETRY; retry > 0; retry--) {
					ret = codec_spi_read(cmds[i].reg, &data);
					if (ret < 0)
						pr_aud_err("%s: read fail %d, retry\n",
							__func__, ret);
					else if (data == cmds[i].data)
						break;
					hr_msleep(1);
				}
				if (retry <= 0)
					pr_aud_info("3254 power down procedure"
						" ,flag 0x%02X=0x%02X(0x%02X)\n",
						cmds[i].reg,
						ret, cmds[i].data);
				break;
			case 'd':
				hr_msleep(cmds[i].data);
				break;
			default:
				break;
			}
		}
	} else {
		/* use bulk to transfer large data */
		if (codec_dev->ext_gpio_cs != 0)
			spi_write_table_parsepage(cmds, size);
		else
			spi_write_table(cmds, size);
	}
	if (ctl_ops->spibus_enable)
		ctl_ops->spibus_enable(0);
	return 0;
}