static int max98925_open(struct inode *inode, struct file *filp) { int ret = 0; int reg = 0; max98925_data->sysclk = 12288000; max98925_data->spk_gain = 0x14; ret = regmap_read(max98925_data->regmapL, MAX98925_R0FF_VERSION, ®); if ((ret < 0) || (reg == 0x00)) { pr_err("max98925 initialization error (%d 0x%02X)\n", ret, reg); goto err_access; } pr_info("max98925 version 0x%02X\n", reg); regmap_write(max98925_data->regmapL, MAX98925_R038_GLOBAL_ENABLE, 0x00); /* It's not the default but we need to set DAI_DLY */ regmap_write(max98925_data->regmapL, MAX98925_R020_FORMAT, M98925_DAI_DLY_MASK | M98925_DAI_CHANSZ_32); regmap_write(max98925_data->regmapL, MAX98925_R021_TDM_SLOT_SELECT, 0xC0); regmap_write(max98925_data->regmapL, MAX98925_R027_DOUT_HIZ_CFG1, 0x00); regmap_write(max98925_data->regmapL, MAX98925_R028_DOUT_HIZ_CFG2, 0x00); regmap_write(max98925_data->regmapL, MAX98925_R029_DOUT_HIZ_CFG3, 0x00); regmap_write(max98925_data->regmapL, MAX98925_R02A_DOUT_HIZ_CFG4, 0x00); regmap_write(max98925_data->regmapL, MAX98925_R02C_FILTERS, 0x49); regmap_write(max98925_data->regmapL, MAX98925_R034_ALC_CONFIGURATION, 0x12); /*****************************************************************/ /* Set boost output to minimum until DSM is implemented */ regmap_write(max98925_data->regmapL, MAX98925_R037_CONFIGURATION, 0x00); /*****************************************************************/ // Disable ALC muting regmap_write(max98925_data->regmapL, MAX98925_R03A_BOOST_LIMITER, 0xF8); regmap_update_bits(max98925_data->regmapL, MAX98925_R02D_GAIN, M98925_DAC_IN_SEL_MASK, M98925_DAC_IN_SEL_DIV2_SUMMED_DAI); max98925_set_clock(max98925_data, 48000); max98925_set_slave(max98925_data); ret = nonseekable_open(inode, filp); if (ret) return ret; filp->private_data = (void*)max98925_data; err_access: pr_info("%s: exit %d\n", __func__, ret); return ret; }
static int max98925_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; struct max98925_priv *max98925 = snd_soc_codec_get_drvdata(codec); struct max98925_cdata *cdata; unsigned int invert = 0; msg_maxim("%s: fmt 0x%08X\n", __func__, fmt); cdata = &max98925->dai[0]; cdata->fmt = fmt; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: max98925_set_slave(max98925); break; case SND_SOC_DAIFMT_CBM_CFM: max98925_set_master(max98925); 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("%s: set SND_SOC_DAIFMT_I2S\n", __func__); break; case SND_SOC_DAIFMT_LEFT_J: msg_maxim("%s: set SND_SOC_DAIFMT_LEFT_J\n", __func__); break; case SND_SOC_DAIFMT_DSP_A: msg_maxim("%s: set SND_SOC_DAIFMT_DSP_A\n", __func__); default: dev_err(codec->dev, "DAI format unsupported, fmt:0x%x", fmt); return -EINVAL; } switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_NB_NF: break; case SND_SOC_DAIFMT_NB_IF: invert = MAX98925_DAI_WCI_MASK; break; case SND_SOC_DAIFMT_IB_NF: invert = MAX98925_DAI_BCI_MASK; break; case SND_SOC_DAIFMT_IB_IF: invert = MAX98925_DAI_BCI_MASK | MAX98925_DAI_WCI_MASK; break; default: dev_err(codec->dev, "DAI invert mode unsupported"); return -EINVAL; } regmap_update_bits(max98925->regmap, MAX98925_R020_FORMAT, MAX98925_DAI_BCI_MASK | MAX98925_DAI_BCI_MASK, invert); return 0; }
static int max98925_do_ioctl(struct file *file, unsigned int cmd, void __user *p, int compat_mode) { int ret = 0; unsigned int value; struct max98925_reg_ops reg_val; unsigned int __user *pUser = (unsigned int __user *) p; struct max98925_priv *max98925 = (struct max98925_priv *)file->private_data; switch (cmd) { case M98925_GET_VERSION: ret = regmap_read(max98925->regmapL, MAX98925_R0FF_VERSION, &value); ret |= put_user(value, pUser); break; case M98925_GET_REG_VAL: if(copy_from_user(®_val,(void*) pUser, sizeof(struct max98925_reg_ops))) { pr_err("%s: set reg copy_from_user fail", __func__); return -1; } ret = regmap_read(max98925->regmapL, reg_val.reg_addr, ®_val.reg_val); if(copy_to_user((void*) pUser, ®_val, sizeof(struct max98925_reg_ops))) { pr_err("%s: send reg value to user fail", __func__); return -1; } break; case M98925_SET_REG_VAL: if(copy_from_user(®_val,(void*) pUser, sizeof(struct max98925_reg_ops))) { pr_err("%s: set reg copy_from_user fail", __func__); return -1; } ret = regmap_write(max98925->regmapL, reg_val.reg_addr, reg_val.reg_val); pr_info("%s: maxim smartpa set reg val: addr = 0x%x, val = 0x%x\n", __func__, reg_val.reg_addr, reg_val.reg_val); break; case M98925_POWER_ON: ret = max98925_digital_mute(max98925, 0); break; case M98925_POWER_OFF: ret = max98925_digital_mute(max98925, 1); break; case M98925_GET_VOLUME: ret = regmap_read(max98925->regmapL, MAX98925_R02D_GAIN, &value); ret |= put_user(value, pUser); break; case M98925_SET_VOLUME: ret = get_user(value, pUser); ret |= regmap_write(max98925->regmapL, MAX98925_R02D_GAIN, value); pr_info("%s: maxim smartpa set volume: 0x%x\n", __func__, value); break; case M98925_GET_DAICLOCK: ret = regmap_read(max98925->regmapL, MAX98925_R01B_DAI_CLK_MODE2, &value); ret |= put_user(value, pUser); break; case M98925_SET_DAICLOCK: ret = get_user(value, pUser); pr_info("%s: maxim smartpa set daiclock: %d\n", __func__, value); ret |= max98925_set_clock(max98925_data, value); ret |= max98925_set_slave(max98925_data); break; #if 0 case M98925_GET_DAIFORMAT: ret = regmap_read(max98925->regmapL, MAX98925_R020_FORMAT, &value); ret |= put_user(value, pUser); break; case M98925_SET_DAIFORMAT: ret = get_user(value, pUser); pr_info("%s: maxim smartpa set daiformat: 0x%x\n",__func__, value); ret |= regmap_write(max98925->regmapL, MAX98925_R020_FORMAT, value); break; #endif case M98925_GET_BOOSTVOLT: ret = regmap_read(max98925->regmapL, MAX98925_R037_CONFIGURATION, &value); ret |= put_user(value, pUser); break; case M98925_SET_BOOSTVOLT: ret = get_user(value, pUser); pr_info("%s: maxim smartpa set boost voltage: 0x%x\n",__func__, value); ret |= regmap_write(max98925->regmapL, MAX98925_R037_CONFIGURATION, value); break; case M98925_GET_ALCTHRESHOLD: ret = regmap_read(max98925->regmapL, MAX98925_R030_THRESHOLD, &value); ret |= put_user(value, pUser); break; case M98925_SET_ALCTHRESHOLD: ret = get_user(value, pUser); pr_info("%s: maxim smartpa set alc threshold: 0x%x\n",__func__, value); ret |= regmap_write(max98925->regmapL, MAX98925_R030_THRESHOLD, value); break; case M98925_GET_FILTERS: ret = regmap_read(max98925->regmapL, MAX98925_R02C_FILTERS, &value); ret |= put_user(value, pUser); break; case M98925_SET_FILTERS: ret = get_user(value, pUser); pr_info("%s: maxim smartpa set fliters: 0x%x\n",__func__, value); ret |= regmap_write(max98925->regmapL, MAX98925_R02C_FILTERS, value); break; case M98925_GET_GAINRAMP: ret = regmap_read(max98925->regmapL, MAX98925_R02E_GAIN_RAMPING, &value); ret |= put_user(value, pUser); break; case M98925_SET_GAINRAMP: ret = get_user(value, pUser); pr_info("%s: maxim smartpa set gainramp: 0x%x\n",__func__, value); ret |= regmap_write(max98925->regmapL, MAX98925_R02E_GAIN_RAMPING, value); break; } if(ret && !dsm_client_ocuppy(max98925_dclient)) { dsm_client_record(max98925_dclient, "%s: ioctl error %d", __func__, ret); dsm_client_notify(max98925_dclient, SMARTPA_I2C_ERR); } return ret; }