static int max98504_i2c_probe(struct i2c_client *i2c,
			     const struct i2c_device_id *id)
{
	struct max98504_priv *max98504;
	int ret;

	msg_maxim("\n");
#ifdef SUPPORT_DEVICE_TREE
	max98504_regulator_config(i2c, of_property_read_bool(i2c->dev.of_node, "max98504,i2c-pull-up"), 1);
#endif

	max98504 = kzalloc(sizeof(struct max98504_priv), GFP_KERNEL);
	if (max98504 == NULL)
		return -ENOMEM;

	max98504->devtype = id->driver_data;
	i2c_set_clientdata(i2c, max98504);
	max98504->control_data = i2c;
	max98504->pdata = i2c->dev.platform_data;

	ret = snd_soc_register_codec(&i2c->dev,
			&soc_codec_dev_max98504, max98504_dai, ARRAY_SIZE(max98504_dai));
	msg_maxim("ret=%d\n", ret);

	if (ret < 0)
		kfree(max98504);
	return ret;
}
static int max98506_dai_set_fmt(struct snd_soc_dai *codec_dai,
				 unsigned int fmt)
{
	struct snd_soc_codec *codec = codec_dai->codec;
	struct max98506_priv *max98506 = snd_soc_codec_get_drvdata(codec);
	unsigned int invert = 0;

	msg_maxim("fmt 0x%08X", fmt);

	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
	case SND_SOC_DAIFMT_CBS_CFS:
		max98506_set_slave(max98506);
		break;
	case SND_SOC_DAIFMT_CBM_CFM:
		max98506_set_master(max98506);
		break;
	case SND_SOC_DAIFMT_CBS_CFM:
	case SND_SOC_DAIFMT_CBM_CFS:
	default:
		dev_err(codec->dev, "DAI clock mode unsupported");
		return -EINVAL;
	}

	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
		msg_maxim("set SND_SOC_DAIFMT_I2S");
		break;
	case SND_SOC_DAIFMT_LEFT_J:
		msg_maxim("set SND_SOC_DAIFMT_LEFT_J");
		break;
	case SND_SOC_DAIFMT_DSP_A:
		msg_maxim("set SND_SOC_DAIFMT_DSP_A");
	default:
		dev_warn(codec->dev, "DAI format unsupported, fmt:0x%x", fmt);
	}

	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
	case SND_SOC_DAIFMT_NB_NF:
		break;
	case SND_SOC_DAIFMT_NB_IF:
		invert = MAX98506_DAI_WCI_MASK;
		break;
	case SND_SOC_DAIFMT_IB_NF:
		invert = MAX98506_DAI_BCI_MASK;
		break;
	case SND_SOC_DAIFMT_IB_IF:
		invert = MAX98506_DAI_BCI_MASK | MAX98506_DAI_WCI_MASK;
		break;
	default:
		dev_err(codec->dev, "DAI invert mode unsupported");
		return -EINVAL;
	}

	regmap_update_bits(max98506->regmap, MAX98506_R020_FORMAT,
			MAX98506_DAI_BCI_MASK | MAX98506_DAI_WCI_MASK, invert);

	return 0;
}
static void max98504_work(struct work_struct *work)
{
	struct max98504_priv *max98504 = container_of(work, struct max98504_priv, work.work);
	struct snd_soc_codec *codec= max98504->codec;

	if(codec->dapm.bias_level==SND_SOC_BIAS_ON)	{
		snd_soc_write(codec, MAX98504_REG_14_WATCHDOG_CLEAR, 0xE9);
		snd_soc_write(codec, MAX98504_REG_40_GLOBAL_ENABLE, M98504_GLOBAL_EN_MASK);
		msg_maxim("Watchdog Recovery\n");
	}
	else	msg_maxim("No Watchdog Recovery.\n");
}
static void max98504_handle_pdata(struct snd_soc_codec *codec)
{
	struct max98504_priv *max98504 = snd_soc_codec_get_drvdata(codec);
	struct max98504_pdata *pdata = max98504->pdata;

	struct max98504_dsp_cfg *dsp_cfg;
	u8 cmon_en, rx_en, tx_en, tx_hiz_en, tx_ch_src, auth_en, wdog_time_out;
	u8 regval = 0;

#if 1	// TEST
	pdata = &max98504_config;
#endif
	msg_maxim("\n");

	if (!pdata) {
		dev_dbg(codec->dev, "No platform data\n");
		return;
	}
	dsp_cfg = pdata->dsp_cfg;
	cmon_en = pdata->clk_monitor_en;
	rx_en = pdata->rx_ch_en;
	tx_en = pdata->tx_ch_en;
	tx_hiz_en = pdata->tx_hiz_ch_en;
	tx_ch_src = pdata->tx_ch_src;
	auth_en = pdata->auth_en;
	wdog_time_out = pdata->wdog_time_out;

	/* filter */
	if(dsp_cfg->tx_dither_en)	regval = M98504_PCM_DSP_CFG_TX_DITH_EN_MASK;
	if(dsp_cfg->meas_dc_block_en)	regval |= M98504_PCM_DSP_CFG_MEAS_DCBLK_EN_MASK;
	if(dsp_cfg->rx_dither_en)	regval |= M98504_PCM_DSP_CFG_RX_DITH_EN_MASK;
	if(dsp_cfg->rx_flt_mode)	regval |= M98504_PCM_DSP_CFG_RX_FLT_MODE_MASK;

	snd_soc_update_bits(codec, MAX98504_REG_25_PCM_DSP_CONFIG,
		M98504_PCM_DSP_CFG_FLT_MASK, regval);

	snd_soc_write(codec, MAX98504_REG_15_CLOCK_MONITOR_ENABLE, cmon_en & M98504_CMON_ENA_MASK);

	snd_soc_write(codec, MAX98504_REG_20_PCM_RX_ENABLES, rx_en);
	snd_soc_write(codec, MAX98504_REG_21_PCM_TX_ENABLES, tx_en);
	snd_soc_write(codec, MAX98504_REG_22_PCM_TX_HIZ_CONTROL, tx_hiz_en);
	snd_soc_write(codec, MAX98504_REG_23_PCM_TX_CHANNEL_SOURCES, tx_ch_src);

	snd_soc_write(codec, MAX98504_REG_13_WATCHDOG_CONFIG, wdog_time_out);

#if 0	// TEST
	snd_soc_write(codec, MAX98504_REG_35_SPEAKER_SOURCE_SELECT, 1);
#endif

	msg_maxim("RX_EN:0x%x, TX_EN:0x%x, TX_SRC:0x%x, wdog_time_out:%d\n", rx_en, tx_en, tx_ch_src, wdog_time_out);
}
static irqreturn_t max98504_interrupt(int irq, void *data)
{
	struct snd_soc_codec *codec = (struct snd_soc_codec *) data;
	struct max98504_priv *max98504 = snd_soc_codec_get_drvdata(codec);

	unsigned int mask;
	unsigned int flag;

	mask = snd_soc_read(codec, MAX98504_REG_03_INTERRUPT_ENABLES);
	flag = snd_soc_read(codec, MAX98504_REG_02_INTERRUPT_FLAGS);

	msg_maxim("flag=0x%02x mask=0x%02x -> flag=0x%02x\n",
		flag, mask, flag & mask);

	flag &= mask;

	if (!flag)
		return IRQ_NONE;
	
	/* Send work to be scheduled */
	if (flag & M98504_INT_GENFAIL_EN_MASK) {
		msg_maxim("M98504_INT_GENFAIL_EN_MASK active!");
	}

	if (flag & M98504_INT_AUTHDONE_EN_MASK) {
		msg_maxim("M98504_INT_AUTHDONE_EN_MASK active!");
	}

	if (flag & M98504_INT_VBATBROWN_EN_MASK) {
		msg_maxim("M98504_INT_VBATBROWN_EN_MASK active!");
	}

	if (flag & M98504_INT_WATCHFAIL_EN_MASK) {
		msg_maxim("M98504_INT_WATCHFAIL_EN_MASK active!");
		schedule_delayed_work(&max98504->work, msecs_to_jiffies(2000));
	}

	if (flag & M98504_INT_THERMWARN_END_EN_MASK) {
		msg_maxim("M98504_INT_THERMWARN_END_EN_MASK active!");
	}

	if (flag & M98504_INT_THERMWARN_BGN_EN_MASK) {
		msg_maxim("M98504_INT_THERMWARN_BGN_EN_MASK active!\n");
	}
	if (flag & M98504_INT_THERMSHDN_END_EN_MASK) {
		msg_maxim("M98504_INT_THERMSHDN_END_EN_MASK active!\n");
	}
	if (flag & M98504_INT_THERMSHDN_BGN_FLAG_MASK) {
		msg_maxim("M98504_INT_THERMSHDN_BGN_FLAG_MASK active!\n");
	}
	snd_soc_write(codec, MAX98504_REG_04_INTERRUPT_FLAG_CLEARS, flag&0xff);

	return IRQ_HANDLED;
}
static int max98506_volume_step_put(struct snd_kcontrol *kcontrol,
		struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
	struct max98506_priv *max98506 = snd_soc_codec_get_drvdata(codec);
	struct max98506_volume_step_info *vstep = &max98506->vstep;

	int sel = (int)ucontrol->value.integer.value[0];
	unsigned int mask = 0;
	bool adc_status = vstep->adc_status;

	/*
	 * ADC status will be updated according to the volume.
	 * Under step 7 : Disable
	 * Over step 7  : Enable
	 */
	if (sel <= vstep->adc_thres
			&& vstep->adc_status) {
		regmap_update_bits(max98506->regmap,
				MAX98506_R036_BLOCK_ENABLE,
				MAX98506_ADC_VIMON_EN_MASK,
				0);
		adc_status = !vstep->adc_status;
	} else if (sel > vstep->adc_thres
			&& !vstep->adc_status) {
		regmap_update_bits(max98506->regmap,
				MAX98506_R036_BLOCK_ENABLE,
				MAX98506_ADC_VIMON_EN_MASK,
				MAX98506_ADC_VIMON_EN_MASK);
		adc_status = !vstep->adc_status;
	} else if (sel > MAX98506_VSTEP_MAX) {
		msg_maxim("Unknown value %d", sel);
		return -EINVAL;
	}

	if (adc_status != vstep->adc_status) {
		vstep->adc_status = adc_status;
#ifdef CONFIG_SND_SOC_MAXIM_DSM
		maxdsm_update_feature_en_adc((int)adc_status);
#endif /* CONFIG_SND_SOC_MAXIM_DSM */
	}

	/*
	 * Boost voltage will be updated according to the volume.
	 * Step 0 ~ Step 13 : 6.5V
	 * Step 14			: 8.0V
	 * Over step 15		: 8.5V
	 */
	mask |= vstep->boost_step[sel];
	mask <<= MAX98506_BST_VOUT_SHIFT;
	regmap_update_bits(max98506->regmap,
			MAX98506_R037_CONFIGURATION,
			MAX98506_BST_VOUT_MASK,
			mask);

	/* Set volume step to ... */
	vstep->vol_step = sel;

	return 0;
}
Example #7
0
static void reg_dump(struct max98925_priv *max98925)
{
	int val_l;
	int i, j;

	static const struct {
		int start;
		int count;
	} reg_table[] = {
		{ 0x02, 0x03 },
		{ 0x1A, 0x1F },
		{ 0x3A, 0x01 },
		{ 0x00, 0x00 }
	};

	i = 0;
	while (reg_table[i].count != 0) {
		for (j = 0; j < reg_table[i].count; j++) {
			int addr = j + reg_table[i].start;
			regmap_read(max98925->regmap, addr, &val_l);
			msg_maxim("%s: reg 0x%02X, val_l 0x%02X\n",
					__func__, addr, val_l);
		}
		i++;
	}
}
Example #8
0
static void max98925_set_slave(struct max98925_priv *max98925)
{
	msg_maxim("%s: ENTER\n", __func__);

	/*
	 * 1. use BCLK instead of MCLK
	 */
	regmap_update_bits(max98925->regmap, MAX98925_R01A_DAI_CLK_MODE1,
			MAX98925_DAI_CLK_SOURCE_MASK, MAX98925_DAI_CLK_SOURCE_MASK);
	/*
	 * 2. set DAI to slave mode
	 */
	regmap_update_bits(max98925->regmap, MAX98925_R01B_DAI_CLK_MODE2,
			MAX98925_DAI_MAS_MASK, 0);
	/*
	 * 3. set BLCKs to LRCLKs to 64
	 */
	regmap_update_bits(max98925->regmap, MAX98925_R01B_DAI_CLK_MODE2,
			MAX98925_DAI_BSEL_MASK, MAX98925_DAI_BSEL_32);
	/*
	 * 4. set VMON slots
	 */
	regmap_update_bits(max98925->regmap, MAX98925_R022_DOUT_CFG_VMON,
			MAX98925_DAI_VMON_EN_MASK, MAX98925_DAI_VMON_EN_MASK);
	regmap_update_bits(max98925->regmap, MAX98925_R022_DOUT_CFG_VMON,
			MAX98925_DAI_VMON_SLOT_MASK, MAX98925_DAI_VMON_SLOT_00_01);
	/*
	 * 5. set IMON slots
	 */
	regmap_update_bits(max98925->regmap, MAX98925_R023_DOUT_CFG_IMON,
			MAX98925_DAI_IMON_EN_MASK, MAX98925_DAI_IMON_EN_MASK);
	regmap_update_bits(max98925->regmap, MAX98925_R023_DOUT_CFG_IMON,
			MAX98925_DAI_IMON_SLOT_MASK, MAX98925_DAI_IMON_SLOT_02_03);
}
Example #9
0
static int max98925_dai_digital_mute(struct snd_soc_dai *codec_dai, int mute)
{
	struct max98925_priv *max98925
		= snd_soc_codec_get_drvdata(codec_dai->codec);

	msg_maxim("%s: mute %d\n", __func__, mute);

	if (mute) {
		regmap_update_bits(max98925->regmap, MAX98925_R02D_GAIN,
			MAX98925_SPK_GAIN_MASK, 0x00);

		usleep_range(5000, 5000);

		regmap_update_bits(max98925->regmap,
			MAX98925_R038_GLOBAL_ENABLE, MAX98925_EN_MASK, 0x0);
	} else	{
		regmap_update_bits(max98925->regmap, MAX98925_R02D_GAIN,
			MAX98925_SPK_GAIN_MASK, max98925->volume);

		regmap_update_bits(max98925->regmap,
			MAX98925_R036_BLOCK_ENABLE,
			MAX98925_BST_EN_MASK | MAX98925_SPK_EN_MASK |
			MAX98925_ADC_IMON_EN_MASK | MAX98925_ADC_VMON_EN_MASK,
			MAX98925_BST_EN_MASK | MAX98925_SPK_EN_MASK |
			MAX98925_ADC_IMON_EN_MASK | MAX98925_ADC_VMON_EN_MASK);
		regmap_write(max98925->regmap, MAX98925_R038_GLOBAL_ENABLE,
			MAX98925_EN_MASK);
	}

#ifdef USE_REG_DUMP
	reg_dump(max98925);
#endif

	return 0;
}
static int max98504_remove(struct snd_soc_codec *codec)
{

	msg_maxim("\n");

	return 0;
}
static void max98506_handle_pdata(struct snd_soc_codec *codec)
{
	struct max98506_priv *max98506 = snd_soc_codec_get_drvdata(codec);
	struct max98506_pdata *pdata = max98506->pdata;
	struct reg_default *reg_chg;
	int loop;
	int len = pdata->reg_arr_len / sizeof(uint32_t);

	if (!pdata) {
		dev_dbg(codec->dev, "No platform data\n");
		return;
	}

	if (pdata->reg_arr != NULL) {
		for (loop = 0; loop < len; loop += 2) {
			reg_chg = (struct reg_default *)&pdata->reg_arr[loop];
			msg_maxim("[0x%02x, 0x%02x]",
					be32_to_cpu(reg_chg->reg),
					be32_to_cpu(reg_chg->def));
			regmap_write(max98506->regmap,
					be32_to_cpu(reg_chg->reg),
					be32_to_cpu(reg_chg->def));
		}
	}
}
static int max98505_dai_digital_mute(struct snd_soc_dai *codec_dai, int mute)
{
	struct max98505_priv *max98505
		= snd_soc_codec_get_drvdata(codec_dai->codec);
	struct max98505_pdata *pdata = max98505->pdata;
	bool action = 1;

	if (pdata->capture_active != codec_dai->capture_active) {
		pdata->capture_active = codec_dai->capture_active;
		action = 0;
	}

	if (pdata->playback_active != codec_dai->playback_active) {
		pdata->playback_active = codec_dai->playback_active;
		action = 1;
	}

	msg_maxim("mute=%d playback_active=%d capture_active=%d action=%d",
			mute, pdata->playback_active,
			pdata->capture_active, action);

	if (action)
		__max98505_dai_digital_mute(codec_dai, mute);

#ifdef USE_REG_DUMP
	if (action)
		reg_dump(max98505);
#endif /* USE_REG_DUMP */

	return 0;
}
static irqreturn_t max98504_interrupt(int irq, void *data)
{
    struct max98504_priv *max98504 = (struct max98504_priv * )data;

    unsigned int mask;
    unsigned int flag;

    regmap_read(max98504->regmap, MAX98504_REG_03_INTERRUPT_ENABLES, &mask);
    regmap_read(max98504->regmap, MAX98504_REG_02_INTERRUPT_FLAGS, &flag);

    msg_maxim("flag=0x%02x mask=0x%02x -> flag=0x%02x\n",
              flag, mask, flag & mask);

    flag &= mask;

    if (!flag)
        return IRQ_NONE;

    /* Send work to be scheduled */
    if (flag & M98504_INT_GENFAIL_EN_MASK) {
        msg_maxim("M98504_INT_GENFAIL_EN_MASK active!");
    }

    if (flag & M98504_INT_AUTHDONE_EN_MASK) {
        msg_maxim("M98504_INT_AUTHDONE_EN_MASK active!");
    }

    if (flag & M98504_INT_VBATBROWN_EN_MASK) {
        msg_maxim("M98504_INT_VBATBROWN_EN_MASK active!");
    }

    if (flag & M98504_INT_WATCHFAIL_EN_MASK) {
        msg_maxim("M98504_INT_WATCHFAIL_EN_MASK active!");
    }

    if (flag & M98504_INT_THERMWARN_END_EN_MASK) {
        msg_maxim("M98504_INT_THERMWARN_END_EN_MASK active!");
    }

    if (flag & M98504_INT_THERMWARN_BGN_EN_MASK) {
        msg_maxim("M98504_INT_THERMWARN_BGN_EN_MASK active!\n");
    }
    if (flag & M98504_INT_THERMSHDN_END_EN_MASK) {
        msg_maxim("M98504_INT_THERMSHDN_END_EN_MASK active!\n");
    }
    if (flag & M98504_INT_THERMSHDN_BGN_FLAG_MASK) {
        msg_maxim("M98504_INT_THERMSHDN_BGN_FLAG_MASK active!\n");
    }
    regmap_write(max98504->regmap, MAX98504_REG_04_INTERRUPT_FLAG_CLEARS, flag&0xff);

    return IRQ_HANDLED;
}
static int max98506_set_tdm_slot(struct snd_soc_dai *codec_dai,
		unsigned int tx_mask, unsigned int rx_mask,
		int slots, int slot_width)
{
	msg_maxim("tx_mask 0x%X, rx_mask 0x%X, slots %d, slot width %d",
			tx_mask, rx_mask, slots, slot_width);
	return 0;
}
Example #15
0
static int max98925_set_tdm_slot(struct snd_soc_dai *codec_dai,
		unsigned int tx_mask, unsigned int rx_mask,
		int slots, int slot_width)
{
	msg_maxim("%s: tx_mask 0x%X, rx_mask 0x%X, slots %d, slot width %d\n",
			__func__, tx_mask, rx_mask, slots, slot_width);
	return 0;
}
static int __devexit max98504_i2c_remove(struct i2c_client *client)
{
	snd_soc_unregister_codec(&client->dev);
	kfree(i2c_get_clientdata(client));

	msg_maxim("\n");

	return 0;
}
static int max98506_regulator_config(struct device *dev)
{
	struct regulator *max98506_vcc_i2c;
	int ret;

	max98506_vcc_i2c = regulator_get(dev, "vcc_i2c");
	if (IS_ERR(max98506_vcc_i2c)) {
		ret = PTR_ERR(max98506_vcc_i2c);
		dev_err(dev, "%s: regulator get failed ret=%d\n",
				__func__, ret);
		goto err_get_vtg_i2c;
	}
	if (regulator_count_voltages(max98506_vcc_i2c) > 0) {
		ret = regulator_set_voltage(max98506_vcc_i2c,
				VCC_I2C_MIN_UV, VCC_I2C_MAX_UV);
		if (ret) {
			dev_err(dev, "%s: regulator set_vtg failed ret=%d\n",
					__func__, ret);
			goto err_set_vtg_i2c;
		}
	}

	ret = reg_set_optimum_mode_check(max98506_vcc_i2c, I2C_LOAD_UA);
	if (ret < 0) {
		dev_err(dev, "%s: regulator vcc_i2c set_opt failed ret=%d\n",
				__func__, ret);
		goto err_reg_opt_i2c;
	}

	ret = regulator_enable(max98506_vcc_i2c);
	if (ret) {
		dev_err(dev, "%s: regulator vcc_i2c enable failed ret=%d\n",
				__func__, ret);
		goto err_reg_en_vcc_i2c;
	}

	msg_maxim("min_uv:%d max_uv:%d load_ua:%d",
		VCC_I2C_MIN_UV, VCC_I2C_MAX_UV, I2C_LOAD_UA);

	return 0;

err_set_vtg_i2c:
	regulator_put(max98506_vcc_i2c);

err_get_vtg_i2c:
	if (regulator_count_voltages(max98506_vcc_i2c) > 0)
		regulator_set_voltage(max98506_vcc_i2c, 0, VCC_I2C_MAX_UV);

err_reg_en_vcc_i2c:
	reg_set_optimum_mode_check(max98506_vcc_i2c, 0);

err_reg_opt_i2c:
	regulator_disable(max98506_vcc_i2c);

	return ret;
}
Example #18
0
static int max98925_i2c_probe(struct i2c_client *i2c_l,
			     const struct i2c_device_id *id)
{
	struct max98925_priv *max98925;
	int ret;

	msg_maxim("%s: enter, device '%s'\n", __func__, id->name);

	max98925 = kzalloc(sizeof(struct max98925_priv), GFP_KERNEL);
	if (max98925 == NULL)
		return -ENOMEM;

	max98925->devtype = id->driver_data;
	i2c_set_clientdata(i2c_l, max98925);
	max98925->control_data = i2c_l;
	max98925->pdata = i2c_l->dev.platform_data;

	max98925->regmap = regmap_init_i2c(i2c_l, &max98925_regmap);
	if (IS_ERR(max98925->regmap)) {
		ret = PTR_ERR(max98925->regmap);
		dev_err(&i2c_l->dev, "Failed to allocate regmap: %d\n", ret);
		goto err_out;
	}

	ret = snd_soc_register_codec(&i2c_l->dev, &soc_codec_dev_max98925,
			max98925_dai, ARRAY_SIZE(max98925_dai));

err_out:

	if (ret < 0) {
		if (max98925->regmap)
			regmap_exit(max98925->regmap);
		kfree(max98925);
	}

#ifdef CONFIG_SND_SOC_MAXIM_DSM
	maxdsm_init();
#endif

	msg_maxim("%s: ret %d\n", __func__, ret);

	return ret;
}
static int max98504_regulator_config(struct i2c_client *i2c,
	bool pullup, bool on)
{
	struct regulator *max98504_vcc_i2c;
	int rc;
	#define VCC_I2C_MIN_UV 1800000
	#define VCC_I2C_MAX_UV 1800000
	#define I2C_LOAD_UA 300000

	msg_maxim("pullup=%d\n", pullup);

	if (pullup) {
		max98504_vcc_i2c = regulator_get(&i2c->dev, "vcc_i2c");

		if (IS_ERR(max98504_vcc_i2c)) {
			rc = PTR_ERR(max98504_vcc_i2c);
			pr_err("Regulator get failed rc=%d\n",	rc);
			return rc;
		}

		if (regulator_count_voltages(max98504_vcc_i2c) > 0) {
			rc = regulator_set_voltage(max98504_vcc_i2c,
				VCC_I2C_MIN_UV, VCC_I2C_MAX_UV);
			if (rc) {
				pr_err("regulator set_vtg failed rc=%d\n", rc);
				goto error_set_vtg_i2c;
			}
		}

		rc = reg_set_optimum_mode_check(max98504_vcc_i2c, I2C_LOAD_UA);
		if (rc < 0) {
			pr_err("Regulator vcc_i2c set_opt failed rc=%d\n", rc);
			goto error_reg_opt_i2c;
		}

		rc = regulator_enable(max98504_vcc_i2c);
		if (rc) {
			pr_err("Regulator vcc_i2c enable failed rc=%d\n", rc);
			goto error_reg_en_vcc_i2c;
		}
	}

	return 0;

error_reg_en_vcc_i2c:
	if (pullup)
		reg_set_optimum_mode_check(max98504_vcc_i2c, 0);
error_reg_opt_i2c:
	regulator_disable(max98504_vcc_i2c);
error_set_vtg_i2c:
	regulator_put(max98504_vcc_i2c);

	return rc;
}
static int max98504_add_widgets(struct snd_soc_codec *codec)
{
	//struct max98504_priv *max98504 = snd_soc_codec_get_drvdata(codec);

	msg_maxim("\n");

	snd_soc_add_codec_controls(codec, max98504_snd_controls,
		ARRAY_SIZE(max98504_snd_controls));

	return 0;
}
static int max98506_spk_out_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol) {
	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
	struct max98506_priv *max98506 = snd_soc_codec_get_drvdata(codec);
	int enable = !!ucontrol->value.integer.value[0];

	max98506_spk_enable(max98506, enable);

	msg_maxim("Speaker was set by '%s'", spk_state_text[enable]);

	return 0;
}
Example #22
0
static int max98925_dai_set_sysclk(struct snd_soc_dai *dai,
				   int clk_id, unsigned int freq, int dir)
{
	struct snd_soc_codec *codec = dai->codec;
	struct max98925_priv *max98925 = snd_soc_codec_get_drvdata(codec);

	msg_maxim("%s: clk_id %d, freq %d, dir %d\n",
		__func__, clk_id, freq, dir);

	max98925->sysclk = freq;

	return 0;
}
static int max98506_dai_set_sysclk(struct snd_soc_dai *dai,
				   int clk_id, unsigned int freq, int dir)
{
	struct snd_soc_codec *codec = dai->codec;
	struct max98506_priv *max98506 = snd_soc_codec_get_drvdata(codec);
	struct max98506_pdata *pdata = max98506->pdata;

	msg_maxim("clk_id %d, freq %d, dir %d", clk_id, freq, dir);

	pdata->sysclk = freq;

	return 0;
}
static int max98504_rxpcm_gain_get(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
	unsigned int val = snd_soc_read(codec, MAX98504_REG_25_PCM_DSP_CONFIG);

	val = (val & M98504_PCM_DSP_CFG_RX_GAIN_MASK) >> M98504_PCM_DSP_CFG_RX_GAIN_SHIFT;

	ucontrol->value.integer.value[0] = val;
	msg_maxim("val=%d\n",val);

	return 0;

}
static int max98504_ain_gain_get(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
	unsigned int val = snd_soc_read(codec, MAX98504_REG_37_ANALOGUE_INPUT_GAIN);

	val = (val & M98504_ANALOG_INPUT_GAIN_MASK) >> M98504_ANALOG_INPUT_GAIN_SHIFT;

	ucontrol->value.integer.value[0] = val;
	msg_maxim("val=%d\n",val);

	return 0;

}
static int max98504_dai_hw_params(struct snd_pcm_substream *substream,
				   struct snd_pcm_hw_params *params,
				   struct snd_soc_dai *dai)
{
	struct snd_soc_codec *codec = dai->codec;
	struct max98504_priv *max98504 = snd_soc_codec_get_drvdata(codec);
	struct max98504_cdata *cdata;

	unsigned int rate;
	u8 regval;

	msg_maxim("\n");

	cdata = &max98504->dai[0];

	rate = params_rate(params);

	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S8:
		snd_soc_update_bits(codec, MAX98504_REG_24_PCM_MODE_CONFIG,
			M98504_PCM_MODE_CFG_CH_SIZE_MASK, M98504_PCM_MODE_CFG_CH_SIZE_8_MASK);
		break;
	case SNDRV_PCM_FORMAT_S16_LE:
		snd_soc_update_bits(codec, MAX98504_REG_24_PCM_MODE_CONFIG,
			M98504_PCM_MODE_CFG_CH_SIZE_MASK, M98504_PCM_MODE_CFG_CH_SIZE_16_MASK);
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		snd_soc_update_bits(codec, MAX98504_REG_24_PCM_MODE_CONFIG,
			M98504_PCM_MODE_CFG_CH_SIZE_MASK, M98504_PCM_MODE_CFG_CH_SIZE_24_MASK);
		break;
	case SNDRV_PCM_FORMAT_S32_LE:
		snd_soc_update_bits(codec, MAX98504_REG_24_PCM_MODE_CONFIG,
			M98504_PCM_MODE_CFG_CH_SIZE_MASK, M98504_PCM_MODE_CFG_CH_SIZE_32_MASK);
		break;
	default:
		return -EINVAL;
	}

	if (rate_value(rate, &regval))
		return -EINVAL;

	/* Update sample rate mode */
	snd_soc_update_bits(codec, MAX98504_REG_27_PCM_SAMPLE_RATE_SETUP,
		M98504_PCM_SR_SETUP_SPK_SR_MASK, regval<<M98504_PCM_SR_SETUP_SPK_SR_SHIFT);	

	snd_soc_update_bits(codec, MAX98504_REG_27_PCM_SAMPLE_RATE_SETUP,
		M98504_PCM_SR_SETUP_MEAS_SR_MASK, regval<<M98504_PCM_SR_SETUP_MEAS_SR_SHIFT);

	return 0;
}
static int max98504_resume(struct snd_soc_codec *codec)
{
	msg_maxim("\n");
	if(max98504_vcc_i2c)
	{
		int rc;
		rc = regulator_enable(max98504_vcc_i2c);
		if (rc) {
			pr_err("Regulator vcc_i2c enable failed rc=%d\n", rc);
			return rc;
		}
	}
	return 0;
}
static int max98506_spk_out_get(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol) {
	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
	struct max98506_priv *max98506 = snd_soc_codec_get_drvdata(codec);
	unsigned int val;

	regmap_read(max98506->regmap,
			MAX98506_R038_GLOBAL_ENABLE, &val);
	ucontrol->value.integer.value[0] = !!(val & MAX98506_EN_MASK);

	msg_maxim("The status of speaker is '%s'",
			spk_state_text[ucontrol->value.integer.value[0]]);

	return 0;
}
Example #29
0
static void max98925_set_master(struct max98925_priv *max98925)
{
	msg_maxim("%s: ENTER\n", __func__);

	/*
	 * 1. use MCLK for Left channel, right channel always BCLK
	 */
	regmap_update_bits(max98925->regmap, MAX98925_R01A_DAI_CLK_MODE1,
			MAX98925_DAI_CLK_SOURCE_MASK, 0);
	/*
	 * 2. set left channel DAI to master mode, right channel always slave
	 */
	regmap_update_bits(max98925->regmap, MAX98925_R01B_DAI_CLK_MODE2,
			MAX98925_DAI_MAS_MASK, MAX98925_DAI_MAS_MASK);
}
static void max98506_set_master(struct max98506_priv *max98506)
{
	msg_maxim("enter");

	/*
	 * 1. use MCLK for Left channel, right channel always BCLK
	 */
	regmap_update_bits(max98506->regmap, MAX98506_R01A_DAI_CLK_MODE1,
			MAX98506_DAI_CLK_SOURCE_MASK, 0);
	/*
	 * 2. set left channel DAI to master mode, right channel always slave
	 */
	regmap_update_bits(max98506->regmap, MAX98506_R01B_DAI_CLK_MODE2,
			MAX98506_DAI_MAS_MASK, MAX98506_DAI_MAS_MASK);
}