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; }