static int max98504_probe(struct max98504_priv *max98504)
{
	struct max98504_pdata *pdata = max98504->pdata;
	struct max98504_cfg_data *cfg_data = &pdata->cfg_data;

	u8 regval;
	int ret;
	unsigned int value;

	msg_maxim("\n");

	max98504_reset(max98504);

	ret = regmap_read(max98504->regmap, MAX98504_REG_7FFF_REV_ID, &value);
	if (ret < 0) {
		pr_err("Failed to read device revision: %d\n",
			ret);
		goto err_access;
	}
	msg_maxim("REV ID=0x%x\n", value);

	if (!pdata) {
		pr_err("No platform data\n");
		return ret;
	}
	/* Configure Rx Mode */
	if (pdata->rx_mode == MODE_RX_PCM) {
		regval = 0;
		if (cfg_data->rx_dither_en)
			regval |= M98504_PCM_DSP_CFG_RX_DITH_EN_MASK;
		if (cfg_data->rx_flt_mode)
			regval |= M98504_PCM_DSP_CFG_RX_FLT_MODE_MASK;

		regmap_update_bits(max98504->regmap,
			MAX98504_REG_25_PCM_DSP_CONFIG,
			M98504_PCM_DSP_CFG_RX_DITH_EN_MASK|\
			M98504_PCM_DSP_CFG_RX_FLT_MODE_MASK,
			regval);
		regmap_write(max98504->regmap,
			MAX98504_REG_20_PCM_RX_ENABLES, (u8)cfg_data->rx_ch_en);
	} else if (pdata->rx_mode == MODE_RX_PDM0 || \
			pdata->rx_mode == MODE_RX_PDM1) {
		regmap_write(max98504->regmap,
			MAX98504_REG_33_PDM_RX_ENABLE, M98504_PDM_RX_EN_MASK);
	} else {
		regmap_write(max98504->regmap,
			MAX98504_REG_20_PCM_RX_ENABLES, 0);
		regmap_write(max98504->regmap,
			MAX98504_REG_33_PDM_RX_ENABLE, 0);
	}

	regmap_write(max98504->regmap,
		MAX98504_REG_35_SPEAKER_SOURCE_SELECT,
		(u8) (M98504_SPK_SRC_SEL_MASK & pdata->rx_mode));

	/* Configure Tx Mode */
	if (pdata->tx_mode == MODE_TX_PCM) {
		regval = 0;
		if (cfg_data->tx_dither_en)
			regval |= M98504_PCM_DSP_CFG_TX_DITH_EN_MASK;
		if (cfg_data->meas_dc_block_en)
			regval |= M98504_PCM_DSP_CFG_MEAS_DCBLK_EN_MASK;
		regmap_update_bits(max98504->regmap,
			MAX98504_REG_25_PCM_DSP_CONFIG,
			M98504_PCM_DSP_CFG_TX_DITH_EN_MASK|\
			M98504_PCM_DSP_CFG_MEAS_DCBLK_EN_MASK, regval);

		regmap_write(max98504->regmap,
			MAX98504_REG_21_PCM_TX_ENABLES, (u8)cfg_data->tx_ch_en);
		regmap_write(max98504->regmap,
			MAX98504_REG_22_PCM_TX_HIZ_CONTROL,
			(u8)cfg_data->tx_hiz_ch_en);
		regmap_write(max98504->regmap,
			MAX98504_REG_23_PCM_TX_CHANNEL_SOURCES,
			(u8)cfg_data->tx_ch_src);
	} else {
		regmap_write(max98504->regmap,
			MAX98504_REG_30_PDM_TX_ENABLES, (u8)cfg_data->tx_ch_en);
		regmap_write(max98504->regmap,
			MAX98504_REG_31_PDM_TX_HIZ_CONTROL,
			(u8)cfg_data->tx_hiz_ch_en);
		regmap_write(max98504->regmap,
			MAX98504_REG_32_PDM_TX_CONTROL,
			(u8)cfg_data->tx_ch_src);
	}

	regmap_write(max98504->regmap,
		MAX98504_REG_36_MEASUREMENT_ENABLES,
		M98504_MEAS_I_EN_MASK | M98504_MEAS_V_EN_MASK);

	/* Brownout Protection */
	regmap_write(max98504->regmap,
	MAX98504_REG_16_PVDD_BROWNOUT_ENABLE, 0x1);
	regmap_write(max98504->regmap,
		MAX98504_REG_17_PVDD_BROWNOUT_CONFIG_1, 0x33);
	regmap_write(max98504->regmap,
		MAX98504_REG_18_PVDD_BROWNOUT_CONFIG_2, 0x0a);
	regmap_write(max98504->regmap,
		MAX98504_REG_19_PVDD_BROWNOUT_CONFIG_3, 0xff);
	regmap_write(max98504->regmap,
		MAX98504_REG_1A_PVDD_BROWNOUT_CONFIG_4, 0xff);

	#ifdef USE_MAX98504_IRQ
	if (gpio_is_valid(pdata->irq))	{
		regmap_write(max98504->regmap,
			MAX98504_REG_03_INTERRUPT_ENABLES, 0xff);
		regmap_write(max98504->regmap,
			MAX98504_REG_10_GPIO_ENABLE, 0x01);
	}
	#endif

	return ret;

err_access:
	return ret;
}
static int max98504_probe(struct snd_soc_codec *codec)
{
	struct max98504_priv *max98504 = snd_soc_codec_get_drvdata(codec);
	struct max98504_cdata *cdata;
	int ret = 0;

	msg_maxim("\n");

	max98504->codec = codec;

	codec->cache_sync = 1;

	ret = snd_soc_codec_set_cache_io(codec, 16, 8, SND_SOC_I2C);
	if (ret != 0) {
		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
		return ret;
	}

	/* reset the codec, the DSP core, and disable all interrupts */
	ret = max98504_reset(codec);
	if (ret < 0) {
		goto err_access;
	}

	/* initialize private data */

	max98504->sysclk = (unsigned)-1;

	cdata = &max98504->dai[0];
	cdata->rate = (unsigned)-1;
	cdata->fmt  = (unsigned)-1;

	ret = snd_soc_read(codec, MAX98504_REG_7FFF_REV_ID);
	if (ret < 0) {
		dev_err(codec->dev, "Failed to read device revision: %d\n",
			ret);
		goto err_access;
	}
	msg_maxim("REV ID=0x%x\n", ret);

	// Do this command for SSM, DEM enable.
	snd_soc_write(codec, MAX98504_REG_7FFF_REV_ID, 0x54);
	snd_soc_write(codec, MAX98504_REG_7FFF_REV_ID, 0x4d);

	#if 0 // // TEMP TEST FACTORY
	snd_soc_write(codec, MAX98504_REG_34_SPEAKER_ENABLE, 0x1);	// Temporary
	snd_soc_write(codec, MAX98504_REG_36_MEASUREMENT_ENABLES, 0x3);	// Temporary
	#endif
	

#ifdef MAX98504_WATCHDOG_ENABLE
	snd_soc_write(codec, MAX98504_REG_03_INTERRUPT_ENABLES, M98504_INT_WATCHFAIL_EN_MASK);
	snd_soc_write(codec, MAX98504_REG_10_GPIO_ENABLE, M98504_GPIO_ENABLE_MASK);
	snd_soc_write(codec, MAX98504_REG_04_INTERRUPT_FLAG_CLEARS, 0xFF);

	if ( (request_threaded_irq(pdata->irq, NULL,
		max98504_interrupt, IRQF_TRIGGER_FALLING,
		"max98504_interrupt", codec)) < 0) {
		msg_maxim("request_irq failed\n");
	}
#endif

	max98504_handle_pdata(codec);
	max98504_add_widgets(codec);

#ifdef MAX98504_WATCHDOG_ENABLE
	INIT_DELAYED_WORK_DEFERRABLE(&max98504->work, max98504_work);
#endif

	msg_maxim("done.");

err_access:
	return ret;
}