Example #1
0
static void palmas_enable_irq(struct palmas_usb *palmas_usb)
{
	palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
		PALMAS_USB_VBUS_CTRL_SET,
		PALMAS_USB_VBUS_CTRL_SET_VBUS_ACT_COMP);

	if (palmas_usb->enable_id_detection) {
		palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
			     PALMAS_USB_ID_CTRL_SET,
			     PALMAS_USB_ID_CTRL_SET_ID_ACT_COMP);

		palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
			     PALMAS_USB_ID_INT_EN_HI_SET,
			     PALMAS_USB_ID_INT_EN_HI_SET_ID_GND |
			     PALMAS_USB_ID_INT_EN_HI_SET_ID_FLOAT);
	}

	if (palmas_usb->enable_vbus_detection)
		palmas_vbus_irq_handler(palmas_usb->vbus_irq, palmas_usb);

	/* cold plug for host mode needs this delay */
	if (palmas_usb->enable_id_detection) {
		msleep(30);
		palmas_id_irq_handler(palmas_usb->id_irq, palmas_usb);
	}
}
Example #2
0
static void palmas_enable_irq(struct palmas_usb *palmas_usb)
{
	int ret;

	palmas_usb->vbus_linkstat = PALMAS_USB_STATE_INIT;
	palmas_usb->id_linkstat = PALMAS_USB_STATE_INIT;
	palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
		PALMAS_USB_VBUS_CTRL_SET,
		PALMAS_USB_VBUS_CTRL_SET_VBUS_ACT_COMP);

	palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
		PALMAS_USB_ID_CTRL_CLEAR, PALMAS_USB_ID_CTRL_SET_ID_SRC_5U);
	palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
		PALMAS_USB_ID_CTRL_SET, PALMAS_USB_ID_CTRL_SET_ID_SRC_16U |
				PALMAS_USB_ID_CTRL_SET_ID_ACT_COMP);

	if (palmas_usb->enable_vbus_detection)
		palmas_vbus_irq_handler(palmas_usb->vbus_irq, palmas_usb);

	if (palmas_usb->enable_id_detection) {
		/* Wait for the comparator to update status */
		msleep(palmas_usb->cable_debounce_time);
		ret = palmas_usb_id_state_update(palmas_usb);
		if (ret == -EAGAIN)
			schedule_delayed_work(&palmas_usb->cable_update_wq,
			    msecs_to_jiffies(palmas_usb->cable_debounce_time));
	}
}
Example #3
0
static void palmas_usb_wakeup(struct palmas *palmas, int enable)
{
	if (enable)
		palmas_write(palmas, PALMAS_USB_OTG_BASE, PALMAS_USB_WAKEUP,
			PALMAS_USB_WAKEUP_ID_WK_UP_COMP);
	else
		palmas_write(palmas, PALMAS_USB_OTG_BASE, PALMAS_USB_WAKEUP, 0);
}
Example #4
0
/*
 * GPADC lock issue in AUTO mode.
 * Impact: In AUTO mode, GPADC conversion can be locked after disabling AUTO
 *	   mode feature.
 * Details:
 *	When the AUTO mode is the only conversion mode enabled, if the AUTO
 *	mode feature is disabled with bit GPADC_AUTO_CTRL.AUTO_CONV1_EN = 0
 *	or bit GPADC_AUTO_CTRL.AUTO_CONV0_EN = 0 during a conversion, the
 *	conversion mechanism can be seen as locked meaning that all following
 *	conversion will give 0 as a result. Bit GPADC_STATUS.GPADC_AVAILABLE
 *	will stay at 0 meaning that GPADC is busy. An RT conversion can unlock
 *	the GPADC.
 *
 * Workaround(s):
 *	To avoid the lock mechanism, the workaround to follow before any stop
 *	conversion request is:
 *	Force the GPADC state machine to be ON by using the
 *		GPADC_CTRL1.GPADC_FORCE bit = 1
 *	Shutdown the GPADC AUTO conversion using
 *		GPADC_AUTO_CTRL.SHUTDOWN_CONV[01] = 0.
 *	After 100us, force the GPADC state machine to be OFF by using the
 *		GPADC_CTRL1.GPADC_FORCE bit = 0
 */
static int palmas_disable_auto_conversion(struct palmas_gpadc *adc)
{
	int ret;

	ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
			PALMAS_GPADC_CTRL1,
			PALMAS_GPADC_CTRL1_GPADC_FORCE,
			PALMAS_GPADC_CTRL1_GPADC_FORCE);
	if (ret < 0) {
		dev_err(adc->dev, "GPADC_CTRL1 update failed: %d\n", ret);
		return ret;
	}

	ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
			PALMAS_GPADC_AUTO_CTRL, 0);
	if (ret < 0) {
		dev_err(adc->dev, "AUTO_CTRL write failed: %d\n", ret);
		return ret;
	}

	udelay(100);

	ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
			PALMAS_GPADC_CTRL1,
			PALMAS_GPADC_CTRL1_GPADC_FORCE, 0);
	if (ret < 0) {
		dev_err(adc->dev, "GPADC_CTRL1 update failed: %d\n", ret);
		return ret;
	}
	return 0;
}
Example #5
0
static int palmas_gpadc_enable(struct palmas_gpadc *adc, int adc_chan,
			       int enable)
{
	unsigned int mask, val;
	int ret;

	if (enable) {
		val = (adc->extended_delay
			<< PALMAS_GPADC_RT_CTRL_EXTEND_DELAY_SHIFT);
		ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
					PALMAS_GPADC_RT_CTRL,
					PALMAS_GPADC_RT_CTRL_EXTEND_DELAY, val);
		if (ret < 0) {
			dev_err(adc->dev, "RT_CTRL update failed: %d\n", ret);
			return ret;
		}

		mask = (PALMAS_GPADC_CTRL1_CURRENT_SRC_CH0_MASK |
			PALMAS_GPADC_CTRL1_CURRENT_SRC_CH3_MASK |
			PALMAS_GPADC_CTRL1_GPADC_FORCE);
		val = (adc->ch0_current
			<< PALMAS_GPADC_CTRL1_CURRENT_SRC_CH0_SHIFT);
		val |= (adc->ch3_current
			<< PALMAS_GPADC_CTRL1_CURRENT_SRC_CH3_SHIFT);
		val |= PALMAS_GPADC_CTRL1_GPADC_FORCE;
		ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
				PALMAS_GPADC_CTRL1, mask, val);
		if (ret < 0) {
			dev_err(adc->dev,
				"Failed to update current setting: %d\n", ret);
			return ret;
		}

		mask = (PALMAS_GPADC_SW_SELECT_SW_CONV0_SEL_MASK |
			PALMAS_GPADC_SW_SELECT_SW_CONV_EN);
		val = (adc_chan | PALMAS_GPADC_SW_SELECT_SW_CONV_EN);
		ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
				PALMAS_GPADC_SW_SELECT, mask, val);
		if (ret < 0) {
			dev_err(adc->dev, "SW_SELECT update failed: %d\n", ret);
			return ret;
		}
	} else {
		ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
				PALMAS_GPADC_SW_SELECT, 0);
		if (ret < 0)
			dev_err(adc->dev, "SW_SELECT write failed: %d\n", ret);

		ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
				PALMAS_GPADC_CTRL1,
				PALMAS_GPADC_CTRL1_GPADC_FORCE, 0);
		if (ret < 0) {
			dev_err(adc->dev, "CTRL1 update failed: %d\n", ret);
			return ret;
		}
	}

	return ret;
}
Example #6
0
static int palmas_rtc_alarm_irq_enable(struct device *dev, unsigned enabled)
{
    struct palmas *palmas = dev_get_drvdata(dev->parent);
    u8 val;

    val = enabled ? PALMAS_RTC_INTERRUPTS_REG_IT_ALARM : 0;
    return palmas_write(palmas, PALMAS_RTC_BASE,
                        PALMAS_RTC_INTERRUPTS_REG, val);
}
Example #7
0
static int palmas_adc_wakeup_configure(struct palmas_gpadc *adc)
{
	int adc_period, conv;
	int i;
	int ch0 = 0, ch1 = 0;
	int thres;
	int ret;

	adc_period = adc->auto_conversion_period;
	for (i = 0; i < 16; ++i) {
		if (((1000 * (1 << i))/32) < adc_period)
			continue;
	}
	if (i > 0)
		i--;
	adc_period = i;
	ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
			PALMAS_GPADC_AUTO_CTRL,
			PALMAS_GPADC_AUTO_CTRL_COUNTER_CONV_MASK,
			adc_period);
	if (ret < 0) {
		dev_err(adc->dev, "AUTO_CTRL write failed: %d\n", ret);
		return ret;
	}

	conv = 0;
	if (adc->wakeup1_enable) {
		int is_high;

		ch0 = adc->wakeup1_data.adc_channel_number;
		conv |= PALMAS_GPADC_AUTO_CTRL_AUTO_CONV0_EN;
		if (adc->wakeup1_data.adc_high_threshold > 0) {
			thres = adc->wakeup1_data.adc_high_threshold;
			is_high = 0;
		} else {
			thres = adc->wakeup1_data.adc_low_threshold;
			is_high = BIT(7);
		}

		ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
				PALMAS_GPADC_THRES_CONV0_LSB, thres & 0xFF);
		if (ret < 0) {
			dev_err(adc->dev,
				"THRES_CONV0_LSB write failed: %d\n", ret);
			return ret;
		}

		ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
				PALMAS_GPADC_THRES_CONV0_MSB,
				((thres >> 8) & 0xF) | is_high);
		if (ret < 0) {
			dev_err(adc->dev,
				"THRES_CONV0_MSB write failed: %d\n", ret);
			return ret;
		}
	}
Example #8
0
static irqreturn_t palmas_id_irq_handler(int irq, void *_palmas_usb)
{
	unsigned int set, id_src;
	struct palmas_usb *palmas_usb = _palmas_usb;
	struct extcon_dev *edev = palmas_usb->edev;

	palmas_read(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
		PALMAS_USB_ID_INT_LATCH_SET, &set);
	palmas_read(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
		PALMAS_USB_ID_INT_SRC, &id_src);

	if ((set & PALMAS_USB_ID_INT_SRC_ID_GND) &&
				(id_src & PALMAS_USB_ID_INT_SRC_ID_GND)) {
		palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
			PALMAS_USB_ID_INT_LATCH_CLR,
			PALMAS_USB_ID_INT_EN_HI_CLR_ID_GND);
		palmas_usb->linkstat = PALMAS_USB_STATE_ID;
		extcon_set_state_sync(edev, EXTCON_USB_HOST, true);
		dev_info(palmas_usb->dev, "USB-HOST cable is attached\n");
	} else if ((set & PALMAS_USB_ID_INT_SRC_ID_FLOAT) &&
				(id_src & PALMAS_USB_ID_INT_SRC_ID_FLOAT)) {
		palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
			PALMAS_USB_ID_INT_LATCH_CLR,
			PALMAS_USB_ID_INT_EN_HI_CLR_ID_FLOAT);
		palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT;
		extcon_set_state_sync(edev, EXTCON_USB_HOST, false);
		dev_info(palmas_usb->dev, "USB-HOST cable is detached\n");
	} else if ((palmas_usb->linkstat == PALMAS_USB_STATE_ID) &&
				(!(set & PALMAS_USB_ID_INT_SRC_ID_GND))) {
		palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT;
		extcon_set_state_sync(edev, EXTCON_USB_HOST, false);
		dev_info(palmas_usb->dev, "USB-HOST cable is detached\n");
	} else if ((palmas_usb->linkstat == PALMAS_USB_STATE_DISCONNECT) &&
				(id_src & PALMAS_USB_ID_INT_SRC_ID_GND)) {
		palmas_usb->linkstat = PALMAS_USB_STATE_ID;
		extcon_set_state_sync(edev, EXTCON_USB_HOST, true);
		dev_info(palmas_usb->dev, " USB-HOST cable is attached\n");
	}

	return IRQ_HANDLED;
}
Example #9
0
static void palmas_usb_id_int_set(struct palmas_usb *palmas_usb)
{
	unsigned int all_int;

	all_int = PALMAS_USB_ID_INT_SRC_ID_GND |
			PALMAS_USB_ID_INT_SRC_ID_A |
			PALMAS_USB_ID_INT_SRC_ID_B |
			PALMAS_USB_ID_INT_SRC_ID_C |
			PALMAS_USB_ID_INT_SRC_ID_FLOAT;
	if (palmas_usb->id_linkstat == PALMAS_USB_STATE_ID_FLOAT) {
		palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
				PALMAS_USB_ID_INT_EN_HI_SET, all_int);
		palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
				PALMAS_USB_ID_INT_EN_LO_CLR, all_int);
	} else {
		palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
				PALMAS_USB_ID_INT_EN_HI_CLR, all_int);
		palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
				PALMAS_USB_ID_INT_EN_HI_SET,
				PALMAS_USB_ID_INT_SRC_ID_FLOAT);
		palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
				PALMAS_USB_ID_INT_EN_LO_CLR, all_int);
		palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
				PALMAS_USB_ID_INT_EN_LO_SET,
				all_int ^ PALMAS_USB_ID_INT_SRC_ID_FLOAT);
	}
}
Example #10
0
static irqreturn_t palmas_id_irq_handler(int irq, void *_palmas_usb)
{
	unsigned int set;
	struct palmas_usb *palmas_usb = _palmas_usb;

	palmas_read(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
		PALMAS_USB_ID_INT_LATCH_SET, &set);

	palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
		PALMAS_USB_ID_INT_LATCH_CLR, set);

	schedule_delayed_work(&palmas_usb->cable_update_wq,
			msecs_to_jiffies(palmas_usb->cable_debounce_time));
	return IRQ_HANDLED;
}
Example #11
0
static void palmas_gpio_set(struct gpio_chip *gc, unsigned offset,
			int value)
{
	struct palmas_gpio *pg = gpiochip_get_data(gc);
	struct palmas *palmas = pg->palmas;
	int ret;
	unsigned int reg;
	int gpio16 = (offset/8);

	offset %= 8;
	if (gpio16)
		reg = (value) ?
			PALMAS_GPIO_SET_DATA_OUT2 : PALMAS_GPIO_CLEAR_DATA_OUT2;
	else
		reg = (value) ?
			PALMAS_GPIO_SET_DATA_OUT : PALMAS_GPIO_CLEAR_DATA_OUT;

	ret = palmas_write(palmas, PALMAS_GPIO_BASE, reg, BIT(offset));
	if (ret < 0)
		dev_err(gc->parent, "Reg 0x%02x write failed, %d\n", reg, ret);
}
Example #12
0
static int palmas_clear_interrupts(struct device *dev)
{
    struct palmas *palmas = dev_get_drvdata(dev->parent);
    unsigned int rtc_reg;
    int ret;

    ret = palmas_read(palmas, PALMAS_RTC_BASE, PALMAS_RTC_STATUS_REG,
                      &rtc_reg);
    if (ret < 0) {
        dev_err(dev, "RTC_STATUS read failed, err = %d\n", ret);
        return ret;
    }

    ret = palmas_write(palmas, PALMAS_RTC_BASE, PALMAS_RTC_STATUS_REG,
                       rtc_reg);
    if (ret < 0) {
        dev_err(dev, "RTC_STATUS write failed, err = %d\n", ret);
        return ret;
    }
    return 0;
}
Example #13
0
static void palmas_power_off(void *drv_data)
{
	struct palmas_pm *palmas_pm = drv_data;
	struct palmas *palmas = palmas_pm->palmas;
	unsigned int val;
	int i;
	int ret;
	unsigned int vbus_line_state, ldo_short_status2;

	palmas_allow_atomic_xfer(palmas);

	if (palmas_pm->need_rtc_power_on)
		palmas_auto_power_on(palmas_pm);

	for (i = 0; i < palmas_pm->num_int_mask_regs; ++i) {
		ret = palmas_write(palmas, PALMAS_INTERRUPT_BASE,
				palmas_pm->int_mask_reg_add[i],
				palmas_pm->int_mask_val[i]);
		if (ret < 0)
			dev_err(palmas_pm->dev,
				"register 0x%02x write failed: %d\n",
				palmas_pm->int_mask_reg_add[i], ret);

		ret = palmas_read(palmas, PALMAS_INTERRUPT_BASE,
					palmas_pm->int_status_reg_add[i], &val);
		if (ret < 0)
			dev_err(palmas_pm->dev,
				"register 0x%02x read failed: %d\n",
				palmas_pm->int_status_reg_add[i], ret);
	}

	if (palmas_pm->enable_boot_up_at_vbus ||
		palmas_pm->need_usb_event_power_on) {
		ret = palmas_update_bits(palmas, PALMAS_INTERRUPT_BASE,
			PALMAS_INT3_MASK,
			PALMAS_INT3_MASK_VBUS | PALMAS_INT3_MASK_VBUS_OTG, 0);
		if (ret < 0)
			dev_err(palmas_pm->dev,
				"INT3_MASK update failed: %d\n", ret);
	}

	/* Mask all COLD RST condition */
	palmas_write(palmas, PALMAS_PMU_CONTROL_BASE,
				PALMAS_SWOFF_COLDRST, 0x0);

	dev_info(palmas_pm->dev, "Powering off the device\n");

	palmas_read(palmas, PALMAS_INTERRUPT_BASE,
		PALMAS_INT3_LINE_STATE, &vbus_line_state);

	if (palmas_pm->enable_boot_up_at_vbus &&
		(vbus_line_state & PALMAS_INT3_LINE_STATE_VBUS)) {
		dev_info(palmas_pm->dev, "VBUS found, boot on system by timer interrupt\n");
		ret = palmas_update_bits(palmas, PALMAS_RTC_BASE,
			PALMAS_RTC_INTERRUPTS_REG,
			PALMAS_RTC_INTERRUPTS_REG_IT_TIMER,
			PALMAS_RTC_INTERRUPTS_REG_IT_TIMER);
		if (ret < 0) {
			dev_err(palmas_pm->dev,
				"RTC_INTERRUPTS update failed: %d\n", ret);
			goto poweroff_direct;
		}

		ret = palmas_update_bits(palmas, PALMAS_RTC_BASE,
			PALMAS_RTC_INTERRUPTS_REG,
			PALMAS_RTC_INTERRUPTS_REG_EVERY_MASK, 0);
		if (ret < 0) {
			dev_err(palmas_pm->dev,
				"RTC_INTERRUPTS update failed: %d\n", ret);
			goto poweroff_direct;
		}

		ret = palmas_update_bits(palmas, PALMAS_RTC_BASE,
			PALMAS_RTC_CTRL_REG, PALMAS_RTC_CTRL_REG_STOP_RTC,
			PALMAS_RTC_CTRL_REG_STOP_RTC);
		if (ret < 0) {
			dev_err(palmas_pm->dev,
				"RTC_CTRL_REG update failed: %d\n", ret);
			goto poweroff_direct;
		}

		ret = palmas_update_bits(palmas, PALMAS_INTERRUPT_BASE,
			PALMAS_INT2_MASK,
			PALMAS_INT2_MASK_RTC_TIMER, 0);
		if (ret < 0) {
			dev_err(palmas_pm->dev,
				"INT2_MASK update failed: %d\n", ret);
			goto poweroff_direct;
		}
	}

poweroff_direct:
	/* Errata
	 * clear VANA short status before switch-off
	 */
	palmas_read(palmas, PALMAS_LDO_BASE, PALMAS_LDO_SHORT_STATUS2,
				&ldo_short_status2);

	/* Power off the device */
	palmas_update_bits(palmas, PALMAS_PMU_CONTROL_BASE,
				PALMAS_DEV_CTRL, 1, 0);
}
Example #14
0
static void palmas_power_reset(void *drv_data)
{
	struct palmas_pm *palmas_pm = drv_data;
	struct palmas *palmas = palmas_pm->palmas;
	unsigned int val;
	int i;
	int ret;

	palmas_allow_atomic_xfer(palmas);

	for (i = 0; i < palmas_pm->num_int_mask_regs; ++i) {
		ret = palmas_write(palmas, PALMAS_INTERRUPT_BASE,
				palmas_pm->int_mask_reg_add[i],
				palmas_pm->int_mask_val[i]);
		if (ret < 0)
			dev_err(palmas_pm->dev,
				"register 0x%02x write failed: %d\n",
				palmas_pm->int_mask_reg_add[i], ret);

		ret = palmas_read(palmas, PALMAS_INTERRUPT_BASE,
					palmas_pm->int_status_reg_add[i], &val);
		if (ret < 0)
			dev_err(palmas_pm->dev,
				"register 0x%02x read failed: %d\n",
				palmas_pm->int_status_reg_add[i], ret);
	}

	/* SW-WAR for ES Version 2.1, 2.0 and 1.0 */
	if (palmas_is_es_version_or_less(palmas, 2, 1)) {
		dev_info(palmas_pm->dev, "Resetting Palmas through RTC\n");
		ret = palmas_update_bits(palmas, PALMAS_PMU_CONTROL_BASE,
				PALMAS_DEV_CTRL, PALMAS_DEV_CTRL_SW_RST, 0);
		if (ret < 0) {
			dev_err(palmas_pm->dev,
				"DEV_CTRL update failed: %d\n", ret);
			goto reset_direct;
		}

		ret = palmas_update_bits(palmas, PALMAS_RTC_BASE,
				PALMAS_RTC_INTERRUPTS_REG,
				PALMAS_RTC_INTERRUPTS_REG_IT_TIMER,
				PALMAS_RTC_INTERRUPTS_REG_IT_TIMER);
		if (ret < 0) {
			dev_err(palmas_pm->dev,
				"RTC_INTERRUPTS update failed: %d\n", ret);
			goto reset_direct;
		}

		ret = palmas_update_bits(palmas, PALMAS_RTC_BASE,
			PALMAS_RTC_CTRL_REG, PALMAS_RTC_CTRL_REG_STOP_RTC,
			PALMAS_RTC_CTRL_REG_STOP_RTC);
		if (ret < 0) {
			dev_err(palmas_pm->dev,
				"RTC_CTRL_REG update failed: %d\n", ret);
			goto reset_direct;
		}

		ret = palmas_update_bits(palmas, PALMAS_INTERRUPT_BASE,
			PALMAS_INT2_MASK, PALMAS_INT2_MASK_RTC_TIMER, 0);
		if (ret < 0) {
			dev_err(palmas_pm->dev,
				"INT2_MASK update failed: %d\n", ret);
			goto reset_direct;
		}

		ret = palmas_update_bits(palmas, PALMAS_PMU_CONTROL_BASE,
				PALMAS_SWOFF_COLDRST, PALMAS_SWOFF_COLDRST_SW_RST,
					PALMAS_SWOFF_COLDRST_SW_RST);
		if (ret < 0) {
			dev_err(palmas_pm->dev,
				"SWOFF_COLDRST update failed: %d\n", ret);
			goto reset_direct;
		}

		ret = palmas_update_bits(palmas, PALMAS_PMU_CONTROL_BASE,
				PALMAS_DEV_CTRL, PALMAS_DEV_CTRL_SW_RST,
				PALMAS_DEV_CTRL_SW_RST);
		if (ret < 0) {
			dev_err(palmas_pm->dev,
				"DEV_CTRL update failed: %d\n", ret);
			goto reset_direct;
		}
		return;
	}

reset_direct:
	dev_info(palmas_pm->dev, "Power reset the device\n");
	palmas_update_bits(palmas, PALMAS_PMU_CONTROL_BASE,
			PALMAS_SWOFF_COLDRST, PALMAS_SWOFF_COLDRST_SW_RST,
			PALMAS_SWOFF_COLDRST_SW_RST);
	palmas_update_bits(palmas, PALMAS_PMU_CONTROL_BASE,
				PALMAS_DEV_CTRL, 0x2, 0x2);
}