/** * If the PLL settings are in place switch the CPU core frequency to the max. value */ static int pcm038_power_init(void) { uint32_t spctl0 = get_pll_spctl10(); struct mc13xxx *mc13xxx = mc13xxx_get(); /* PLL registers already set to their final values? */ if (spctl0 == SPCTL0_VAL && readl(MX27_CCM_BASE_ADDR + MX27_MPCTL0) == MPCTL0_VAL) { console_flush(); if (mc13xxx) { mc13xxx_reg_write(mc13xxx, MC13783_REG_SWITCHERS(0), MC13783_SWX_VOLTAGE(MC13783_SWX_VOLTAGE_1_450) | MC13783_SWX_VOLTAGE_DVS(MC13783_SWX_VOLTAGE_1_450) | MC13783_SWX_VOLTAGE_STANDBY(MC13783_SWX_VOLTAGE_1_450)); mc13xxx_reg_write(mc13xxx, MC13783_REG_SWITCHERS(4), MC13783_SW1A_MODE(MC13783_SWX_MODE_NO_PULSE_SKIP) | MC13783_SW1A_MODE_STANDBY(MC13783_SWX_MODE_NO_PULSE_SKIP) | MC13783_SW1A_SOFTSTART | MC13783_SW1B_MODE(MC13783_SWX_MODE_NO_PULSE_SKIP) | MC13783_SW1B_MODE_STANDBY(MC13783_SWX_MODE_NO_PULSE_SKIP) | MC13783_SW1B_SOFTSTART | MC13783_SW_PLL_FACTOR(32)); /* Setup VMMC voltage */ if (IS_ENABLED(CONFIG_MCI_IMX)) { u32 val; mc13xxx_reg_read(mc13xxx, MC13783_REG_REG_SETTING(1), &val); /* VMMC1 = 3.00 V */ val &= ~(7 << 6); val |= 6 << 6; mc13xxx_reg_write(mc13xxx, MC13783_REG_REG_SETTING(1), val); mc13xxx_reg_read(mc13xxx, MC13783_REG_REG_MODE(1), &val); /* Enable VMMC1 */ val |= 1 << 18; mc13xxx_reg_write(mc13xxx, MC13783_REG_REG_MODE(1), val); } /* wait for required power level to run the CPU at 400 MHz */ udelay(100000); writel(CSCR_VAL_FINAL, MX27_CCM_BASE_ADDR + MX27_CSCR); writel(0x130410c3, MX27_CCM_BASE_ADDR + MX27_PCDR0); writel(0x09030911, MX27_CCM_BASE_ADDR + MX27_PCDR1); /* Clocks have changed. Notify clients */ clock_notifier_call_chain(); } else { pr_err("Failed to initialize PMIC. Will continue with low CPU speed\n"); } } /* clock gating enable */ writel(0x00050f08, MX27_SYSCTRL_BASE_ADDR + MX27_GPCR); return 0; }
static int mc13783_powermisc_rmw(struct mc13xxx_regulator_priv *priv, u32 mask, u32 val) { struct mc13xxx *mc13783 = priv->mc13xxx; int ret; u32 valread; BUG_ON(val & ~mask); ret = mc13xxx_reg_read(mc13783, MC13783_REG_POWERMISC, &valread); if (ret) return ret; /* Update the stored state for Power Gates. */ priv->powermisc_pwgt_state = (priv->powermisc_pwgt_state & ~mask) | val; priv->powermisc_pwgt_state &= MC13783_REG_POWERMISC_PWGTSPI_M; /* Construct the new register value */ valread = (valread & ~mask) | val; /* Overwrite the PWGTxEN with the stored version */ valread = (valread & ~MC13783_REG_POWERMISC_PWGTSPI_M) | priv->powermisc_pwgt_state; return mc13xxx_reg_write(mc13783, MC13783_REG_POWERMISC, valread); }
int mc13xxx_irq_ack(struct mc13xxx *mc13xxx, int irq) { unsigned int offstat = irq < 24 ? MC13XXX_IRQSTAT0 : MC13XXX_IRQSTAT1; unsigned int val = 1 << (irq < 24 ? irq : irq - 24); BUG_ON(irq < 0 || irq >= MC13XXX_NUM_IRQ); return mc13xxx_reg_write(mc13xxx, offstat, val); }
static int mc13xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) { struct mc13xxx_rtc *priv = dev_get_drvdata(dev); unsigned long s1970; unsigned seconds, days; int ret; mc13xxx_lock(priv->mc13xxx); /* */ ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, 0x1ffff); if (unlikely(ret)) goto out; ret = mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_TODA); if (unlikely(ret)) goto out; ret = rtc_tm_to_time(&alarm->time, &s1970); if (unlikely(ret)) goto out; dev_dbg(dev, "%s: o%2.s %lu\n", __func__, alarm->enabled ? "n" : "ff", s1970); ret = mc13xxx_rtc_irq_enable_unlocked(dev, alarm->enabled, MC13XXX_IRQ_TODA); if (unlikely(ret)) goto out; seconds = s1970 % 86400; days = s1970 / 86400; ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCDAYA, days); if (unlikely(ret)) goto out; ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, seconds); out: mc13xxx_unlock(priv->mc13xxx); return ret; }
static int mc13xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) { struct mc13xxx_rtc *priv = dev_get_drvdata(dev); time64_t s1970; u32 seconds, days; int ret; mc13xxx_lock(priv->mc13xxx); /* disable alarm to prevent false triggering */ ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, 0x1ffff); if (unlikely(ret)) goto out; ret = mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_TODA); if (unlikely(ret)) goto out; s1970 = rtc_tm_to_time64(&alarm->time); dev_dbg(dev, "%s: %s %lld\n", __func__, alarm->enabled ? "on" : "off", (long long)s1970); ret = mc13xxx_rtc_irq_enable_unlocked(dev, alarm->enabled, MC13XXX_IRQ_TODA); if (unlikely(ret)) goto out; days = div_s64_rem(s1970, SEC_PER_DAY, &seconds); ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCDAYA, days); if (unlikely(ret)) goto out; ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, seconds); out: mc13xxx_unlock(priv->mc13xxx); return ret; }
static int mc13783_probe(struct snd_soc_codec *codec) { struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec); /* these are the reset values */ mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_RX0, 0x25893); mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_RX1, 0x00d35A); mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_TX, 0x420000); mc13xxx_reg_write(priv->mc13xxx, MC13783_SSI_NETWORK, 0x013060); mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_CODEC, 0x180027); mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_DAC, 0x0e0004); if (priv->adc_ssi_port == MC13783_SSI1_PORT) mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_CODEC, AUDIO_SSI_SEL, 0); else mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_CODEC, AUDIO_SSI_SEL, AUDIO_SSI_SEL); if (priv->dac_ssi_port == MC13783_SSI1_PORT) mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_DAC, AUDIO_SSI_SEL, 0); else mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_DAC, AUDIO_SSI_SEL, AUDIO_SSI_SEL); return 0; }
static int mc13783_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec); int ret; mc13xxx_lock(priv->mc13xxx); ret = mc13xxx_reg_write(priv->mc13xxx, reg, value); mc13xxx_unlock(priv->mc13xxx); return ret; }
static int mc13892_sw_regulator_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, unsigned *selector) { struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); int hi, value, mask, id = rdev_get_id(rdev); u32 valread; int ret; dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", __func__, id, min_uV, max_uV); /* Find the best index */ value = mc13xxx_get_best_voltage_index(rdev, min_uV, max_uV); dev_dbg(rdev_get_dev(rdev), "%s best value: %d\n", __func__, value); if (value < 0) return value; value = mc13892_regulators[id].voltages[value]; mc13xxx_lock(priv->mc13xxx); ret = mc13xxx_reg_read(priv->mc13xxx, mc13892_regulators[id].vsel_reg, &valread); if (ret) goto err; if (value > 1375000) hi = 1; else if (value < 1100000) hi = 0; else hi = valread & MC13892_SWITCHERS0_SWxHI; if (hi) { value = (value - 1100000) / 25000; value |= MC13892_SWITCHERS0_SWxHI; } else value = (value - 600000) / 25000; mask = mc13892_regulators[id].vsel_mask | MC13892_SWITCHERS0_SWxHI; valread = (valread & ~mask) | (value << mc13892_regulators[id].vsel_shift); ret = mc13xxx_reg_write(priv->mc13xxx, mc13892_regulators[id].vsel_reg, valread); err: mc13xxx_unlock(priv->mc13xxx); return ret; }
int mc13xxx_irq_unmask(struct mc13xxx *mc13xxx, int irq) { int ret; unsigned int offmask = irq < 24 ? MC13XXX_IRQMASK0 : MC13XXX_IRQMASK1; u32 irqbit = 1 << (irq < 24 ? irq : irq - 24); u32 mask; if (irq < 0 || irq >= MC13XXX_NUM_IRQ) return -EINVAL; ret = mc13xxx_reg_read(mc13xxx, offmask, &mask); if (ret) return ret; if (!(mask & irqbit)) /* already unmasked */ return 0; return mc13xxx_reg_write(mc13xxx, offmask, mask & ~irqbit); }
/* * returns: number of handled irqs or negative error * locking: holds mc13xxx->lock */ static int mc13xxx_irq_handle(struct mc13xxx *mc13xxx, unsigned int offstat, unsigned int offmask, int baseirq) { u32 stat, mask; int ret = mc13xxx_reg_read(mc13xxx, offstat, &stat); int num_handled = 0; if (ret) return ret; ret = mc13xxx_reg_read(mc13xxx, offmask, &mask); if (ret) return ret; while (stat & ~mask) { int irq = __ffs(stat & ~mask); stat &= ~(1 << irq); if (likely(mc13xxx->irqhandler[baseirq + irq])) { irqreturn_t handled; handled = mc13xxx_irqhandler(mc13xxx, baseirq + irq); if (handled == IRQ_HANDLED) num_handled++; } else { dev_err(mc13xxx->dev, "BUG: irq %u but no handler\n", baseirq + irq); mask |= 1 << irq; ret = mc13xxx_reg_write(mc13xxx, offmask, mask); } } return num_handled; }
static int mc13783_probe(struct snd_soc_codec *codec) { struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec); int ret; ret = snd_soc_codec_set_cache_io(codec, dev_get_regmap(codec->dev->parent, NULL)); if (ret != 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; } /* these are the reset values */ mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_RX0, 0x25893); mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_RX1, 0x00d35A); mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_TX, 0x420000); mc13xxx_reg_write(priv->mc13xxx, MC13783_SSI_NETWORK, 0x013060); mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_CODEC, 0x180027); mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_DAC, 0x0e0004); if (priv->adc_ssi_port == MC13783_SSI1_PORT) mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_CODEC, AUDIO_SSI_SEL, 0); else mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_CODEC, 0, AUDIO_SSI_SEL); if (priv->dac_ssi_port == MC13783_SSI1_PORT) mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_DAC, AUDIO_SSI_SEL, 0); else mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_DAC, 0, AUDIO_SSI_SEL); return 0; }
int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode, unsigned int channel, u8 ato, bool atox, unsigned int *sample) { u32 adc0, adc1, old_adc0; int i, ret; struct mc13xxx_adcdone_data adcdone_data = { .mc13xxx = mc13xxx, }; init_completion(&adcdone_data.done); dev_dbg(mc13xxx->dev, "%s\n", __func__); mc13xxx_lock(mc13xxx); if (mc13xxx->adcflags & MC13XXX_ADC_WORKING) { ret = -EBUSY; goto out; } mc13xxx->adcflags |= MC13XXX_ADC_WORKING; mc13xxx_reg_read(mc13xxx, MC13XXX_ADC0, &old_adc0); adc0 = MC13XXX_ADC0_ADINC1 | MC13XXX_ADC0_ADINC2; adc1 = MC13XXX_ADC1_ADEN | MC13XXX_ADC1_ADTRIGIGN | MC13XXX_ADC1_ASC; if (channel > 7) adc1 |= MC13XXX_ADC1_ADSEL; switch (mode) { case MC13XXX_ADC_MODE_TS: adc0 |= MC13XXX_ADC0_ADREFEN | MC13XXX_ADC0_TSMOD0 | MC13XXX_ADC0_TSMOD1; adc1 |= 4 << MC13XXX_ADC1_CHAN1_SHIFT; break; case MC13XXX_ADC_MODE_SINGLE_CHAN: adc0 |= old_adc0 & MC13XXX_ADC0_CONFIG_MASK; adc1 |= (channel & 0x7) << MC13XXX_ADC1_CHAN0_SHIFT; adc1 |= MC13XXX_ADC1_RAND; break; case MC13XXX_ADC_MODE_MULT_CHAN: adc0 |= old_adc0 & MC13XXX_ADC0_CONFIG_MASK; adc1 |= 4 << MC13XXX_ADC1_CHAN1_SHIFT; break; default: mc13xxx_unlock(mc13xxx); return -EINVAL; } adc1 |= ato << MC13783_ADC1_ATO_SHIFT; if (atox) adc1 |= MC13783_ADC1_ATOX; dev_dbg(mc13xxx->dev, "%s: request irq\n", __func__); mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE, mc13xxx_handler_adcdone, __func__, &adcdone_data); mc13xxx_irq_ack(mc13xxx, MC13XXX_IRQ_ADCDONE); mc13xxx_reg_write(mc13xxx, MC13XXX_ADC0, adc0); mc13xxx_reg_write(mc13xxx, MC13XXX_ADC1, adc1); mc13xxx_unlock(mc13xxx); ret = wait_for_completion_interruptible_timeout(&adcdone_data.done, HZ); if (!ret) ret = -ETIMEDOUT; mc13xxx_lock(mc13xxx); mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_ADCDONE, &adcdone_data); if (ret > 0) for (i = 0; i < 4; ++i) { ret = mc13xxx_reg_read(mc13xxx, MC13XXX_ADC2, &sample[i]); if (ret) break; } if (mode == MC13XXX_ADC_MODE_TS) /* restore TSMOD */ mc13xxx_reg_write(mc13xxx, MC13XXX_ADC0, old_adc0); mc13xxx->adcflags &= ~MC13XXX_ADC_WORKING; out: mc13xxx_unlock(mc13xxx); return ret; }
static int mc13xxx_rtc_set_mmss(struct device *dev, unsigned long secs) { struct mc13xxx_rtc *priv = dev_get_drvdata(dev); unsigned int seconds, days; unsigned int alarmseconds; int ret; seconds = secs % 86400; days = secs / 86400; mc13xxx_lock(priv->mc13xxx); /* */ ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTODA, &alarmseconds); if (unlikely(ret)) goto out; if (alarmseconds < 86400) { ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, 0x1ffff); if (unlikely(ret)) goto out; } /* */ ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTOD, 0); if (unlikely(ret)) goto out; ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCDAY, days); if (unlikely(ret)) goto out; ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTOD, seconds); if (unlikely(ret)) goto out; /* */ if (alarmseconds < 86400) { ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, alarmseconds); if (unlikely(ret)) goto out; } ret = mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_RTCRST); if (unlikely(ret)) goto out; ret = mc13xxx_irq_unmask(priv->mc13xxx, MC13XXX_IRQ_RTCRST); out: priv->valid = !ret; mc13xxx_unlock(priv->mc13xxx); return ret; }
static void efikamx_power_init(struct mc13xxx *mc) { unsigned int val; /* Write needed to Power Gate 2 register */ mc13xxx_reg_read(mc, MC13892_REG_POWER_MISC, &val); val &= ~MC13892_POWER_MISC_PWGT2SPIEN; mc13xxx_reg_write(mc, MC13892_REG_POWER_MISC, val); /* Externally powered */ mc13xxx_reg_read(mc, MC13892_REG_CHARGE, &val); val |= MC13782_CHARGE_ICHRG0 | MC13782_CHARGE_ICHRG1 | MC13782_CHARGE_ICHRG2 | MC13782_CHARGE_ICHRG3 | MC13782_CHARGE_CHGAUTOB; mc13xxx_reg_write(mc, MC13892_REG_CHARGE, val); /* power up the system first */ mc13xxx_reg_write(mc, MC13892_REG_POWER_MISC, MC13892_POWER_MISC_PWUP); /* Set core voltage to 1.1V */ mc13xxx_reg_read(mc, MC13892_REG_SW_0, &val); val &= ~MC13892_SWx_SWx_VOLT_MASK; val |= MC13892_SWx_SWx_1_100V; mc13xxx_reg_write(mc, MC13892_REG_SW_0, val); /* Setup VCC (SW2) to 1.25 */ mc13xxx_reg_read(mc, MC13892_REG_SW_1, &val); val &= ~MC13892_SWx_SWx_VOLT_MASK; val |= MC13892_SWx_SWx_1_250V; mc13xxx_reg_write(mc, MC13892_REG_SW_1, val); /* Setup 1V2_DIG1 (SW3) to 1.25 */ mc13xxx_reg_read(mc, MC13892_REG_SW_2, &val); val &= ~MC13892_SWx_SWx_VOLT_MASK; val |= MC13892_SWx_SWx_1_250V; mc13xxx_reg_write(mc, MC13892_REG_SW_2, val); udelay(50); /* Set switchers in Auto in NORMAL mode & STANDBY mode */ /* Setup the switcher mode for SW1 & SW2*/ mc13xxx_reg_read(mc, MC13892_REG_SW_4, &val); val = (val & ~((MC13892_SWMODE_MASK << MC13892_SWMODE1_SHIFT) | (MC13892_SWMODE_MASK << MC13892_SWMODE2_SHIFT))); val |= (MC13892_SWMODE_AUTO_AUTO << MC13892_SWMODE1_SHIFT) | (MC13892_SWMODE_AUTO_AUTO << MC13892_SWMODE2_SHIFT); mc13xxx_reg_write(mc, MC13892_REG_SW_4, val); /* Setup the switcher mode for SW3 & SW4 */ mc13xxx_reg_read(mc, MC13892_REG_SW_5, &val); val = (val & ~((MC13892_SWMODE_MASK << MC13892_SWMODE3_SHIFT) | (MC13892_SWMODE_MASK << MC13892_SWMODE4_SHIFT))); val |= (MC13892_SWMODE_AUTO_AUTO << MC13892_SWMODE3_SHIFT) | (MC13892_SWMODE_AUTO_AUTO << MC13892_SWMODE4_SHIFT); mc13xxx_reg_write(mc, MC13892_REG_SW_5, val); /* Set VDIG to 1.8V, VGEN3 to 1.8V, VCAM to 2.6V */ mc13xxx_reg_read(mc, MC13892_REG_SETTING_0, &val); val &= ~(MC13892_SETTING_0_VCAM_MASK | MC13892_SETTING_0_VGEN3_MASK | MC13892_SETTING_0_VDIG_MASK); val |= MC13892_SETTING_0_VDIG_1_8 | MC13892_SETTING_0_VGEN3_1_8 | MC13892_SETTING_0_VCAM_2_6; mc13xxx_reg_write(mc, MC13892_REG_SETTING_0, val); /* Set VVIDEO to 2.775V, VAUDIO to 3V, VSD to 3.15V */ mc13xxx_reg_read(mc, MC13892_REG_SETTING_1, &val); val &= ~(MC13892_SETTING_1_VVIDEO_MASK | MC13892_SETTING_1_VSD_MASK | MC13892_SETTING_1_VAUDIO_MASK); val |= MC13892_SETTING_1_VSD_3_15 | MC13892_SETTING_1_VAUDIO_3_0 | MC13892_SETTING_1_VVIDEO_2_775 | MC13892_SETTING_1_VGEN1_1_2 | MC13892_SETTING_1_VGEN2_3_15; mc13xxx_reg_write(mc, MC13892_REG_SETTING_1, val); /* Enable VGEN1, VGEN2, VDIG, VPLL */ mc13xxx_reg_read(mc, MC13892_REG_MODE_0, &val); val |= MC13892_MODE_0_VGEN1EN | MC13892_MODE_0_VDIGEN | MC13892_MODE_0_VGEN2EN | MC13892_MODE_0_VPLLEN; mc13xxx_reg_write(mc, MC13892_REG_MODE_0, val); /* Configure VGEN3 and VCAM regulators to use external PNP */ val = MC13892_MODE_1_VGEN3CONFIG | MC13892_MODE_1_VCAMCONFIG; mc13xxx_reg_write(mc, MC13892_REG_MODE_1, val); udelay(200); /* Enable VGEN3, VCAM, VAUDIO, VVIDEO, VSD regulators */ val = MC13892_MODE_1_VGEN3EN | MC13892_MODE_1_VGEN3CONFIG | MC13892_MODE_1_VCAMEN | MC13892_MODE_1_VCAMCONFIG | MC13892_MODE_1_VVIDEOEN | MC13892_MODE_1_VAUDIOEN | MC13892_MODE_1_VSDEN; mc13xxx_reg_write(mc, MC13892_REG_MODE_1, val); mc13xxx_reg_read(mc, MC13892_REG_POWER_CTL2, &val); val |= MC13892_POWER_CONTROL_2_WDIRESET; mc13xxx_reg_write(mc, MC13892_REG_POWER_CTL2, val); udelay(2500); }
static int __init mc13xxx_led_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(dev); struct mc13xxx *mcdev = dev_get_drvdata(dev->parent); struct mc13xxx_led_devtype *devtype = (struct mc13xxx_led_devtype *)pdev->id_entry->driver_data; struct mc13xxx_leds *leds; int i, id, ret = -ENODATA; u32 init_led = 0; leds = devm_kzalloc(dev, sizeof(*leds), GFP_KERNEL); if (!leds) return -ENOMEM; leds->devtype = devtype; leds->master = mcdev; platform_set_drvdata(pdev, leds); if (dev->parent->of_node) { pdata = mc13xxx_led_probe_dt(pdev); if (IS_ERR(pdata)) return PTR_ERR(pdata); } else if (!pdata) return -ENODATA; leds->num_leds = pdata->num_leds; if ((leds->num_leds < 1) || (leds->num_leds > (devtype->led_max - devtype->led_min + 1))) { dev_err(dev, "Invalid LED count %d\n", leds->num_leds); return -EINVAL; } leds->led = devm_kzalloc(dev, leds->num_leds * sizeof(*leds->led), GFP_KERNEL); if (!leds->led) return -ENOMEM; for (i = 0; i < devtype->num_regs; i++) { ret = mc13xxx_reg_write(mcdev, leds->devtype->ledctrl_base + i, pdata->led_control[i]); if (ret) return ret; } for (i = 0; i < leds->num_leds; i++) { const char *name, *trig; ret = -EINVAL; id = pdata->led[i].id; name = pdata->led[i].name; trig = pdata->led[i].default_trigger; if ((id > devtype->led_max) || (id < devtype->led_min)) { dev_err(dev, "Invalid ID %i\n", id); break; } if (init_led & (1 << id)) { dev_warn(dev, "LED %i already initialized\n", id); break; } init_led |= 1 << id; leds->led[i].id = id; leds->led[i].leds = leds; leds->led[i].cdev.name = name; leds->led[i].cdev.default_trigger = trig; leds->led[i].cdev.flags = LED_CORE_SUSPENDRESUME; leds->led[i].cdev.brightness_set = mc13xxx_led_set; leds->led[i].cdev.max_brightness = mc13xxx_max_brightness(id); INIT_WORK(&leds->led[i].work, mc13xxx_led_work); ret = led_classdev_register(dev->parent, &leds->led[i].cdev); if (ret) { dev_err(dev, "Failed to register LED %i\n", id); break; } } if (ret) while (--i >= 0) { led_classdev_unregister(&leds->led[i].cdev); cancel_work_sync(&leds->led[i].work); } return ret; }
static void babbage_power_init(void) { struct mc13xxx *mc13xxx; u32 val; mc13xxx = mc13xxx_get(); if (!mc13xxx) { printf("could not get PMIC\n"); return; } /* Write needed to Power Gate 2 register */ mc13xxx_reg_read(mc13xxx, MC13892_REG_POWER_MISC, &val); val &= ~0x10000; mc13xxx_reg_write(mc13xxx, MC13892_REG_POWER_MISC, val); /* Write needed to update Charger 0 */ mc13xxx_reg_write(mc13xxx, MC13892_REG_CHARGE, 0x0023807F); /* power up the system first */ mc13xxx_reg_write(mc13xxx, MC13892_REG_POWER_MISC, 0x00200000); if (imx_silicon_revision() < IMX_CHIP_REV_3_0) { /* Set core voltage to 1.1V */ mc13xxx_reg_read(mc13xxx, MC13892_REG_SW_0, &val); val &= ~0x1f; val |= 0x14; mc13xxx_reg_write(mc13xxx, MC13892_REG_SW_0, val); /* Setup VCC (SW2) to 1.25 */ mc13xxx_reg_read(mc13xxx, MC13892_REG_SW_1, &val); val &= ~0x1f; val |= 0x1a; mc13xxx_reg_write(mc13xxx, MC13892_REG_SW_1, val); /* Setup 1V2_DIG1 (SW3) to 1.25 */ mc13xxx_reg_read(mc13xxx, MC13892_REG_SW_2, &val); val &= ~0x1f; val |= 0x1a; mc13xxx_reg_write(mc13xxx, MC13892_REG_SW_2, val); } else { /* Setup VCC (SW2) to 1.225 */ mc13xxx_reg_read(mc13xxx, MC13892_REG_SW_1, &val); val &= ~0x1f; val |= 0x19; mc13xxx_reg_write(mc13xxx, MC13892_REG_SW_1, val); /* Setup 1V2_DIG1 (SW3) to 1.2 */ mc13xxx_reg_read(mc13xxx, MC13892_REG_SW_2, &val); val &= ~0x1f; val |= 0x18; mc13xxx_reg_write(mc13xxx, MC13892_REG_SW_2, val); } if (mc13xxx_revision(mc13xxx) < MC13892_REVISION_2_0) { /* Set switchers in PWM mode for Atlas 2.0 and lower */ /* Setup the switcher mode for SW1 & SW2*/ mc13xxx_reg_read(mc13xxx, MC13892_REG_SW_4, &val); val &= ~0x3c0f; val |= 0x1405; mc13xxx_reg_write(mc13xxx, MC13892_REG_SW_4, val); /* Setup the switcher mode for SW3 & SW4 */ mc13xxx_reg_read(mc13xxx, MC13892_REG_SW_5, &val); val &= ~0xf0f; val |= 0x505; mc13xxx_reg_write(mc13xxx, MC13892_REG_SW_5, val); } else { /* Set switchers in Auto in NORMAL mode & STANDBY mode for Atlas 2.0a */ /* Setup the switcher mode for SW1 & SW2*/ mc13xxx_reg_read(mc13xxx, MC13892_REG_SW_4, &val); val &= ~0x3c0f; val |= 0x2008; mc13xxx_reg_write(mc13xxx, MC13892_REG_SW_4, val); /* Setup the switcher mode for SW3 & SW4 */ mc13xxx_reg_read(mc13xxx, MC13892_REG_SW_5, &val); val &= ~0xf0f; val |= 0x808; mc13xxx_reg_write(mc13xxx, MC13892_REG_SW_5, val); } /* Set VDIG to 1.65V, VGEN3 to 1.8V, VCAM to 2.5V */ mc13xxx_reg_read(mc13xxx, MC13892_REG_SETTING_0, &val); val &= ~0x34030; val |= 0x10020; mc13xxx_reg_write(mc13xxx, MC13892_REG_SETTING_0, val); /* Set VVIDEO to 2.775V, VAUDIO to 3V, VSD to 3.15V */ mc13xxx_reg_read(mc13xxx, MC13892_REG_SETTING_1, &val); val &= ~0x1FC; val |= 0x1F4; mc13xxx_reg_write(mc13xxx, MC13892_REG_SETTING_1, val); /* Configure VGEN3 and VCAM regulators to use external PNP */ val = 0x208; mc13xxx_reg_write(mc13xxx, MC13892_REG_MODE_1, val); udelay(200); #define GPIO_LAN8700_RESET (1 * 32 + 14) /* Reset the ethernet controller over GPIO */ gpio_direction_output(GPIO_LAN8700_RESET, 0); /* Enable VGEN3, VCAM, VAUDIO, VVIDEO, VSD regulators */ val = 0x49249; mc13xxx_reg_write(mc13xxx, MC13892_REG_MODE_1, val); udelay(200); gpio_set_value(GPIO_LAN8700_RESET, 1); mdelay(50); }
int mc13xxx_common_init(struct mc13xxx *mc13xxx, struct mc13xxx_platform_data *pdata, int irq) { int ret; u32 revision; mc13xxx_lock(mc13xxx); ret = mc13xxx_reg_read(mc13xxx, MC13XXX_REVISION, &revision); if (ret) goto err_revision; mc13xxx->variant->print_revision(mc13xxx, revision); /* mask all irqs */ ret = mc13xxx_reg_write(mc13xxx, MC13XXX_IRQMASK0, 0x00ffffff); if (ret) goto err_mask; ret = mc13xxx_reg_write(mc13xxx, MC13XXX_IRQMASK1, 0x00ffffff); if (ret) goto err_mask; ret = request_threaded_irq(irq, NULL, mc13xxx_irq_thread, IRQF_ONESHOT | IRQF_TRIGGER_HIGH, "mc13xxx", mc13xxx); if (ret) { err_mask: err_revision: mc13xxx_unlock(mc13xxx); return ret; } mc13xxx->irq = irq; mc13xxx_unlock(mc13xxx); if (mc13xxx_probe_flags_dt(mc13xxx) < 0 && pdata) mc13xxx->flags = pdata->flags; if (mc13xxx->flags & MC13XXX_USE_ADC) mc13xxx_add_subdevice(mc13xxx, "%s-adc"); if (mc13xxx->flags & MC13XXX_USE_CODEC) mc13xxx_add_subdevice_pdata(mc13xxx, "%s-codec", pdata->codec, sizeof(*pdata->codec)); if (mc13xxx->flags & MC13XXX_USE_RTC) mc13xxx_add_subdevice(mc13xxx, "%s-rtc"); if (mc13xxx->flags & MC13XXX_USE_TOUCHSCREEN) mc13xxx_add_subdevice_pdata(mc13xxx, "%s-ts", &pdata->touch, sizeof(pdata->touch)); if (pdata) { mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator", &pdata->regulators, sizeof(pdata->regulators)); mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led", pdata->leds, sizeof(*pdata->leds)); mc13xxx_add_subdevice_pdata(mc13xxx, "%s-pwrbutton", pdata->buttons, sizeof(*pdata->buttons)); } else { mc13xxx_add_subdevice(mc13xxx, "%s-regulator"); mc13xxx_add_subdevice(mc13xxx, "%s-led"); mc13xxx_add_subdevice(mc13xxx, "%s-pwrbutton"); } return 0; }
static int mc13xxx_rtc_set_mmss(struct device *dev, time64_t secs) { struct mc13xxx_rtc *priv = dev_get_drvdata(dev); unsigned int seconds, days; unsigned int alarmseconds; int ret; days = div_s64_rem(secs, SEC_PER_DAY, &seconds); mc13xxx_lock(priv->mc13xxx); /* * temporarily invalidate alarm to prevent triggering it when the day is * already updated while the time isn't yet. */ ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTODA, &alarmseconds); if (unlikely(ret)) goto out; if (alarmseconds < SEC_PER_DAY) { ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, 0x1ffff); if (unlikely(ret)) goto out; } /* * write seconds=0 to prevent a day switch between writing days * and seconds below */ ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTOD, 0); if (unlikely(ret)) goto out; ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCDAY, days); if (unlikely(ret)) goto out; ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTOD, seconds); if (unlikely(ret)) goto out; /* restore alarm */ if (alarmseconds < SEC_PER_DAY) { ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCTODA, alarmseconds); if (unlikely(ret)) goto out; } if (!priv->valid) { ret = mc13xxx_irq_ack(priv->mc13xxx, MC13XXX_IRQ_RTCRST); if (unlikely(ret)) goto out; ret = mc13xxx_irq_unmask(priv->mc13xxx, MC13XXX_IRQ_RTCRST); } out: priv->valid = !ret; mc13xxx_unlock(priv->mc13xxx); return ret; }
static int loco_late_init(void) { struct mc13xxx *mc34708; int rev; if (!of_machine_is_compatible("fsl,imx53-qsb") && !of_machine_is_compatible("fsl,imx53-qsrb")) return 0; mc34708 = mc13xxx_get(); if (mc34708) { unsigned int val; int ret; /* get the board revision from fuse */ rev = readl(MX53_IIM_BASE_ADDR + 0x878); set_board_rev(rev); printf("MCIMX53-START-R board 1.0 rev %c\n", (rev == 1) ? 'A' : 'B' ); barebox_set_hostname("loco-r"); armlinux_set_revision(loco_system_rev); /* Set VDDGP to 1.25V for 1GHz on SW1 */ mc13xxx_reg_read(mc34708, MC13892_REG_SW_0, &val); val = (val & ~SWx_VOLT_MASK_MC34708) | SWx_1_250V_MC34708; ret = mc13xxx_reg_write(mc34708, MC13892_REG_SW_0, val); if (ret) { printf("Writing to REG_SW_0 failed: %d\n", ret); return ret; } /* Set VCC as 1.30V on SW2 */ mc13xxx_reg_read(mc34708, MC13892_REG_SW_1, &val); val = (val & ~SWx_VOLT_MASK_MC34708) | SWx_1_300V_MC34708; ret = mc13xxx_reg_write(mc34708, MC13892_REG_SW_1, val); if (ret) { printf("Writing to REG_SW_1 failed: %d\n", ret); return ret; } /* Set global reset timer to 4s */ mc13xxx_reg_read(mc34708, MC13892_REG_POWER_CTL2, &val); val = (val & ~TIMER_MASK_MC34708) | TIMER_4S_MC34708; ret = mc13xxx_reg_write(mc34708, MC13892_REG_POWER_CTL2, val); if (ret) { printf("Writing to REG_POWER_CTL2 failed: %d\n", ret); return ret; } /* Set VUSBSEL and VUSBEN for USB PHY supply*/ mc13xxx_reg_read(mc34708, MC13892_REG_MODE_0, &val); val |= (VUSBSEL_MC34708 | VUSBEN_MC34708); ret = mc13xxx_reg_write(mc34708, MC13892_REG_MODE_0, val); if (ret) { printf("Writing to REG_MODE_0 failed: %d\n", ret); return ret; } /* Set SWBST to 5V in auto mode */ val = SWBST_AUTO; ret = mc13xxx_reg_write(mc34708, SWBST_CTRL, val); if (ret) { printf("Writing to SWBST_CTRL failed: %d\n", ret); return ret; } } else { /* so we have a DA9053 based board */ printf("MCIMX53-START board 1.0\n"); barebox_set_hostname("loco"); armlinux_set_revision(loco_system_rev); } /* USB PWR enable */ gpio_direction_output(MX53_LOCO_USB_PWREN, 0); gpio_set_value(MX53_LOCO_USB_PWREN, 1); loco_fec_reset(); set_silicon_rev(imx_silicon_revision()); armlinux_set_architecture(MACH_TYPE_MX53_LOCO); imx53_bbu_internal_mmc_register_handler("mmc", "/dev/mmc0", BBU_HANDLER_FLAG_DEFAULT); return 0; }
static void babbage_power_init(struct mc13xxx *mc13xxx) { u32 val; /* Write needed to Power Gate 2 register */ mc13xxx_reg_read(mc13xxx, MC13892_REG_POWER_MISC, &val); val &= ~0x10000; mc13xxx_reg_write(mc13xxx, MC13892_REG_POWER_MISC, val); /* Write needed to update Charger 0 */ mc13xxx_reg_write(mc13xxx, MC13892_REG_CHARGE, 0x0023807F); /* power up the system first */ mc13xxx_reg_write(mc13xxx, MC13892_REG_POWER_MISC, 0x00200000); if (imx_silicon_revision() < IMX_CHIP_REV_3_0) { /* Set core voltage to 1.1V */ mc13xxx_reg_read(mc13xxx, MC13892_REG_SW_0, &val); val &= ~0x1f; val |= 0x14; mc13xxx_reg_write(mc13xxx, MC13892_REG_SW_0, val); /* Setup VCC (SW2) to 1.25 */ mc13xxx_reg_read(mc13xxx, MC13892_REG_SW_1, &val); val &= ~0x1f; val |= 0x1a; mc13xxx_reg_write(mc13xxx, MC13892_REG_SW_1, val); /* Setup 1V2_DIG1 (SW3) to 1.25 */ mc13xxx_reg_read(mc13xxx, MC13892_REG_SW_2, &val); val &= ~0x1f; val |= 0x1a; mc13xxx_reg_write(mc13xxx, MC13892_REG_SW_2, val); } else { /* Setup VCC (SW2) to 1.225 */ mc13xxx_reg_read(mc13xxx, MC13892_REG_SW_1, &val); val &= ~0x1f; val |= 0x19; mc13xxx_reg_write(mc13xxx, MC13892_REG_SW_1, val); /* Setup 1V2_DIG1 (SW3) to 1.2 */ mc13xxx_reg_read(mc13xxx, MC13892_REG_SW_2, &val); val &= ~0x1f; val |= 0x18; mc13xxx_reg_write(mc13xxx, MC13892_REG_SW_2, val); } if (mc13xxx_revision(mc13xxx) < MC13892_REVISION_2_0) { /* Set switchers in PWM mode for Atlas 2.0 and lower */ /* Setup the switcher mode for SW1 & SW2*/ mc13xxx_reg_read(mc13xxx, MC13892_REG_SW_4, &val); val &= ~0x3c0f; val |= 0x1405; mc13xxx_reg_write(mc13xxx, MC13892_REG_SW_4, val); /* Setup the switcher mode for SW3 & SW4 */ mc13xxx_reg_read(mc13xxx, MC13892_REG_SW_5, &val); val &= ~0xf0f; val |= 0x505; mc13xxx_reg_write(mc13xxx, MC13892_REG_SW_5, val); } else { /* Set switchers in Auto in NORMAL mode & STANDBY mode for Atlas 2.0a */ /* Setup the switcher mode for SW1 & SW2*/ mc13xxx_reg_read(mc13xxx, MC13892_REG_SW_4, &val); val &= ~0x3c0f; val |= 0x2008; mc13xxx_reg_write(mc13xxx, MC13892_REG_SW_4, val); /* Setup the switcher mode for SW3 & SW4 */ mc13xxx_reg_read(mc13xxx, MC13892_REG_SW_5, &val); val &= ~0xf0f; val |= 0x808; mc13xxx_reg_write(mc13xxx, MC13892_REG_SW_5, val); } /* Set VDIG to 1.65V, VGEN3 to 1.8V, VCAM to 2.5V */ mc13xxx_reg_read(mc13xxx, MC13892_REG_SETTING_0, &val); val &= ~0x34030; val |= 0x10020; mc13xxx_reg_write(mc13xxx, MC13892_REG_SETTING_0, val); /* Set VVIDEO to 2.775V, VAUDIO to 3V, VSD to 3.15V */ mc13xxx_reg_read(mc13xxx, MC13892_REG_SETTING_1, &val); val &= ~0x1FC; val |= 0x1F4; mc13xxx_reg_write(mc13xxx, MC13892_REG_SETTING_1, val); /* Configure VGEN3 and VCAM regulators to use external PNP */ val = 0x208; mc13xxx_reg_write(mc13xxx, MC13892_REG_MODE_1, val); udelay(200); /* Enable VGEN3, VCAM, VAUDIO, VVIDEO, VSD regulators */ val = 0x49249; mc13xxx_reg_write(mc13xxx, MC13892_REG_MODE_1, val); udelay(200); pr_info("initialized PMIC\n"); console_flush(); imx51_init_lowlevel(800); clock_notifier_call_chain(); }