static int __init msm_audio_init(void)
{
	int ret = 0;

	if (machine_is_msm8x60_dragon()) {
		ret = msm8660_wm8903_prepare();
		if (ret) {
			pr_err("failed to prepare wm8903 audio codec\n");
			return ret;
		}

		msm_snd_device = platform_device_alloc("soc-audio", 0);
		if (!msm_snd_device) {
			pr_err("Platform device allocation failed\n");
			msm8660_wm8903_unprepare();
			return -ENOMEM;
		}

		platform_set_drvdata(msm_snd_device, &snd_soc_card_msm8660);
		ret = platform_device_add(msm_snd_device);
		if (ret) {
			platform_device_put(msm_snd_device);
			msm8660_wm8903_unprepare();
			return ret;
		}
	}
	return ret;

}
/**
 * vos_chip_power_qrf8615() - WLAN Power Up Seq for WCN1314 rev 2.0 on QRF 8615
 * @on - Turn WLAN ON/OFF (1 or 0)
 *
 * Power up/down WLAN by turning on/off various regs and asserting/deasserting
 * Power-on-reset pin. Also, put XO A0 buffer as slave to wlan_clk_pwr_req while
 * turning ON WLAN and vice-versa.
 *
 * This function returns 0 on success or a non-zero value on failure.
 */
int vos_chip_power_qrf8615(int on)
{
	static char wlan_on;
	static const char *vregs_qwlan_name[] = {
		"8058_l20",
		"8058_l8",
		"8901_s4",
		"8901_lvs1",
		"8901_l0",
		"8058_s2",
		"8058_s1",
	};
	static const char *vregs_qwlan_pc_name[] = {
		"8058_l20_pc",
		"8058_l8_pc",
		NULL,
		NULL,
		"8901_l0_pc",
		"8058_s2_pc",
		NULL,
	};
	static const int vregs_qwlan_val_min[] = {
		1800000,
		3050000,
		1225000,
		0,
		1200000,
		1300000,
		500000,
	};
	static const int vregs_qwlan_val_max[] = {
		1800000,
		3050000,
		1225000,
		0,
		1200000,
		1300000,
		1250000,
	};
	static const int vregs_qwlan_peek_current[] = {
		4000,
		150000,
		60000,
		0,
		32000,
		130000,
		0,
	};
	static const bool vregs_is_pin_controlled_default[] = {
		1,
		1,
		0,
		0,
		1,
		1,
		0,
	};
	static const bool vregs_is_pin_controlled_dragon[] = {
		0,
		0,
		0,
		0,
		0,
		1,
		0,
	};
	bool const *vregs_is_pin_controlled;
	static struct regulator *vregs_qwlan[ARRAY_SIZE(vregs_qwlan_name)];
	static struct regulator *vregs_pc_qwlan[ARRAY_SIZE(vregs_qwlan_name)];
	static struct msm_xo_voter *wlan_clock;
	int ret, i, rc = 0;
	unsigned wlan_gpio_deep_sleep = GPIO_WLAN_DEEP_SLEEP_N;

	vregs_is_pin_controlled = vregs_is_pin_controlled_default;

	if (machine_is_msm8x60_dragon()) {
		wlan_gpio_deep_sleep = GPIO_WLAN_DEEP_SLEEP_N_DRAGON;
		vregs_is_pin_controlled = vregs_is_pin_controlled_dragon;
	}
	/* WLAN RESET and CLK settings */
	if (on && !wlan_on) {
		/*
		 * Program U12 GPIO expander pin IO1 to de-assert (drive 0)
		 * WLAN_EXT_POR_N to put WLAN in reset
		 */
		rc = gpio_request(wlan_gpio_deep_sleep, "WLAN_DEEP_SLEEP_N");
		if (rc) {
			pr_err("WLAN reset GPIO %d request failed\n",
					wlan_gpio_deep_sleep);
			goto fail;
		}
		rc = gpio_direction_output(wlan_gpio_deep_sleep,
				WLAN_RESET);
		if (rc < 0) {
			pr_err("WLAN reset GPIO %d set output direction failed",
					wlan_gpio_deep_sleep);
			goto fail_gpio_dir_out;
		}

		/* Configure TCXO to be slave to WLAN_CLK_PWR_REQ */
		if (wlan_clock == NULL) {
			wlan_clock = msm_xo_get(MSM_XO_TCXO_A0, id);
			if (IS_ERR(wlan_clock)) {
				pr_err("Failed to get TCXO_A0 voter (%ld)\n",
						PTR_ERR(wlan_clock));
				goto fail_gpio_dir_out;
			}
		}

		rc = msm_xo_mode_vote(wlan_clock, MSM_XO_MODE_PIN_CTRL);
		if (rc < 0) {
			pr_err("Configuring TCXO to Pin controllable failed"
					"(%d)\n", rc);
			goto fail_xo_mode_vote;
		}
	} else if (!on && wlan_on) {
		if (wlan_clock != NULL)
			msm_xo_mode_vote(wlan_clock, MSM_XO_MODE_OFF);
		gpio_set_value_cansleep(wlan_gpio_deep_sleep, WLAN_RESET);
		gpio_free(wlan_gpio_deep_sleep);
	}

	/* WLAN VREG settings */
	for (i = 0; i < ARRAY_SIZE(vregs_qwlan_name); i++) {
		if (on && !wlan_on)	{
			vregs_qwlan[i] = regulator_get(NULL,
					vregs_qwlan_name[i]);
			if (IS_ERR(vregs_qwlan[i])) {
				pr_err("regulator get of %s failed (%ld)\n",
						vregs_qwlan_name[i],
						PTR_ERR(vregs_qwlan[i]));
				rc = PTR_ERR(vregs_qwlan[i]);
				goto vreg_get_fail;
			}
			if (vregs_qwlan_val_min[i] || vregs_qwlan_val_max[i]) {
				rc = regulator_set_voltage(vregs_qwlan[i],
						vregs_qwlan_val_min[i],
						vregs_qwlan_val_max[i]);
				if (rc) {
					pr_err("regulator_set_voltage(%s) failed\n",
							vregs_qwlan_name[i]);
					goto vreg_fail;
				}
			}
			/* vote for pin control (if needed) */
			if (vregs_is_pin_controlled[i]) {
				vregs_pc_qwlan[i] = regulator_get(NULL,
							vregs_qwlan_pc_name[i]);
				if (IS_ERR(vregs_pc_qwlan[i])) {
					pr_err("regulator get of %s failed "
						"(%ld)\n",
						vregs_qwlan_pc_name[i],
						PTR_ERR(vregs_pc_qwlan[i]));
					rc = PTR_ERR(vregs_pc_qwlan[i]);
					goto vreg_fail;
				}
			}

			if (vregs_qwlan_peek_current[i]) {
				rc = regulator_set_optimum_mode(vregs_qwlan[i],
						vregs_qwlan_peek_current[i]);
				if (rc < 0)
					pr_err("vreg %s set optimum mode"
						" failed to %d (%d)\n",
						vregs_qwlan_name[i], rc,
						 vregs_qwlan_peek_current[i]);
			}
			rc = regulator_enable(vregs_qwlan[i]);
			if (rc < 0) {
				pr_err("vreg %s enable failed (%d)\n",
						vregs_qwlan_name[i], rc);
				goto vreg_fail;
			}
			if (vregs_is_pin_controlled[i]) {
				rc = regulator_enable(vregs_pc_qwlan[i]);
				if (rc < 0) {
					pr_err("vreg %s enable failed (%d)\n",
						vregs_qwlan_pc_name[i], rc);
					goto vreg_fail;
				}
			}
		} else if (!on && wlan_on) {

			if (vregs_qwlan_peek_current[i]) {
				/* For legacy reasons we pass 1mA current to
				 * put regulator in LPM mode.
				 */
				rc = regulator_set_optimum_mode(vregs_qwlan[i],
									 1000);
				if (rc < 0)
					pr_info("vreg %s set optimum mode"
								"failed (%d)\n",
						vregs_qwlan_name[i], rc);
				rc = regulator_set_voltage(vregs_qwlan[i], 0 ,
							vregs_qwlan_val_max[i]);
				if (rc)
					pr_err("regulator_set_voltage(%s)"
								"failed (%d)\n",
						vregs_qwlan_name[i], rc);

			}

			if (vregs_is_pin_controlled[i]) {
				rc = regulator_disable(vregs_pc_qwlan[i]);
				if (rc < 0) {
					pr_err("vreg %s disable failed (%d)\n",
						vregs_qwlan_pc_name[i], rc);
					goto vreg_fail;
				}
				regulator_put(vregs_pc_qwlan[i]);
			}

			rc = regulator_disable(vregs_qwlan[i]);
			if (rc < 0) {
				pr_err("vreg %s disable failed (%d)\n",
						vregs_qwlan_name[i], rc);
				goto vreg_fail;
			}
			regulator_put(vregs_qwlan[i]);
		}
	}
	if (on) {
		gpio_set_value_cansleep(wlan_gpio_deep_sleep, WLAN_RESET_OUT);
		wlan_on = true;
	}
	else
		wlan_on = false;
	return 0;

vreg_fail:
	regulator_put(vregs_qwlan[i]);
	if (vregs_is_pin_controlled[i])
		regulator_put(vregs_pc_qwlan[i]);
vreg_get_fail:
	i--;
	while (i >= 0) {
		ret = !on ? regulator_enable(vregs_qwlan[i]) :
			regulator_disable(vregs_qwlan[i]);
		if (ret < 0) {
			pr_err("vreg %s %s failed (%d) in err path\n",
					vregs_qwlan_name[i],
					!on ? "enable" : "disable", ret);
		}
		if (vregs_is_pin_controlled[i]) {
			ret = !on ? regulator_enable(vregs_pc_qwlan[i]) :
				regulator_disable(vregs_pc_qwlan[i]);
			if (ret < 0) {
				pr_err("vreg %s %s failed (%d) in err path\n",
					vregs_qwlan_pc_name[i],
					!on ? "enable" : "disable", ret);
			}
		}
		regulator_put(vregs_qwlan[i]);
		if (vregs_is_pin_controlled[i])
			regulator_put(vregs_pc_qwlan[i]);
		i--;
	}
	if (!on)
		goto fail;
fail_xo_mode_vote:
	msm_xo_put(wlan_clock);
fail_gpio_dir_out:
	gpio_free(wlan_gpio_deep_sleep);
fail:
	return rc;
}