static int __devinit device_gpadc_init(struct pm80x_chip *chip, struct pm80x_platform_data *pdata) { struct pm80x_subchip *subchip = chip->subchip; struct regmap *map = subchip->regmap_gpadc; int data = 0, mask = 0, ret = 0; if (!map) { dev_warn(chip->dev, "Warning: gpadc regmap is not available!\n"); return -EINVAL; } /* * initialize GPADC without activating it turn on GPADC * measurments */ ret = regmap_update_bits(map, PM800_GPADC_MISC_CONFIG2, PM800_GPADC_MISC_GPFSM_EN, PM800_GPADC_MISC_GPFSM_EN); if (ret < 0) goto out; /* * This function configures the ADC as requires for * CP implementation.CP does not "own" the ADC configuration * registers and relies on AP. * Reason: enable automatic ADC measurements needed * for CP to get VBAT and RF temperature readings. */ ret = regmap_update_bits(map, PM800_GPADC_MEAS_EN1, PM800_MEAS_EN1_VBAT, PM800_MEAS_EN1_VBAT); if (ret < 0) goto out; ret = regmap_update_bits(map, PM800_GPADC_MEAS_EN2, (PM800_MEAS_EN2_RFTMP | PM800_MEAS_GP0_EN), (PM800_MEAS_EN2_RFTMP | PM800_MEAS_GP0_EN)); if (ret < 0) goto out; /* * the defult of PM800 is GPADC operates at 100Ks/s rate * and Number of GPADC slots with active current bias prior * to GPADC sampling = 1 slot for all GPADCs set for * Temprature mesurmants */ mask = (PM800_GPADC_GP_BIAS_EN0 | PM800_GPADC_GP_BIAS_EN1 | PM800_GPADC_GP_BIAS_EN2 | PM800_GPADC_GP_BIAS_EN3); if (pdata && (pdata->batt_det == 0)) data = (PM800_GPADC_GP_BIAS_EN0 | PM800_GPADC_GP_BIAS_EN1 | PM800_GPADC_GP_BIAS_EN2 | PM800_GPADC_GP_BIAS_EN3); else data = (PM800_GPADC_GP_BIAS_EN0 | PM800_GPADC_GP_BIAS_EN2 | PM800_GPADC_GP_BIAS_EN3); ret = regmap_update_bits(map, PM800_GP_BIAS_ENA1, mask, data); if (ret < 0) goto out; dev_info(chip->dev, "pm800 device_gpadc_init: Done\n"); return 0; out: dev_info(chip->dev, "pm800 device_gpadc_init: Failed!\n"); return ret; }
static int max8973_init_dcdc(struct max8973_chip *max, struct max8973_regulator_platform_data *pdata) { int ret; uint8_t control1 = 0; uint8_t control2 = 0; if (pdata->control_flags & MAX8973_CONTROL_REMOTE_SENSE_ENABLE) control1 |= MAX8973_SNS_ENABLE; if (!(pdata->control_flags & MAX8973_CONTROL_FALLING_SLEW_RATE_ENABLE)) control1 |= MAX8973_NFSR_ENABLE; if (pdata->control_flags & MAX8973_CONTROL_OUTPUT_ACTIVE_DISCH_ENABLE) control1 |= MAX8973_AD_ENABLE; if (pdata->control_flags & MAX8973_CONTROL_BIAS_ENABLE) control1 |= MAX8973_BIAS_ENABLE; if (pdata->control_flags & MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE) control1 |= MAX8973_FREQSHIFT_9PER; /* Set ramp delay */ if (pdata->reg_init_data && pdata->reg_init_data->constraints.ramp_delay) { if (pdata->reg_init_data->constraints.ramp_delay < 25000) control1 |= MAX8973_RAMP_12mV_PER_US; else if (pdata->reg_init_data->constraints.ramp_delay < 50000) control1 |= MAX8973_RAMP_25mV_PER_US; else if (pdata->reg_init_data->constraints.ramp_delay < 200000) control1 |= MAX8973_RAMP_50mV_PER_US; else control1 |= MAX8973_RAMP_200mV_PER_US; } else { control1 |= MAX8973_RAMP_12mV_PER_US; max->desc.ramp_delay = 12500; } if (!(pdata->control_flags & MAX8973_CONTROL_PULL_DOWN_ENABLE)) control2 |= MAX8973_DISCH_ENBABLE; /* Clock advance trip configuration */ switch (pdata->control_flags & MAX8973_CONTROL_CLKADV_TRIP_MASK) { case MAX8973_CONTROL_CLKADV_TRIP_DISABLED: control2 |= MAX8973_CKKADV_TRIP_DISABLE; break; case MAX8973_CONTROL_CLKADV_TRIP_75mV_PER_US: control2 |= MAX8973_CKKADV_TRIP_75mV_PER_US; break; case MAX8973_CONTROL_CLKADV_TRIP_150mV_PER_US: control2 |= MAX8973_CKKADV_TRIP_150mV_PER_US; break; case MAX8973_CONTROL_CLKADV_TRIP_75mV_PER_US_HIST_DIS: control2 |= MAX8973_CKKADV_TRIP_75mV_PER_US_HIST_DIS; break; } /* Configure inductor value */ switch (pdata->control_flags & MAX8973_CONTROL_INDUCTOR_VALUE_MASK) { case MAX8973_CONTROL_INDUCTOR_VALUE_NOMINAL: control2 |= MAX8973_INDUCTOR_NOMINAL; break; case MAX8973_CONTROL_INDUCTOR_VALUE_MINUS_30_PER: control2 |= MAX8973_INDUCTOR_MIN_30_PER; break; case MAX8973_CONTROL_INDUCTOR_VALUE_PLUS_30_PER: control2 |= MAX8973_INDUCTOR_PLUS_30_PER; break; case MAX8973_CONTROL_INDUCTOR_VALUE_PLUS_60_PER: control2 |= MAX8973_INDUCTOR_PLUS_60_PER; break; } ret = regmap_write(max->regmap, MAX8973_CONTROL1, control1); if (ret < 0) { dev_err(max->dev, "register %d write failed, err = %d", MAX8973_CONTROL1, ret); return ret; } ret = regmap_write(max->regmap, MAX8973_CONTROL2, control2); if (ret < 0) { dev_err(max->dev, "register %d write failed, err = %d", MAX8973_CONTROL2, ret); return ret; } /* If external control is enabled then disable EN bit */ if (max->enable_external_control) { ret = regmap_update_bits(max->regmap, MAX8973_VOUT, MAX8973_VOUT_ENABLE, 0); if (ret < 0) dev_err(max->dev, "register %d update failed, err = %d", MAX8973_VOUT, ret); } return ret; }
static int uda134x_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 uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); unsigned int hw_params = 0; if (substream == uda134x->slave_substream) { pr_debug("%s ignoring hw_params for slave substream\n", __func__); return 0; } pr_debug("%s sysclk: %d, rate:%d\n", __func__, uda134x->sysclk, params_rate(params)); /* set SYSCLK / fs ratio */ switch (uda134x->sysclk / params_rate(params)) { case 512: break; case 384: hw_params |= (1<<4); break; case 256: hw_params |= (1<<5); break; default: printk(KERN_ERR "%s unsupported fs\n", __func__); return -EINVAL; } pr_debug("%s dai_fmt: %d, params_format:%d\n", __func__, uda134x->dai_fmt, params_format(params)); /* set DAI format and word length */ switch (uda134x->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: break; case SND_SOC_DAIFMT_RIGHT_J: switch (params_width(params)) { case 16: hw_params |= (1<<1); break; case 18: hw_params |= (1<<2); break; case 20: hw_params |= ((1<<2) | (1<<1)); break; default: printk(KERN_ERR "%s unsupported format (right)\n", __func__); return -EINVAL; } break; case SND_SOC_DAIFMT_LEFT_J: hw_params |= (1<<3); break; default: printk(KERN_ERR "%s unsupported format\n", __func__); return -EINVAL; } return regmap_update_bits(uda134x->regmap, UDA134X_STATUS0, STATUS0_SYSCLK_MASK | STATUS0_DAIFMT_MASK, hw_params); }
int sec_reg_update(struct sec_pmic_dev *sec_pmic, u8 reg, u8 val, u8 mask) { return regmap_update_bits(sec_pmic->regmap, reg, mask, val); }
static void bcm2835_i2s_clear_fifos(struct bcm2835_i2s_dev *dev, bool tx, bool rx) { int timeout = 1000; uint32_t syncval; uint32_t csreg; uint32_t i2s_active_state; bool clk_was_prepared; uint32_t off; uint32_t clr; off = tx ? BCM2835_I2S_TXON : 0; off |= rx ? BCM2835_I2S_RXON : 0; clr = tx ? BCM2835_I2S_TXCLR : 0; clr |= rx ? BCM2835_I2S_RXCLR : 0; /* Backup the current state */ regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &csreg); i2s_active_state = csreg & (BCM2835_I2S_RXON | BCM2835_I2S_TXON); /* Start clock if not running */ clk_was_prepared = dev->clk_prepared; if (!clk_was_prepared) bcm2835_i2s_start_clock(dev); /* Stop I2S module */ regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, off, 0); /* * Clear the FIFOs * Requires at least 2 PCM clock cycles to take effect */ regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, clr, clr); /* Wait for 2 PCM clock cycles */ /* * Toggle the SYNC flag. After 2 PCM clock cycles it can be read back * FIXME: This does not seem to work for slave mode! */ regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &syncval); syncval &= BCM2835_I2S_SYNC; regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, BCM2835_I2S_SYNC, ~syncval); /* Wait for the SYNC flag changing it's state */ while (--timeout) { regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &csreg); if ((csreg & BCM2835_I2S_SYNC) != syncval) break; } if (!timeout) dev_err(dev->dev, "I2S SYNC error!\n"); /* Stop clock if it was not running before */ if (!clk_was_prepared) bcm2835_i2s_stop_clock(dev); /* Restore I2S state */ regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, BCM2835_I2S_RXON | BCM2835_I2S_TXON, i2s_active_state); }
static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) { struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); u32 xcr = 0, xccr = 0, mask; /* DAI mode */ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: /* Data on rising edge of bclk, frame low, 1clk before data */ xcr |= ESAI_xCR_xFSR; xccr |= ESAI_xCCR_xFSP | ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP; break; case SND_SOC_DAIFMT_LEFT_J: /* Data on rising edge of bclk, frame high */ xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP; break; case SND_SOC_DAIFMT_RIGHT_J: /* Data on rising edge of bclk, frame high, right aligned */ xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCR_xWA; break; case SND_SOC_DAIFMT_DSP_A: /* Data on rising edge of bclk, frame high, 1clk before data */ xcr |= ESAI_xCR_xFSL | ESAI_xCR_xFSR; xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP; break; case SND_SOC_DAIFMT_DSP_B: /* Data on rising edge of bclk, frame high */ xcr |= ESAI_xCR_xFSL; xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP; break; default: return -EINVAL; } /* DAI clock inversion */ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_NB_NF: /* Nothing to do for both normal cases */ break; case SND_SOC_DAIFMT_IB_NF: /* Invert bit clock */ xccr ^= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP; break; case SND_SOC_DAIFMT_NB_IF: /* Invert frame clock */ xccr ^= ESAI_xCCR_xFSP; break; case SND_SOC_DAIFMT_IB_IF: /* Invert both clocks */ xccr ^= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP; break; default: return -EINVAL; } esai_priv->slave_mode = false; /* DAI clock master masks */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBM_CFM: esai_priv->slave_mode = true; break; case SND_SOC_DAIFMT_CBS_CFM: xccr |= ESAI_xCCR_xCKD; break; case SND_SOC_DAIFMT_CBM_CFS: xccr |= ESAI_xCCR_xFSD; break; case SND_SOC_DAIFMT_CBS_CFS: xccr |= ESAI_xCCR_xFSD | ESAI_xCCR_xCKD; break; default: return -EINVAL; } mask = ESAI_xCR_xFSL | ESAI_xCR_xFSR; regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, mask, xcr); regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR, mask, xcr); mask = ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP | ESAI_xCCR_xFSD | ESAI_xCCR_xCKD | ESAI_xCR_xWA; regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, mask, xccr); regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, mask, xccr); return 0; }
int arizona_set_fll(struct arizona_fll *fll, int source, unsigned int Fref, unsigned int Fout) { struct arizona *arizona = fll->arizona; struct arizona_fll_cfg cfg, sync; unsigned int reg, val; int syncsrc; bool ena; int ret; ret = regmap_read(arizona->regmap, fll->base + 1, ®); if (ret != 0) { arizona_fll_err(fll, "Failed to read current state: %d\n", ret); return ret; } ena = reg & ARIZONA_FLL1_ENA; if (Fout) { /* Do we have a 32kHz reference? */ regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val); switch (val & ARIZONA_CLK_32K_SRC_MASK) { case ARIZONA_CLK_SRC_MCLK1: case ARIZONA_CLK_SRC_MCLK2: syncsrc = val & ARIZONA_CLK_32K_SRC_MASK; break; default: syncsrc = -1; } if (source == syncsrc) syncsrc = -1; if (syncsrc >= 0) { ret = arizona_calc_fll(fll, &sync, Fref, Fout); if (ret != 0) return ret; ret = arizona_calc_fll(fll, &cfg, 32768, Fout); if (ret != 0) return ret; } else { ret = arizona_calc_fll(fll, &cfg, Fref, Fout); if (ret != 0) return ret; } } else { regmap_update_bits(arizona->regmap, fll->base + 1, ARIZONA_FLL1_ENA, 0); regmap_update_bits(arizona->regmap, fll->base + 0x11, ARIZONA_FLL1_SYNC_ENA, 0); if (ena) pm_runtime_put_autosuspend(arizona->dev); return 0; } regmap_update_bits(arizona->regmap, fll->base + 5, ARIZONA_FLL1_OUTDIV_MASK, cfg.outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); if (syncsrc >= 0) { arizona_apply_fll(arizona, fll->base, &cfg, syncsrc); arizona_apply_fll(arizona, fll->base + 0x10, &sync, source); } else { arizona_apply_fll(arizona, fll->base, &cfg, source); } if (!ena) pm_runtime_get(arizona->dev); /* Clear any pending completions */ try_wait_for_completion(&fll->ok); regmap_update_bits(arizona->regmap, fll->base + 1, ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); if (syncsrc >= 0) regmap_update_bits(arizona->regmap, fll->base + 0x11, ARIZONA_FLL1_SYNC_ENA, ARIZONA_FLL1_SYNC_ENA); ret = wait_for_completion_timeout(&fll->ok, msecs_to_jiffies(25)); if (ret == 0) arizona_fll_warn(fll, "Timed out waiting for lock\n"); return 0; }
static int pm8xxx_read_channel_rsv(struct pm8xxx_xoadc *adc, const struct pm8xxx_chan_info *ch, u8 rsv, u16 *adc_code, bool force_ratiometric) { int ret; unsigned int val; u8 rsvmask, rsvval; u8 lsb, msb; dev_dbg(adc->dev, "read channel \"%s\", amux %d, prescale/mux: %d, rsv %d\n", ch->name, ch->hwchan->amux_channel, ch->hwchan->pre_scale_mux, rsv); mutex_lock(&adc->lock); /* Mux in this channel */ val = ch->hwchan->amux_channel << ADC_AMUX_SEL_SHIFT; val |= ch->hwchan->pre_scale_mux << ADC_AMUX_PREMUX_SHIFT; ret = regmap_write(adc->map, ADC_ARB_USRP_AMUX_CNTRL, val); if (ret) goto unlock; /* Set up ratiometric scale value, mask off all bits except these */ rsvmask = (ADC_ARB_USRP_RSV_RST | ADC_ARB_USRP_RSV_DTEST0 | ADC_ARB_USRP_RSV_DTEST1 | ADC_ARB_USRP_RSV_OP); if (adc->variant->broken_ratiometric && !force_ratiometric) { /* * Apparently the PM8058 has some kind of bug which is * reflected in the vendor tree drivers/misc/pmix8058-xoadc.c * which just hardcodes the RSV selector to SEL1 (0x20) for * most cases and SEL0 (0x10) for the MUXOFF channel only. * If we force ratiometric (currently only done when attempting * to do ratiometric calibration) this doesn't seem to work * very well and I suspect ratiometric conversion is simply * broken or not supported on the PM8058. * * Maybe IO_SEL2 doesn't exist on PM8058 and bits 4 & 5 select * the mode alone. * * Some PM8058 register documentation would be nice to get * this right. */ if (ch->hwchan->amux_channel == PM8XXX_CHANNEL_MUXOFF) rsvval = ADC_ARB_USRP_RSV_IP_SEL0; else rsvval = ADC_ARB_USRP_RSV_IP_SEL1; } else { if (rsv == 0xff) rsvval = (ch->amux_ip_rsv << ADC_RSV_IP_SEL_SHIFT) | ADC_ARB_USRP_RSV_TRM; else rsvval = (rsv << ADC_RSV_IP_SEL_SHIFT) | ADC_ARB_USRP_RSV_TRM; } ret = regmap_update_bits(adc->map, ADC_ARB_USRP_RSV, ~rsvmask, rsvval); if (ret) goto unlock; ret = regmap_write(adc->map, ADC_ARB_USRP_ANA_PARAM, ADC_ARB_USRP_ANA_PARAM_DIS); if (ret) goto unlock; /* Decimation factor */ ret = regmap_write(adc->map, ADC_ARB_USRP_DIG_PARAM, ADC_ARB_USRP_DIG_PARAM_SEL_SHIFT0 | ADC_ARB_USRP_DIG_PARAM_SEL_SHIFT1 | ch->decimation << ADC_DIG_PARAM_DEC_SHIFT); if (ret) goto unlock; ret = regmap_write(adc->map, ADC_ARB_USRP_ANA_PARAM, ADC_ARB_USRP_ANA_PARAM_EN); if (ret) goto unlock; /* Enable the arbiter, the Qualcomm code does it twice like this */ ret = regmap_write(adc->map, ADC_ARB_USRP_CNTRL, ADC_ARB_USRP_CNTRL_EN_ARB); if (ret) goto unlock; ret = regmap_write(adc->map, ADC_ARB_USRP_CNTRL, ADC_ARB_USRP_CNTRL_EN_ARB); if (ret) goto unlock; /* Fire a request! */ reinit_completion(&adc->complete); ret = regmap_write(adc->map, ADC_ARB_USRP_CNTRL, ADC_ARB_USRP_CNTRL_EN_ARB | ADC_ARB_USRP_CNTRL_REQ); if (ret) goto unlock; /* Next the interrupt occurs */ ret = wait_for_completion_timeout(&adc->complete, VADC_CONV_TIME_MAX_US); if (!ret) { dev_err(adc->dev, "conversion timed out\n"); ret = -ETIMEDOUT; goto unlock; } ret = regmap_read(adc->map, ADC_ARB_USRP_DATA0, &val); if (ret) goto unlock; lsb = val; ret = regmap_read(adc->map, ADC_ARB_USRP_DATA1, &val); if (ret) goto unlock; msb = val; *adc_code = (msb << 8) | lsb; /* Turn off the ADC by setting the arbiter to 0 twice */ ret = regmap_write(adc->map, ADC_ARB_USRP_CNTRL, 0); if (ret) goto unlock; ret = regmap_write(adc->map, ADC_ARB_USRP_CNTRL, 0); if (ret) goto unlock; unlock: mutex_unlock(&adc->lock); return ret; }
static void exynos4x12_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on) { struct samsung_usb2_phy_driver *drv = inst->drv; u32 rstbits = 0; u32 phypwr = 0; u32 rst; u32 pwr; u32 mode = 0; u32 switch_mode = 0; switch (inst->cfg->id) { case EXYNOS4x12_DEVICE: phypwr = EXYNOS_4x12_UPHYPWR_PHY0; rstbits = EXYNOS_4x12_URSTCON_PHY0; mode = EXYNOS_4x12_MODE_SWITCH_DEVICE; switch_mode = 1; break; case EXYNOS4x12_HOST: phypwr = EXYNOS_4x12_UPHYPWR_PHY1; rstbits = EXYNOS_4x12_URSTCON_HOST_PHY; mode = EXYNOS_4x12_MODE_SWITCH_HOST; switch_mode = 1; break; case EXYNOS4x12_HSIC0: phypwr = EXYNOS_4x12_UPHYPWR_HSIC0; rstbits = EXYNOS_4x12_URSTCON_HSIC1 | EXYNOS_4x12_URSTCON_HOST_LINK_P0 | EXYNOS_4x12_URSTCON_HOST_PHY; break; case EXYNOS4x12_HSIC1: phypwr = EXYNOS_4x12_UPHYPWR_HSIC1; rstbits = EXYNOS_4x12_URSTCON_HSIC1 | EXYNOS_4x12_URSTCON_HOST_LINK_P1; break; }; if (on) { if (switch_mode) regmap_update_bits(drv->reg_sys, EXYNOS_4x12_MODE_SWITCH_OFFSET, EXYNOS_4x12_MODE_SWITCH_MASK, mode); pwr = readl(drv->reg_phy + EXYNOS_4x12_UPHYPWR); pwr &= ~phypwr; writel(pwr, drv->reg_phy + EXYNOS_4x12_UPHYPWR); rst = readl(drv->reg_phy + EXYNOS_4x12_UPHYRST); rst |= rstbits; writel(rst, drv->reg_phy + EXYNOS_4x12_UPHYRST); udelay(10); rst &= ~rstbits; writel(rst, drv->reg_phy + EXYNOS_4x12_UPHYRST); /* The following delay is necessary for the reset sequence to be * completed */ udelay(80); } else { pwr = readl(drv->reg_phy + EXYNOS_4x12_UPHYPWR); pwr |= phypwr; writel(pwr, drv->reg_phy + EXYNOS_4x12_UPHYPWR); } }
static int rk808_rtc_probe(struct platform_device *pdev) { struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); struct rk808_rtc *rk808_rtc; struct rtc_time tm; int ret; rk808_rtc = devm_kzalloc(&pdev->dev, sizeof(*rk808_rtc), GFP_KERNEL); if (rk808_rtc == NULL) return -ENOMEM; platform_set_drvdata(pdev, rk808_rtc); rk808_rtc->rk808 = rk808; /* start rtc running by default, and use shadowed timer. */ ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG, BIT_RTC_CTRL_REG_STOP_RTC_M | BIT_RTC_CTRL_REG_RTC_READSEL_M, BIT_RTC_CTRL_REG_RTC_READSEL_M); if (ret) { dev_err(&pdev->dev, "Failed to update RTC control: %d\n", ret); return ret; } ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG, RTC_STATUS_MASK); if (ret) { dev_err(&pdev->dev, "Failed to write RTC status: %d\n", ret); return ret; } /* set init time */ ret = rk808_rtc_readtime(&pdev->dev, &tm); if (ret) { dev_err(&pdev->dev, "Failed to read RTC time\n"); return ret; } ret = rtc_valid_tm(&tm); if (ret) dev_warn(&pdev->dev, "invalid date/time\n"); device_init_wakeup(&pdev->dev, 1); rk808_rtc->rtc = devm_rtc_device_register(&pdev->dev, "rk808-rtc", &rk808_rtc_ops, THIS_MODULE); if (IS_ERR(rk808_rtc->rtc)) { ret = PTR_ERR(rk808_rtc->rtc); return ret; } rk808_rtc->irq = platform_get_irq(pdev, 0); if (rk808_rtc->irq < 0) { if (rk808_rtc->irq != -EPROBE_DEFER) dev_err(&pdev->dev, "Wake up is not possible as irq = %d\n", rk808_rtc->irq); return rk808_rtc->irq; } /* request alarm irq of rk808 */ ret = devm_request_threaded_irq(&pdev->dev, rk808_rtc->irq, NULL, rk808_alarm_irq, 0, "RTC alarm", rk808_rtc); if (ret) { dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n", rk808_rtc->irq, ret); } return ret; }
static int meson_pinconf_set(struct pinctrl_dev *pcdev, unsigned int pin, unsigned long *configs, unsigned num_configs) { struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev); struct meson_bank *bank; enum pin_config_param param; unsigned int reg, bit; int i, ret; ret = meson_get_bank(pc, pin, &bank); if (ret) return ret; for (i = 0; i < num_configs; i++) { param = pinconf_to_config_param(configs[i]); switch (param) { case PIN_CONFIG_BIAS_DISABLE: dev_dbg(pc->dev, "pin %u: disable bias\n", pin); meson_calc_reg_and_bit(bank, pin, REG_PULL, ®, &bit); ret = regmap_update_bits(pc->reg_pull, reg, BIT(bit), 0); if (ret) return ret; break; case PIN_CONFIG_BIAS_PULL_UP: dev_dbg(pc->dev, "pin %u: enable pull-up\n", pin); meson_calc_reg_and_bit(bank, pin, REG_PULLEN, ®, &bit); ret = regmap_update_bits(pc->reg_pullen, reg, BIT(bit), BIT(bit)); if (ret) return ret; meson_calc_reg_and_bit(bank, pin, REG_PULL, ®, &bit); ret = regmap_update_bits(pc->reg_pull, reg, BIT(bit), BIT(bit)); if (ret) return ret; break; case PIN_CONFIG_BIAS_PULL_DOWN: dev_dbg(pc->dev, "pin %u: enable pull-down\n", pin); meson_calc_reg_and_bit(bank, pin, REG_PULLEN, ®, &bit); ret = regmap_update_bits(pc->reg_pullen, reg, BIT(bit), BIT(bit)); if (ret) return ret; meson_calc_reg_and_bit(bank, pin, REG_PULL, ®, &bit); ret = regmap_update_bits(pc->reg_pull, reg, BIT(bit), 0); if (ret) return ret; break; default: return -ENOTSUPP; } } return 0; }
static int adau1701_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); unsigned int serictl = 0x00, seroctl = 0x00; bool invert_lrclk; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBM_CFM: /* master, 64-bits per sample, 1 frame per sample */ seroctl |= ADAU1701_SEROCTL_MASTER | ADAU1701_SEROCTL_OBF16 | ADAU1701_SEROCTL_OLF1024; break; case SND_SOC_DAIFMT_CBS_CFS: break; default: return -EINVAL; } /* clock inversion */ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_NB_NF: invert_lrclk = false; break; case SND_SOC_DAIFMT_NB_IF: invert_lrclk = true; break; case SND_SOC_DAIFMT_IB_NF: invert_lrclk = false; serictl |= ADAU1701_SERICTL_INV_BCLK; seroctl |= ADAU1701_SEROCTL_INV_BCLK; break; case SND_SOC_DAIFMT_IB_IF: invert_lrclk = true; serictl |= ADAU1701_SERICTL_INV_BCLK; seroctl |= ADAU1701_SEROCTL_INV_BCLK; break; default: return -EINVAL; } switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: break; case SND_SOC_DAIFMT_LEFT_J: serictl |= ADAU1701_SERICTL_LEFTJ; seroctl |= ADAU1701_SEROCTL_MSB_DEALY0; invert_lrclk = !invert_lrclk; break; case SND_SOC_DAIFMT_RIGHT_J: serictl |= ADAU1701_SERICTL_RIGHTJ_24; seroctl |= ADAU1701_SEROCTL_MSB_DEALY8; invert_lrclk = !invert_lrclk; break; default: return -EINVAL; } if (invert_lrclk) { seroctl |= ADAU1701_SEROCTL_INV_LRCLK; serictl |= ADAU1701_SERICTL_INV_LRCLK; } adau1701->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK; regmap_write(adau1701->regmap, ADAU1701_SERICTL, serictl); regmap_update_bits(adau1701->regmap, ADAU1701_SEROCTL, ~ADAU1701_SEROCTL_WORD_LEN_MASK, seroctl); return 0; }
static int tps65910_rtc_probe(struct platform_device *pdev) { struct tps65910 *tps65910 = NULL; struct tps65910_rtc *tps_rtc = NULL; int ret; int irq; u32 rtc_reg; tps65910 = dev_get_drvdata(pdev->dev.parent); tps_rtc = devm_kzalloc(&pdev->dev, sizeof(struct tps65910_rtc), GFP_KERNEL); if (!tps_rtc) return -ENOMEM; /* Clear pending interrupts */ ret = regmap_read(tps65910->regmap, TPS65910_RTC_STATUS, &rtc_reg); if (ret < 0) return ret; ret = regmap_write(tps65910->regmap, TPS65910_RTC_STATUS, rtc_reg); if (ret < 0) return ret; dev_dbg(&pdev->dev, "Enabling rtc-tps65910.\n"); /* Enable RTC digital power domain */ ret = regmap_update_bits(tps65910->regmap, TPS65910_DEVCTRL, DEVCTRL_RTC_PWDN_MASK, 0 << DEVCTRL_RTC_PWDN_SHIFT); if (ret < 0) return ret; rtc_reg = TPS65910_RTC_CTRL_STOP_RTC; ret = regmap_write(tps65910->regmap, TPS65910_RTC_CTRL, rtc_reg); if (ret < 0) return ret; platform_set_drvdata(pdev, tps_rtc); irq = platform_get_irq(pdev, 0); if (irq <= 0) { dev_warn(&pdev->dev, "Wake up is not possible as irq = %d\n", irq); return -ENXIO; } ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, tps65910_rtc_interrupt, IRQF_TRIGGER_LOW | IRQF_EARLY_RESUME, dev_name(&pdev->dev), &pdev->dev); if (ret < 0) { dev_err(&pdev->dev, "IRQ is not free.\n"); return ret; } tps_rtc->irq = irq; device_set_wakeup_capable(&pdev->dev, 1); tps_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &tps65910_rtc_ops, THIS_MODULE); if (IS_ERR(tps_rtc->rtc)) { ret = PTR_ERR(tps_rtc->rtc); dev_err(&pdev->dev, "RTC device register: err %d\n", ret); return ret; } return 0; }
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; }
/** * This function is used to calculate the divisors of psr, pm, fp and it is * supposed to be called in set_dai_sysclk() and set_bclk(). * * @ratio: desired overall ratio for the paticipating dividers * @usefp: for HCK setting, there is no need to set fp divider * @fp: bypass other dividers by setting fp directly if fp != 0 * @tx: current setting is for playback or capture */ static int fsl_esai_divisor_cal(struct snd_soc_dai *dai, bool tx, u32 ratio, bool usefp, u32 fp) { struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); u32 psr, pm = 999, maxfp, prod, sub, savesub, i, j; maxfp = usefp ? 16 : 1; if (usefp && fp) goto out_fp; if (ratio > 2 * 8 * 256 * maxfp || ratio < 2) { dev_err(dai->dev, "the ratio is out of range (2 ~ %d)\n", 2 * 8 * 256 * maxfp); return -EINVAL; } else if (ratio % 2) { dev_err(dai->dev, "the raio must be even if using upper divider\n"); return -EINVAL; } ratio /= 2; psr = ratio <= 256 * maxfp ? ESAI_xCCR_xPSR_BYPASS : ESAI_xCCR_xPSR_DIV8; /* Set the max fluctuation -- 0.1% of the max devisor */ savesub = (psr ? 1 : 8) * 256 * maxfp / 1000; /* Find the best value for PM */ for (i = 1; i <= 256; i++) { for (j = 1; j <= maxfp; j++) { /* PSR (1 or 8) * PM (1 ~ 256) * FP (1 ~ 16) */ prod = (psr ? 1 : 8) * i * j; if (prod == ratio) sub = 0; else if (prod / ratio == 1) sub = prod - ratio; else if (ratio / prod == 1) sub = ratio - prod; else continue; /* Calculate the fraction */ sub = sub * 1000 / ratio; if (sub < savesub) { savesub = sub; pm = i; fp = j; } /* We are lucky */ if (savesub == 0) goto out; } } if (pm == 999) { dev_err(dai->dev, "failed to calculate proper divisors\n"); return -EINVAL; } out: regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx), ESAI_xCCR_xPSR_MASK | ESAI_xCCR_xPM_MASK, psr | ESAI_xCCR_xPM(pm)); out_fp: /* Bypass fp if not being required */ if (maxfp <= 1) return 0; regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx), ESAI_xCCR_xFP_MASK, ESAI_xCCR_xFP(fp)); return 0; }
static int imx6q_sata_init(struct device *dev, void __iomem *mmio) { int ret = 0; unsigned int reg_val; struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent); imxpriv->gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr"); if (IS_ERR(imxpriv->gpr)) { dev_err(dev, "failed to find fsl,imx6q-iomux-gpr regmap\n"); return PTR_ERR(imxpriv->gpr); } ret = clk_prepare_enable(imxpriv->sata_ref_clk); if (ret < 0) { dev_err(dev, "prepare-enable sata_ref clock err:%d\n", ret); return ret; } /* * set PHY Paremeters, two steps to configure the GPR13, * one write for rest of parameters, mask of first write * is 0x07fffffd, and the other one write for setting * the mpll_clk_en. */ regmap_update_bits(imxpriv->gpr, 0x34, IMX6Q_GPR13_SATA_RX_EQ_VAL_MASK | IMX6Q_GPR13_SATA_RX_LOS_LVL_MASK | IMX6Q_GPR13_SATA_RX_DPLL_MODE_MASK | IMX6Q_GPR13_SATA_SPD_MODE_MASK | IMX6Q_GPR13_SATA_MPLL_SS_EN | IMX6Q_GPR13_SATA_TX_ATTEN_MASK | IMX6Q_GPR13_SATA_TX_BOOST_MASK | IMX6Q_GPR13_SATA_TX_LVL_MASK | IMX6Q_GPR13_SATA_TX_EDGE_RATE , IMX6Q_GPR13_SATA_RX_EQ_VAL_3_0_DB | IMX6Q_GPR13_SATA_RX_LOS_LVL_SATA2M | IMX6Q_GPR13_SATA_RX_DPLL_MODE_2P_4F | IMX6Q_GPR13_SATA_SPD_MODE_3P0G | IMX6Q_GPR13_SATA_MPLL_SS_EN | IMX6Q_GPR13_SATA_TX_ATTEN_9_16 | IMX6Q_GPR13_SATA_TX_BOOST_3_33_DB | IMX6Q_GPR13_SATA_TX_LVL_1_025_V); regmap_update_bits(imxpriv->gpr, 0x34, IMX6Q_GPR13_SATA_MPLL_CLK_EN, IMX6Q_GPR13_SATA_MPLL_CLK_EN); usleep_range(100, 200); /* * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL, * and IP vendor specific register HOST_TIMER1MS. * Configure CAP_SSS (support stagered spin up). * Implement the port0. * Get the ahb clock rate, and configure the TIMER1MS register. */ reg_val = readl(mmio + HOST_CAP); if (!(reg_val & HOST_CAP_SSS)) { reg_val |= HOST_CAP_SSS; writel(reg_val, mmio + HOST_CAP); } reg_val = readl(mmio + HOST_PORTS_IMPL); if (!(reg_val & 0x1)) { reg_val |= 0x1; writel(reg_val, mmio + HOST_PORTS_IMPL); } reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000; writel(reg_val, mmio + HOST_TIMER1MS); return 0; }
/** * This function mainly configures the clock frequency of MCLK (HCKT/HCKR) * * @Parameters: * clk_id: The clock source of HCKT/HCKR * (Input from outside; output from inside, FSYS or EXTAL) * freq: The required clock rate of HCKT/HCKR * dir: The clock direction of HCKT/HCKR * * Note: If the direction is input, we do not care about clk_id. */ static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir) { struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); struct clk *clksrc = esai_priv->extalclk; bool tx = clk_id <= ESAI_HCKT_EXTAL; bool in = dir == SND_SOC_CLOCK_IN; u32 ret, ratio, ecr = 0; unsigned long clk_rate; /* sck_div can be only bypassed if ETO/ERO=0 and SNC_SOC_CLOCK_OUT */ esai_priv->sck_div[tx] = true; /* Set the direction of HCKT/HCKR pins */ regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx), ESAI_xCCR_xHCKD, in ? 0 : ESAI_xCCR_xHCKD); if (in) goto out; switch (clk_id) { case ESAI_HCKT_FSYS: case ESAI_HCKR_FSYS: clksrc = esai_priv->fsysclk; break; case ESAI_HCKT_EXTAL: ecr |= ESAI_ECR_ETI; case ESAI_HCKR_EXTAL: ecr |= ESAI_ECR_ERI; break; default: return -EINVAL; } if (IS_ERR(clksrc)) { dev_err(dai->dev, "no assigned %s clock\n", clk_id % 2 ? "extal" : "fsys"); return PTR_ERR(clksrc); } clk_rate = clk_get_rate(clksrc); ratio = clk_rate / freq; if (ratio * freq > clk_rate) ret = ratio * freq - clk_rate; else if (ratio * freq < clk_rate) ret = clk_rate - ratio * freq; else ret = 0; /* Block if clock source can not be divided into the required rate */ if (ret != 0 && clk_rate / ret < 1000) { dev_err(dai->dev, "failed to derive required HCK%c rate\n", tx ? 'T' : 'R'); return -EINVAL; } /* Only EXTAL source can be output directly without using PSR and PM */ if (ratio == 1 && clksrc == esai_priv->extalclk) { /* Bypass all the dividers if not being needed */ ecr |= tx ? ESAI_ECR_ETO : ESAI_ECR_ERO; goto out; } else if (ratio < 2) { /* The ratio should be no less than 2 if using other sources */ dev_err(dai->dev, "failed to derive required HCK%c rate\n", tx ? 'T' : 'R'); return -EINVAL; } ret = fsl_esai_divisor_cal(dai, tx, ratio, false, 0); if (ret) return ret; esai_priv->sck_div[tx] = false; out: esai_priv->hck_rate[tx] = freq; regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR, tx ? ESAI_ECR_ETI | ESAI_ECR_ETO : ESAI_ECR_ERI | ESAI_ECR_ERO, ecr); return 0; }
static int adau1977_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 adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec); unsigned int rate = params_rate(params); unsigned int slot_width; unsigned int ctrl0, ctrl0_mask; unsigned int ctrl1; int mcs, fs; int ret; fs = adau1977_lookup_fs(rate); if (fs < 0) return fs; if (adau1977->sysclk_src == ADAU1977_SYSCLK_SRC_MCLK) { mcs = adau1977_lookup_mcs(adau1977, rate, fs); if (mcs < 0) return mcs; } else { mcs = 0; } ctrl0_mask = ADAU1977_SAI_CTRL0_FS_MASK; ctrl0 = fs; if (adau1977->right_j) { switch (params_width(params)) { case 16: ctrl0 |= ADAU1977_SAI_CTRL0_FMT_RJ_16BIT; break; case 24: ctrl0 |= ADAU1977_SAI_CTRL0_FMT_RJ_24BIT; break; default: return -EINVAL; } ctrl0_mask |= ADAU1977_SAI_CTRL0_FMT_MASK; } if (adau1977->master) { switch (params_width(params)) { case 16: ctrl1 = ADAU1977_SAI_CTRL1_DATA_WIDTH_16BIT; slot_width = 16; break; case 24: case 32: ctrl1 = ADAU1977_SAI_CTRL1_DATA_WIDTH_24BIT; slot_width = 32; break; default: return -EINVAL; } /* In TDM mode there is a fixed slot width */ if (adau1977->slot_width) slot_width = adau1977->slot_width; if (slot_width == 16) ctrl1 |= ADAU1977_SAI_CTRL1_BCLKRATE_16; else ctrl1 |= ADAU1977_SAI_CTRL1_BCLKRATE_32; ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL1, ADAU1977_SAI_CTRL1_DATA_WIDTH_MASK | ADAU1977_SAI_CTRL1_BCLKRATE_MASK, ctrl1); if (ret < 0) return ret; } ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0, ctrl0_mask, ctrl0); if (ret < 0) return ret; return regmap_update_bits(adau1977->regmap, ADAU1977_REG_PLL, ADAU1977_PLL_MCS_MASK, mcs); }
static void max97236_jack_plugged(struct max97236_priv *max97236) { unsigned int status_reg[3] = {0, 0, 0}; int retries = M97236_DEFAULT_RETRIES; int test_number = 1; int force_value = 0; int count; /* Check for spurious interrupt */ if (!max97236_jacksw_active(max97236)) goto max97236_jack_plugged_30; /* Start debounce while periodically verifying jack presence */ for (count = 0; count < 24; count++) { msleep(20); if (!max97236_jacksw_active(max97236)) goto max97236_jack_plugged_30; } max97236_jack_plugged_10: if (!max97236_jacksw_active(max97236)) goto max97236_jack_plugged_30; max97236_begin_detect(max97236, test_number); count = 10; do { msleep(20); regmap_read(max97236->regmap, M97236_REG_00_STATUS1, &status_reg[0]); } while (((status_reg[0] & 0x40) != 0x40) && --count); status_reg[0] = max97236_get_detect_result(max97236); max97236_translate_detected(status_reg, &force_value); max97236_end_detect(max97236); if (status_reg[0] != 0) { regmap_write(max97236->regmap, M97236_REG_19_STATE_FORCING, force_value); regmap_update_bits(max97236->regmap, M97236_REG_19_STATE_FORCING, 0x20, 0x00); regmap_update_bits(max97236->regmap, M97236_REG_1D_ENABLE_1, M97236_SHDNN_MASK, M97236_SHDNN_MASK); } else { if (--retries) { goto max97236_jack_plugged_10; } regmap_write(max97236->regmap, M97236_REG_19_STATE_FORCING, force_value); regmap_update_bits(max97236->regmap, M97236_REG_19_STATE_FORCING, 0x20, 0x00); } max97236_jack_plugged_20: max97236_report_jack_state(max97236, status_reg); max97236_configure_for_detection(max97236, M97236_AUTO_MODE_0); if (max97236->jack_state == SND_JACK_HEADSET) #ifdef IGNORE_KEY_INT_FUNCTION_ENABLED max97236_ignore_key_ints(max97236); #else max97236->ignore_int = 1; #endif if ((max97236->jack_state == M97236_JACK_STATE_NONE) || (max97236->jack_state == M97236_JACK_STATE_UNKNOWN)) { regmap_write(max97236->regmap, M97236_REG_19_STATE_FORCING, M97236_STATE_FLOAT); } else { if (!max97236_jacksw_active(max97236)) { status_reg[0] = 0; status_reg[1] = 0; goto max97236_jack_plugged_20; } } return; max97236_jack_plugged_30: max97236_configure_for_detection(max97236, M97236_AUTO_MODE_0); }
static int adau1977_power_enable(struct adau1977 *adau1977) { unsigned int val; int ret = 0; if (adau1977->enabled) return 0; ret = regulator_enable(adau1977->avdd_reg); if (ret) return ret; if (adau1977->dvdd_reg) { ret = regulator_enable(adau1977->dvdd_reg); if (ret) goto err_disable_avdd; } if (adau1977->reset_gpio) gpiod_set_value_cansleep(adau1977->reset_gpio, 1); regcache_cache_only(adau1977->regmap, false); if (adau1977->switch_mode) adau1977->switch_mode(adau1977->dev); ret = adau1977_reset(adau1977); if (ret) goto err_disable_dvdd; ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_POWER, ADAU1977_POWER_PWUP, ADAU1977_POWER_PWUP); if (ret) goto err_disable_dvdd; ret = regcache_sync(adau1977->regmap); if (ret) goto err_disable_dvdd; /* * The PLL register is not affected by the software reset. It is * possible that the value of the register was changed to the * default value while we were in cache only mode. In this case * regcache_sync will skip over it and we have to manually sync * it. */ ret = regmap_read(adau1977->regmap, ADAU1977_REG_PLL, &val); if (ret) goto err_disable_dvdd; if (val == 0x41) { regcache_cache_bypass(adau1977->regmap, true); ret = regmap_write(adau1977->regmap, ADAU1977_REG_PLL, 0x41); if (ret) goto err_disable_dvdd; regcache_cache_bypass(adau1977->regmap, false); } adau1977->enabled = true; return ret; err_disable_dvdd: if (adau1977->dvdd_reg) regulator_disable(adau1977->dvdd_reg); err_disable_avdd: regulator_disable(adau1977->avdd_reg); return ret; }
int sec_rtc_update(struct sec_pmic_dev *sec_pmic, u8 reg, unsigned int val, unsigned int mask) { return regmap_update_bits(sec_pmic->rtc_regmap, reg, mask, val); }
static int adau1977_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, unsigned int rx_mask, int slots, int width) { struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec); unsigned int ctrl0, ctrl1, drv; unsigned int slot[4]; unsigned int i; int ret; if (slots == 0) { /* 0 = No fixed slot width */ adau1977->slot_width = 0; adau1977->max_master_fs = 192000; return regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0, ADAU1977_SAI_CTRL0_SAI_MASK, ADAU1977_SAI_CTRL0_SAI_I2S); } if (rx_mask == 0 || tx_mask != 0) return -EINVAL; drv = 0; for (i = 0; i < 4; i++) { slot[i] = __ffs(rx_mask); drv |= ADAU1977_SAI_OVERTEMP_DRV_C(i); rx_mask &= ~(1 << slot[i]); if (slot[i] >= slots) return -EINVAL; if (rx_mask == 0) break; } if (rx_mask != 0) return -EINVAL; switch (width) { case 16: ctrl1 = ADAU1977_SAI_CTRL1_SLOT_WIDTH_16; break; case 24: /* We can only generate 16 bit or 32 bit wide slots */ if (adau1977->master) return -EINVAL; ctrl1 = ADAU1977_SAI_CTRL1_SLOT_WIDTH_24; break; case 32: ctrl1 = ADAU1977_SAI_CTRL1_SLOT_WIDTH_32; break; default: return -EINVAL; } switch (slots) { case 2: ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_2; break; case 4: ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_4; break; case 8: ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_8; break; case 16: ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_16; break; default: return -EINVAL; } ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_OVERTEMP, ADAU1977_SAI_OVERTEMP_DRV_C(0) | ADAU1977_SAI_OVERTEMP_DRV_C(1) | ADAU1977_SAI_OVERTEMP_DRV_C(2) | ADAU1977_SAI_OVERTEMP_DRV_C(3), drv); if (ret) return ret; ret = regmap_write(adau1977->regmap, ADAU1977_REG_CMAP12, (slot[1] << ADAU1977_CHAN_MAP_SECOND_SLOT_OFFSET) | (slot[0] << ADAU1977_CHAN_MAP_FIRST_SLOT_OFFSET)); if (ret) return ret; ret = regmap_write(adau1977->regmap, ADAU1977_REG_CMAP34, (slot[3] << ADAU1977_CHAN_MAP_SECOND_SLOT_OFFSET) | (slot[2] << ADAU1977_CHAN_MAP_FIRST_SLOT_OFFSET)); if (ret) return ret; ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0, ADAU1977_SAI_CTRL0_SAI_MASK, ctrl0); if (ret) return ret; ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL1, ADAU1977_SAI_CTRL1_SLOT_WIDTH_MASK, ctrl1); if (ret) return ret; adau1977->slot_width = width; /* In master mode the maximum bitclock is 24.576 MHz */ adau1977->max_master_fs = min(192000, 24576000 / width / slots); return 0; }
int pcm512x_probe(struct device *dev, struct regmap *regmap) { struct pcm512x_priv *pcm512x; int i, ret; pcm512x = devm_kzalloc(dev, sizeof(struct pcm512x_priv), GFP_KERNEL); if (!pcm512x) return -ENOMEM; dev_set_drvdata(dev, pcm512x); pcm512x->regmap = regmap; for (i = 0; i < ARRAY_SIZE(pcm512x->supplies); i++) pcm512x->supplies[i].supply = pcm512x_supply_names[i]; ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(pcm512x->supplies), pcm512x->supplies); if (ret != 0) { dev_err(dev, "Failed to get supplies: %d\n", ret); return ret; } pcm512x->supply_nb[0].notifier_call = pcm512x_regulator_event_0; pcm512x->supply_nb[1].notifier_call = pcm512x_regulator_event_1; pcm512x->supply_nb[2].notifier_call = pcm512x_regulator_event_2; for (i = 0; i < ARRAY_SIZE(pcm512x->supplies); i++) { ret = regulator_register_notifier(pcm512x->supplies[i].consumer, &pcm512x->supply_nb[i]); if (ret != 0) { dev_err(dev, "Failed to register regulator notifier: %d\n", ret); } } ret = regulator_bulk_enable(ARRAY_SIZE(pcm512x->supplies), pcm512x->supplies); if (ret != 0) { dev_err(dev, "Failed to enable supplies: %d\n", ret); return ret; } /* Reset the device, verifying I/O in the process for I2C */ ret = regmap_write(regmap, PCM512x_RESET, PCM512x_RSTM | PCM512x_RSTR); if (ret != 0) { dev_err(dev, "Failed to reset device: %d\n", ret); goto err; } ret = regmap_write(regmap, PCM512x_RESET, 0); if (ret != 0) { dev_err(dev, "Failed to reset device: %d\n", ret); goto err; } pcm512x->sclk = devm_clk_get(dev, NULL); if (IS_ERR(pcm512x->sclk)) { if (PTR_ERR(pcm512x->sclk) == -EPROBE_DEFER) return -EPROBE_DEFER; dev_info(dev, "No SCLK, using BCLK: %ld\n", PTR_ERR(pcm512x->sclk)); /* Disable reporting of missing SCLK as an error */ regmap_update_bits(regmap, PCM512x_ERROR_DETECT, PCM512x_IDCH, PCM512x_IDCH); /* Switch PLL input to BCLK */ regmap_update_bits(regmap, PCM512x_PLL_REF, PCM512x_SREF, PCM512x_SREF); } else { ret = clk_prepare_enable(pcm512x->sclk); if (ret != 0) { dev_err(dev, "Failed to enable SCLK: %d\n", ret); return ret; } } /* Default to standby mode */ ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER, PCM512x_RQST, PCM512x_RQST); if (ret != 0) { dev_err(dev, "Failed to request standby: %d\n", ret); goto err_clk; } pm_runtime_set_active(dev); pm_runtime_enable(dev); pm_runtime_idle(dev); ret = snd_soc_register_codec(dev, &pcm512x_codec_driver, &pcm512x_dai, 1); if (ret != 0) { dev_err(dev, "Failed to register CODEC: %d\n", ret); goto err_pm; } return 0; err_pm: pm_runtime_disable(dev); err_clk: if (!IS_ERR(pcm512x->sclk)) clk_disable_unprepare(pcm512x->sclk); err: regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies), pcm512x->supplies); return ret; }
static int adau1977_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) { struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(dai->codec); unsigned int ctrl0 = 0, ctrl1 = 0, block_power = 0; bool invert_lrclk; int ret; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: adau1977->master = false; break; case SND_SOC_DAIFMT_CBM_CFM: ctrl1 |= ADAU1977_SAI_CTRL1_MASTER; adau1977->master = true; break; default: return -EINVAL; } switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_NB_NF: invert_lrclk = false; break; case SND_SOC_DAIFMT_IB_NF: block_power |= ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE; invert_lrclk = false; break; case SND_SOC_DAIFMT_NB_IF: invert_lrclk = true; break; case SND_SOC_DAIFMT_IB_IF: block_power |= ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE; invert_lrclk = true; break; default: return -EINVAL; } adau1977->right_j = false; switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: ctrl0 |= ADAU1977_SAI_CTRL0_FMT_I2S; break; case SND_SOC_DAIFMT_LEFT_J: ctrl0 |= ADAU1977_SAI_CTRL0_FMT_LJ; invert_lrclk = !invert_lrclk; break; case SND_SOC_DAIFMT_RIGHT_J: ctrl0 |= ADAU1977_SAI_CTRL0_FMT_RJ_24BIT; adau1977->right_j = true; invert_lrclk = !invert_lrclk; break; case SND_SOC_DAIFMT_DSP_A: ctrl1 |= ADAU1977_SAI_CTRL1_LRCLK_PULSE; ctrl0 |= ADAU1977_SAI_CTRL0_FMT_I2S; invert_lrclk = false; break; case SND_SOC_DAIFMT_DSP_B: ctrl1 |= ADAU1977_SAI_CTRL1_LRCLK_PULSE; ctrl0 |= ADAU1977_SAI_CTRL0_FMT_LJ; invert_lrclk = false; break; default: return -EINVAL; } if (invert_lrclk) block_power |= ADAU1977_BLOCK_POWER_SAI_LR_POL; ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_BLOCK_POWER_SAI, ADAU1977_BLOCK_POWER_SAI_LR_POL | ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE, block_power); if (ret) return ret; ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0, ADAU1977_SAI_CTRL0_FMT_MASK, ctrl0); if (ret) return ret; return regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL1, ADAU1977_SAI_CTRL1_MASTER | ADAU1977_SAI_CTRL1_LRCLK_PULSE, ctrl1); }
static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); unsigned int sampling_rate = params_rate(params); unsigned int data_length, data_delay, bclk_ratio; unsigned int ch1pos, ch2pos, mode, format; uint32_t csreg; /* * If a stream is already enabled, * the registers are already set properly. */ regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &csreg); if (csreg & (BCM2835_I2S_TXON | BCM2835_I2S_RXON)) return 0; /* * Adjust the data length according to the format. * We prefill the half frame length with an integer * divider of 2400 as explained at the clock settings. * Maybe it is overwritten there, if the Integer mode * does not apply. */ switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: data_length = 16; break; case SNDRV_PCM_FORMAT_S24_LE: data_length = 24; break; case SNDRV_PCM_FORMAT_S32_LE: data_length = 32; break; default: return -EINVAL; } /* If bclk_ratio already set, use that one. */ if (dev->bclk_ratio) bclk_ratio = dev->bclk_ratio; else /* otherwise calculate a fitting block ratio */ bclk_ratio = 2 * data_length; /* Clock should only be set up here if CPU is clock master */ switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: case SND_SOC_DAIFMT_CBS_CFM: clk_set_rate(dev->clk, sampling_rate * bclk_ratio); break; default: break; } /* Setup the frame format */ format = BCM2835_I2S_CHEN; if (data_length >= 24) format |= BCM2835_I2S_CHWEX; format |= BCM2835_I2S_CHWID((data_length-8)&0xf); switch (dev->fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: data_delay = 1; break; default: /* * TODO * Others are possible but are not implemented at the moment. */ dev_err(dev->dev, "%s:bad format\n", __func__); return -EINVAL; } ch1pos = data_delay; ch2pos = bclk_ratio / 2 + data_delay; switch (params_channels(params)) { case 2: format = BCM2835_I2S_CH1(format) | BCM2835_I2S_CH2(format); format |= BCM2835_I2S_CH1(BCM2835_I2S_CHPOS(ch1pos)); format |= BCM2835_I2S_CH2(BCM2835_I2S_CHPOS(ch2pos)); break; default: return -EINVAL; } /* * Set format for both streams. * We cannot set another frame length * (and therefore word length) anyway, * so the format will be the same. */ regmap_write(dev->i2s_regmap, BCM2835_I2S_RXC_A_REG, format); regmap_write(dev->i2s_regmap, BCM2835_I2S_TXC_A_REG, format); /* Setup the I2S mode */ mode = 0; if (data_length <= 16) { /* * Use frame packed mode (2 channels per 32 bit word) * We cannot set another frame length in the second stream * (and therefore word length) anyway, * so the format will be the same. */ mode |= BCM2835_I2S_FTXP | BCM2835_I2S_FRXP; } mode |= BCM2835_I2S_FLEN(bclk_ratio - 1); mode |= BCM2835_I2S_FSLEN(bclk_ratio / 2); /* Master or slave? */ switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: /* CPU is master */ break; case SND_SOC_DAIFMT_CBM_CFS: /* * CODEC is bit clock master * CPU is frame master */ mode |= BCM2835_I2S_CLKM; break; case SND_SOC_DAIFMT_CBS_CFM: /* * CODEC is frame master * CPU is bit clock master */ mode |= BCM2835_I2S_FSM; break; case SND_SOC_DAIFMT_CBM_CFM: /* CODEC is master */ mode |= BCM2835_I2S_CLKM; mode |= BCM2835_I2S_FSM; break; default: dev_err(dev->dev, "%s:bad master\n", __func__); return -EINVAL; } /* * Invert clocks? * * The BCM approach seems to be inverted to the classical I2S approach. */ switch (dev->fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_NB_NF: /* None. Therefore, both for BCM */ mode |= BCM2835_I2S_CLKI; mode |= BCM2835_I2S_FSI; break; case SND_SOC_DAIFMT_IB_IF: /* Both. Therefore, none for BCM */ break; case SND_SOC_DAIFMT_NB_IF: /* * Invert only frame sync. Therefore, * invert only bit clock for BCM */ mode |= BCM2835_I2S_CLKI; break; case SND_SOC_DAIFMT_IB_NF: /* * Invert only bit clock. Therefore, * invert only frame sync for BCM */ mode |= BCM2835_I2S_FSI; break; default: return -EINVAL; } regmap_write(dev->i2s_regmap, BCM2835_I2S_MODE_A_REG, mode); /* Setup the DMA parameters */ regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, BCM2835_I2S_RXTHR(1) | BCM2835_I2S_TXTHR(1) | BCM2835_I2S_DMAEN, 0xffffffff); regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_DREQ_A_REG, BCM2835_I2S_TX_PANIC(0x10) | BCM2835_I2S_RX_PANIC(0x30) | BCM2835_I2S_TX(0x30) | BCM2835_I2S_RX(0x20), 0xffffffff); /* Clear FIFOs */ bcm2835_i2s_clear_fifos(dev, true, true); return 0; }
int adau1977_probe(struct device *dev, struct regmap *regmap, enum adau1977_type type, void (*switch_mode)(struct device *dev)) { unsigned int power_off_mask; struct adau1977 *adau1977; int ret; if (IS_ERR(regmap)) return PTR_ERR(regmap); adau1977 = devm_kzalloc(dev, sizeof(*adau1977), GFP_KERNEL); if (adau1977 == NULL) return -ENOMEM; adau1977->dev = dev; adau1977->type = type; adau1977->regmap = regmap; adau1977->switch_mode = switch_mode; adau1977->max_master_fs = 192000; adau1977->constraints.list = adau1977_rates; adau1977->constraints.count = ARRAY_SIZE(adau1977_rates); adau1977->avdd_reg = devm_regulator_get(dev, "AVDD"); if (IS_ERR(adau1977->avdd_reg)) return PTR_ERR(adau1977->avdd_reg); adau1977->dvdd_reg = devm_regulator_get_optional(dev, "DVDD"); if (IS_ERR(adau1977->dvdd_reg)) { if (PTR_ERR(adau1977->dvdd_reg) != -ENODEV) return PTR_ERR(adau1977->dvdd_reg); adau1977->dvdd_reg = NULL; } adau1977->reset_gpio = devm_gpiod_get(dev, "reset"); if (IS_ERR(adau1977->reset_gpio)) { ret = PTR_ERR(adau1977->reset_gpio); if (ret != -ENOENT && ret != -ENOSYS) return PTR_ERR(adau1977->reset_gpio); adau1977->reset_gpio = NULL; } dev_set_drvdata(dev, adau1977); if (adau1977->reset_gpio) { ret = gpiod_direction_output(adau1977->reset_gpio, 0); if (ret) return ret; ndelay(100); } ret = adau1977_power_enable(adau1977); if (ret) return ret; if (type == ADAU1977) { ret = adau1977_setup_micbias(adau1977); if (ret) goto err_poweroff; } if (adau1977->dvdd_reg) power_off_mask = ~0; else power_off_mask = ~ADAU1977_BLOCK_POWER_SAI_LDO_EN; ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_BLOCK_POWER_SAI, power_off_mask, 0x00); if (ret) goto err_poweroff; ret = adau1977_power_disable(adau1977); if (ret) return ret; return snd_soc_register_codec(dev, &adau1977_codec_driver, &adau1977_dai, 1); err_poweroff: adau1977_power_disable(adau1977); return ret; }
static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec_dai->codec); unsigned int adc_serfmt = 0; unsigned int adc_fmt = 0; unsigned int dac_fmt = 0; /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A) */ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: adc_serfmt |= AD193X_ADC_SERFMT_TDM; break; case SND_SOC_DAIFMT_DSP_A: adc_serfmt |= AD193X_ADC_SERFMT_AUX; break; default: return -EINVAL; } switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */ break; case SND_SOC_DAIFMT_NB_IF: /* normal bclk + invert frm */ adc_fmt |= AD193X_ADC_LEFT_HIGH; dac_fmt |= AD193X_DAC_LEFT_HIGH; break; case SND_SOC_DAIFMT_IB_NF: /* invert bclk + normal frm */ adc_fmt |= AD193X_ADC_BCLK_INV; dac_fmt |= AD193X_DAC_BCLK_INV; break; case SND_SOC_DAIFMT_IB_IF: /* invert bclk + frm */ adc_fmt |= AD193X_ADC_LEFT_HIGH; adc_fmt |= AD193X_ADC_BCLK_INV; dac_fmt |= AD193X_DAC_LEFT_HIGH; dac_fmt |= AD193X_DAC_BCLK_INV; break; default: return -EINVAL; } switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & frm master */ adc_fmt |= AD193X_ADC_LCR_MASTER; adc_fmt |= AD193X_ADC_BCLK_MASTER; dac_fmt |= AD193X_DAC_LCR_MASTER; dac_fmt |= AD193X_DAC_BCLK_MASTER; break; case SND_SOC_DAIFMT_CBS_CFM: /* codec clk slave & frm master */ adc_fmt |= AD193X_ADC_LCR_MASTER; dac_fmt |= AD193X_DAC_LCR_MASTER; break; case SND_SOC_DAIFMT_CBM_CFS: /* codec clk master & frame slave */ adc_fmt |= AD193X_ADC_BCLK_MASTER; dac_fmt |= AD193X_DAC_BCLK_MASTER; break; case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & frm slave */ break; default: return -EINVAL; } regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL1, AD193X_ADC_SERFMT_MASK, adc_serfmt); regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2, AD193X_ADC_FMT_MASK, adc_fmt); regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1, AD193X_DAC_FMT_MASK, dac_fmt); return 0; }
static inline void tegra20_ac97_stop_capture(struct tegra20_ac97 *ac97) { regmap_update_bits(ac97->regmap, TEGRA20_AC97_FIFO1_SCR, TEGRA20_AC97_FIFO_SCR_REC_FULL_EN, 0); }
int twl6040_clear_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask) { return regmap_update_bits(twl6040->regmap, reg, mask, 0); }
static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec); u32 value; /* clock masters */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: /* DAI Slave */ value = 0x0; /* Codec Master */ break; case SND_SOC_DAIFMT_CBM_CFM: /* DAI Master */ value = 0x1; /* Codec Slave */ break; default: return -EINVAL; } regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL, BIT(SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD), value << SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD); /* clock inversion */ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_NB_NF: /* Normal */ value = 0x0; break; case SND_SOC_DAIFMT_IB_IF: /* Inversion */ value = 0x1; break; default: return -EINVAL; } regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL, BIT(SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV), value << SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV); regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL, BIT(SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV), value << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV); /* DAI format */ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: value = 0x0; break; case SND_SOC_DAIFMT_LEFT_J: value = 0x1; break; case SND_SOC_DAIFMT_RIGHT_J: value = 0x2; break; case SND_SOC_DAIFMT_DSP_A: case SND_SOC_DAIFMT_DSP_B: value = 0x3; break; default: return -EINVAL; } regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL, BIT(SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT), value << SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT); return 0; }