int mc13xxx_irq_status(struct mc13xxx *mc13xxx, int irq, int *enabled, int *pending) { int ret; unsigned int offmask = irq < 24 ? MC13XXX_IRQMASK0 : MC13XXX_IRQMASK1; unsigned int offstat = irq < 24 ? MC13XXX_IRQSTAT0 : MC13XXX_IRQSTAT1; u32 irqbit = 1 << (irq < 24 ? irq : irq - 24); if (irq < 0 || irq >= MC13XXX_NUM_IRQ) return -EINVAL; if (enabled) { u32 mask; ret = mc13xxx_reg_read(mc13xxx, offmask, &mask); if (ret) return ret; *enabled = mask & irqbit; } if (pending) { u32 stat; ret = mc13xxx_reg_read(mc13xxx, offstat, &stat); if (ret) return ret; *pending = stat & irqbit; } return 0; }
static int mc13xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct mc13xxx_rtc *priv = dev_get_drvdata(dev); unsigned int seconds, days1, days2; if (!priv->valid) return -ENODATA; do { int ret; ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days1); if (ret) return ret; ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTOD, &seconds); if (ret) return ret; ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days2); if (ret) return ret; } while (days1 != days2); rtc_time64_to_tm((time64_t)days1 * SEC_PER_DAY + seconds, tm); return 0; }
/** * 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 mc13xxx_regulator_get_voltage(struct regulator_dev *rdev) { struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; int ret, id = rdev_get_id(rdev); unsigned int val; dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); mc13xxx_lock(priv->mc13xxx); ret = mc13xxx_reg_read(priv->mc13xxx, mc13xxx_regulators[id].vsel_reg, &val); mc13xxx_unlock(priv->mc13xxx); if (ret) return ret; val = (val & mc13xxx_regulators[id].vsel_mask) >> mc13xxx_regulators[id].vsel_shift; dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val); BUG_ON(val >= mc13xxx_regulators[id].desc.n_voltages); return rdev->desc->volt_table[val]; }
static irqreturn_t button_irq(int irq, void *_priv) { struct mc13783_pwrb *priv = _priv; int val; mc13xxx_irq_ack(priv->mc13783, irq); mc13xxx_reg_read(priv->mc13783, MC13783_REG_INTERRUPT_SENSE_1, &val); switch (irq) { case MC13783_IRQ_ONOFD1: val = val & MC13783_IRQSENSE1_ONOFD1S ? 1 : 0; if (priv->flags & MC13783_PWRB_B1_POL_INVERT) val ^= 1; input_report_key(priv->pwr, priv->keymap[0], val); break; case MC13783_IRQ_ONOFD2: val = val & MC13783_IRQSENSE1_ONOFD2S ? 1 : 0; if (priv->flags & MC13783_PWRB_B2_POL_INVERT) val ^= 1; input_report_key(priv->pwr, priv->keymap[1], val); break; case MC13783_IRQ_ONOFD3: val = val & MC13783_IRQSENSE1_ONOFD3S ? 1 : 0; if (priv->flags & MC13783_PWRB_B3_POL_INVERT) val ^= 1; input_report_key(priv->pwr, priv->keymap[2], val); break; } input_sync(priv->pwr); return IRQ_HANDLED; }
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); }
static int mc13892_sw_regulator_get_voltage(struct regulator_dev *rdev) { struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); int ret, id = rdev_get_id(rdev); unsigned int val, hi; dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); mc13xxx_lock(priv->mc13xxx); ret = mc13xxx_reg_read(priv->mc13xxx, mc13892_regulators[id].vsel_reg, &val); mc13xxx_unlock(priv->mc13xxx); if (ret) return ret; hi = val & MC13892_SWITCHERS0_SWxHI; val = (val & mc13892_regulators[id].vsel_mask) >> mc13892_regulators[id].vsel_shift; dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val); if (hi) val = (25000 * val) + 1100000; else val = (25000 * val) + 600000; return val; }
static int mc13xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct mc13xxx_rtc *priv = dev_get_drvdata(dev); unsigned int seconds, days1, days2; unsigned long s1970; int ret; mc13xxx_lock(priv->mc13xxx); if (!priv->valid) { ret = -ENODATA; goto out; } ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days1); if (unlikely(ret)) goto out; ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTOD, &seconds); if (unlikely(ret)) goto out; ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days2); out: mc13xxx_unlock(priv->mc13xxx); if (ret) return ret; if (days2 == days1 + 1) { if (seconds >= 86400 / 2) days2 = days1; else days1 = days2; } if (days1 != days2) return -EIO; s1970 = days1 * 86400 + seconds; rtc_time_to_tm(s1970, tm); return rtc_valid_tm(tm); }
static int mc13xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) { struct mc13xxx_rtc *priv = dev_get_drvdata(dev); unsigned seconds, days; unsigned long s1970; int enabled, pending; int ret; mc13xxx_lock(priv->mc13xxx); ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCTODA, &seconds); if (unlikely(ret)) goto out; if (seconds >= 86400) { ret = -ENODATA; goto out; } ret = mc13xxx_reg_read(priv->mc13xxx, MC13XXX_RTCDAY, &days); if (unlikely(ret)) goto out; ret = mc13xxx_irq_status(priv->mc13xxx, MC13XXX_IRQ_TODA, &enabled, &pending); out: mc13xxx_unlock(priv->mc13xxx); if (ret) return ret; alarm->enabled = enabled; alarm->pending = pending; s1970 = days * 86400 + seconds; rtc_time_to_tm(s1970, &alarm->time); dev_dbg(dev, "%s: %lu\n", __func__, s1970); return 0; }
static int mc13xxx_regulator_is_enabled(struct regulator_dev *rdev) { struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; int ret, id = rdev_get_id(rdev); unsigned int val; ret = mc13xxx_reg_read(priv->mc13xxx, mc13xxx_regulators[id].reg, &val); if (ret) return ret; return (val & mc13xxx_regulators[id].enable_bit) != 0; }
/* * 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 f3s_get_rev(struct mc13xxx *mc13xxx) { u32 rev; int err; err = mc13xxx_reg_read(mc13xxx, MC13XXX_REG_IDENTIFICATION, &rev); if (err) return err; if (rev == 0x00ffffff) return -ENODEV; return ((rev >> 6) & 0x7) ? MX35PDK_BOARD_REV_2 : MX35PDK_BOARD_REV_1; }
static unsigned int mc13783_read(struct snd_soc_codec *codec, unsigned int reg) { struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec); unsigned int value = 0; mc13xxx_lock(priv->mc13xxx); mc13xxx_reg_read(priv->mc13xxx, reg, &value); mc13xxx_unlock(priv->mc13xxx); return value; }
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; }
static unsigned int mc13892_vcam_get_mode(struct regulator_dev *rdev) { struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); int ret, id = rdev_get_id(rdev); unsigned int val; mc13xxx_lock(priv->mc13xxx); ret = mc13xxx_reg_read(priv->mc13xxx, mc13892_regulators[id].reg, &val); mc13xxx_unlock(priv->mc13xxx); if (ret) return ret; if (val & MC13892_REGULATORMODE1_VCAMCONFIGEN) return REGULATOR_MODE_FAST; return REGULATOR_MODE_NORMAL; }
static int mc13892_gpo_regulator_is_enabled(struct regulator_dev *rdev) { struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); int ret, id = rdev_get_id(rdev); unsigned int val; mc13xxx_lock(priv->mc13xxx); ret = mc13xxx_reg_read(priv->mc13xxx, mc13892_regulators[id].reg, &val); mc13xxx_unlock(priv->mc13xxx); if (ret) return ret; /* Power Gates state is stored in powermisc_pwgt_state * where the meaning of bits is negated */ val = (val & ~MC13892_POWERMISC_PWGTSPI_M) | (priv->powermisc_pwgt_state ^ MC13892_POWERMISC_PWGTSPI_M); return (val & mc13892_regulators[id].enable_bit) != 0; }
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); }
static int mc13892_sw_regulator_get_voltage_sel(struct regulator_dev *rdev) { struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); int ret, id = rdev_get_id(rdev); unsigned int val; dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); mc13xxx_lock(priv->mc13xxx); ret = mc13xxx_reg_read(priv->mc13xxx, mc13892_regulators[id].vsel_reg, &val); mc13xxx_unlock(priv->mc13xxx); if (ret) return ret; val = (val & mc13892_regulators[id].vsel_mask) >> mc13892_regulators[id].vsel_shift; dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val); return val; }
static int mc13892_sw_regulator_get_voltage_sel(struct regulator_dev *rdev) { struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); int ret, id = rdev_get_id(rdev); unsigned int val, selector; dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); mc13xxx_lock(priv->mc13xxx); ret = mc13xxx_reg_read(priv->mc13xxx, mc13892_regulators[id].vsel_reg, &val); mc13xxx_unlock(priv->mc13xxx); if (ret) return ret; /* * Figure out if the HI bit is set inside the switcher mode register * since this means the selector value we return is at a different * offset into the selector table. * * According to the MC13892 documentation note 59 (Table 47) the SW1 * buck switcher does not support output range programming therefore * the HI bit must always remain 0. So do not do anything strange if * our register is MC13892_SWITCHERS0. */ selector = val & mc13892_regulators[id].vsel_mask; if ((mc13892_regulators[id].vsel_reg != MC13892_SWITCHERS0) && (val & MC13892_SWITCHERS0_SWxHI)) { selector += MC13892_SWxHI_SEL_OFFSET; } dev_dbg(rdev_get_dev(rdev), "%s id: %d val: 0x%08x selector: %d\n", __func__, id, val, selector); return selector; }
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, 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 int __devinit mc13892_regulator_probe(struct platform_device *pdev) { struct mc13xxx_regulator_priv *priv; struct mc13xxx *mc13892 = dev_get_drvdata(pdev->dev.parent); struct mc13xxx_regulator_platform_data *pdata = dev_get_platdata(&pdev->dev); struct mc13xxx_regulator_init_data *init_data; int i, ret; u32 val; priv = kzalloc(sizeof(*priv) + pdata->num_regulators * sizeof(priv->regulators[0]), GFP_KERNEL); if (!priv) return -ENOMEM; priv->mc13xxx_regulators = mc13892_regulators; priv->mc13xxx = mc13892; mc13xxx_lock(mc13892); ret = mc13xxx_reg_read(mc13892, MC13892_REVISION, &val); if (ret) goto err_free; /* enable switch auto mode */ if ((val & 0x0000FFFF) == 0x45d0) { ret = mc13xxx_reg_rmw(mc13892, MC13892_SWITCHERS4, MC13892_SWITCHERS4_SW1MODE_M | MC13892_SWITCHERS4_SW2MODE_M, MC13892_SWITCHERS4_SW1MODE_AUTO | MC13892_SWITCHERS4_SW2MODE_AUTO); if (ret) goto err_free; ret = mc13xxx_reg_rmw(mc13892, MC13892_SWITCHERS5, MC13892_SWITCHERS5_SW3MODE_M | MC13892_SWITCHERS5_SW4MODE_M, MC13892_SWITCHERS5_SW3MODE_AUTO | MC13892_SWITCHERS5_SW4MODE_AUTO); if (ret) goto err_free; } mc13xxx_unlock(mc13892); pax_open_kernel(); *(void **)&mc13892_regulators[MC13892_VCAM].desc.ops->set_mode = mc13892_vcam_set_mode; *(void **)&mc13892_regulators[MC13892_VCAM].desc.ops->get_mode = mc13892_vcam_get_mode; pax_close_kernel(); for (i = 0; i < pdata->num_regulators; i++) { init_data = &pdata->regulators[i]; priv->regulators[i] = regulator_register( &mc13892_regulators[init_data->id].desc, &pdev->dev, init_data->init_data, priv); if (IS_ERR(priv->regulators[i])) { dev_err(&pdev->dev, "failed to register regulator %s\n", mc13892_regulators[i].desc.name); ret = PTR_ERR(priv->regulators[i]); goto err; } } platform_set_drvdata(pdev, priv); return 0; err: while (--i >= 0) regulator_unregister(priv->regulators[i]); err_free: mc13xxx_unlock(mc13892); kfree(priv); 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 mc13892_regulator_probe(struct platform_device *pdev) { struct mc13xxx_regulator_priv *priv; struct mc13xxx *mc13892 = dev_get_drvdata(pdev->dev.parent); struct mc13xxx_regulator_platform_data *pdata = dev_get_platdata(&pdev->dev); struct mc13xxx_regulator_init_data *mc13xxx_data; struct regulator_config config = { }; int i, ret; int num_regulators = 0; u32 val; num_regulators = mc13xxx_get_num_regulators_dt(pdev); if (num_regulators <= 0 && pdata) num_regulators = pdata->num_regulators; if (num_regulators <= 0) return -EINVAL; priv = devm_kzalloc(&pdev->dev, sizeof(*priv) + num_regulators * sizeof(priv->regulators[0]), GFP_KERNEL); if (!priv) return -ENOMEM; priv->num_regulators = num_regulators; priv->mc13xxx_regulators = mc13892_regulators; priv->mc13xxx = mc13892; platform_set_drvdata(pdev, priv); mc13xxx_lock(mc13892); ret = mc13xxx_reg_read(mc13892, MC13892_REVISION, &val); if (ret) goto err_unlock; /* enable switch auto mode (on 2.0A silicon only) */ if ((val & 0x0000FFFF) == 0x45d0) { ret = mc13xxx_reg_rmw(mc13892, MC13892_SWITCHERS4, MC13892_SWITCHERS4_SW1MODE_M | MC13892_SWITCHERS4_SW2MODE_M, MC13892_SWITCHERS4_SW1MODE_AUTO | MC13892_SWITCHERS4_SW2MODE_AUTO); if (ret) goto err_unlock; ret = mc13xxx_reg_rmw(mc13892, MC13892_SWITCHERS5, MC13892_SWITCHERS5_SW3MODE_M | MC13892_SWITCHERS5_SW4MODE_M, MC13892_SWITCHERS5_SW3MODE_AUTO | MC13892_SWITCHERS5_SW4MODE_AUTO); if (ret) goto err_unlock; } mc13xxx_unlock(mc13892); mc13892_regulators[MC13892_VCAM].desc.ops->set_mode = mc13892_vcam_set_mode; mc13892_regulators[MC13892_VCAM].desc.ops->get_mode = mc13892_vcam_get_mode; mc13xxx_data = mc13xxx_parse_regulators_dt(pdev, mc13892_regulators, ARRAY_SIZE(mc13892_regulators)); for (i = 0; i < priv->num_regulators; i++) { struct regulator_init_data *init_data; struct regulator_desc *desc; struct device_node *node = NULL; int id; if (mc13xxx_data) { id = mc13xxx_data[i].id; init_data = mc13xxx_data[i].init_data; node = mc13xxx_data[i].node; } else { id = pdata->regulators[i].id; init_data = pdata->regulators[i].init_data; } desc = &mc13892_regulators[id].desc; config.dev = &pdev->dev; config.init_data = init_data; config.driver_data = priv; config.of_node = node; priv->regulators[i] = regulator_register(desc, &config); if (IS_ERR(priv->regulators[i])) { dev_err(&pdev->dev, "failed to register regulator %s\n", mc13892_regulators[i].desc.name); ret = PTR_ERR(priv->regulators[i]); goto err; } } return 0; err: while (--i >= 0) regulator_unregister(priv->regulators[i]); return ret; err_unlock: mc13xxx_unlock(mc13892); return ret; }
int mc13xxx_common_init(struct device *dev) { struct mc13xxx_platform_data *pdata = dev_get_platdata(dev); struct mc13xxx *mc13xxx = dev_get_drvdata(dev); u32 revision; int i, ret; mc13xxx->dev = dev; ret = mc13xxx_reg_read(mc13xxx, MC13XXX_REVISION, &revision); if (ret) return ret; mc13xxx->variant->print_revision(mc13xxx, revision); ret = mc13xxx_reg_rmw(mc13xxx, MC13XXX_PWRCTRL, MC13XXX_PWRCTRL_WDIRESET, MC13XXX_PWRCTRL_WDIRESET); if (ret) return ret; for (i = 0; i < ARRAY_SIZE(mc13xxx->irqs); i++) { mc13xxx->irqs[i].reg_offset = i / MC13XXX_IRQ_PER_REG; mc13xxx->irqs[i].mask = BIT(i % MC13XXX_IRQ_PER_REG); } mc13xxx->irq_chip.name = dev_name(dev); mc13xxx->irq_chip.status_base = MC13XXX_IRQSTAT0; mc13xxx->irq_chip.mask_base = MC13XXX_IRQMASK0; mc13xxx->irq_chip.ack_base = MC13XXX_IRQSTAT0; mc13xxx->irq_chip.irq_reg_stride = MC13XXX_IRQSTAT1 - MC13XXX_IRQSTAT0; mc13xxx->irq_chip.init_ack_masked = true; mc13xxx->irq_chip.use_ack = true; mc13xxx->irq_chip.num_regs = MC13XXX_IRQ_REG_CNT; mc13xxx->irq_chip.irqs = mc13xxx->irqs; mc13xxx->irq_chip.num_irqs = ARRAY_SIZE(mc13xxx->irqs); ret = regmap_add_irq_chip(mc13xxx->regmap, mc13xxx->irq, IRQF_ONESHOT, 0, &mc13xxx->irq_chip, &mc13xxx->irq_data); if (ret) return ret; mutex_init(&mc13xxx->lock); if (mc13xxx_probe_flags_dt(mc13xxx) < 0 && pdata) mc13xxx->flags = pdata->flags; 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)); if (mc13xxx->flags & MC13XXX_USE_CODEC) mc13xxx_add_subdevice_pdata(mc13xxx, "%s-codec", pdata->codec, sizeof(*pdata->codec)); if (mc13xxx->flags & MC13XXX_USE_TOUCHSCREEN) mc13xxx_add_subdevice_pdata(mc13xxx, "%s-ts", &pdata->touch, sizeof(pdata->touch)); } else { mc13xxx_add_subdevice(mc13xxx, "%s-regulator"); mc13xxx_add_subdevice(mc13xxx, "%s-led"); mc13xxx_add_subdevice(mc13xxx, "%s-pwrbutton"); if (mc13xxx->flags & MC13XXX_USE_CODEC) mc13xxx_add_subdevice(mc13xxx, "%s-codec"); if (mc13xxx->flags & MC13XXX_USE_TOUCHSCREEN) mc13xxx_add_subdevice(mc13xxx, "%s-ts"); } if (mc13xxx->flags & MC13XXX_USE_ADC) mc13xxx_add_subdevice(mc13xxx, "%s-adc"); if (mc13xxx->flags & MC13XXX_USE_RTC) mc13xxx_add_subdevice(mc13xxx, "%s-rtc"); 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(); }
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; }
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 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(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); }