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; }
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++; } }
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); }
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; }
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; }
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; }
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, ®val)) 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; }
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); }