Esempio n. 1
0
static int mc34708_sw_get_normal_voltage(struct regulator_dev *reg)
{
	unsigned int register_val = 0;
	int voltage = 0, mV = 0;
	int id = rdev_get_id(reg);

	switch (id) {
	case MC34708_SW1A:
		CHECK_ERROR(pmic_read_reg(MC34708_REG_SW1AB,
					  &register_val, PMIC_ALL_BITS));
		voltage = BITFEXT(register_val, SW1A);
		mV = bit_value_to_uv(voltage, SW1_MIN_UV, SW1_STEP_UV) / 1000;
		break;
	case MC34708_SW1B:
		CHECK_ERROR(pmic_read_reg(MC34708_REG_SW1AB,
					  &register_val, PMIC_ALL_BITS));
		voltage = BITFEXT(register_val, SW1B);
		mV = bit_value_to_uv(voltage, SW1_MIN_UV, SW1_STEP_UV) / 1000;
		break;
	case MC34708_SW2:
		CHECK_ERROR(pmic_read_reg(MC34708_REG_SW2_3,
					  &register_val, PMIC_ALL_BITS));
		voltage = BITFEXT(register_val, SW2);
		mV = bit_value_to_uv(voltage, SW2_MIN_UV, SW2_STEP_UV) / 1000;
		break;
	case MC34708_SW3:
		CHECK_ERROR(pmic_read_reg(MC34708_REG_SW2_3,
					  &register_val, PMIC_ALL_BITS));
		voltage = BITFEXT(register_val, SW3);
		mV = bit_value_to_mv(voltage, SW3_MIN_MV, SW3_STEP_MV);
		break;
	case MC34708_SW4A:
		CHECK_ERROR(pmic_read_reg(MC34708_REG_SW4AB,
					  &register_val, PMIC_ALL_BITS));
		voltage = BITFEXT(register_val, SW4AHI);
		if (voltage == 0) {
			voltage = BITFEXT(register_val, SW4A);
			mV = bit_value_to_mv(voltage, SW4_MIN_MV, SW4_STEP_MV);
		} else if (voltage == 1)
			mV = SW4_HI_2500_MV;
		else if (voltage == 2)
			mV = SW4_HI_3150_MV;
		else
			mV = SW4_HI_3300_MV;
		break;
	case MC34708_SW4B:
		CHECK_ERROR(pmic_read_reg(MC34708_REG_SW4AB,
					  &register_val, PMIC_ALL_BITS));
		voltage = BITFEXT(register_val, SW4BHI);
		if (voltage == 0) {
			voltage = BITFEXT(register_val, SW4B);
			mV = bit_value_to_mv(voltage, SW4_MIN_MV, SW4_STEP_MV);
		} else if (voltage == 1)
			mV = SW4_HI_2500_MV;
		else if (voltage == 2)
			mV = SW4_HI_3150_MV;
		else
			mV = SW4_HI_3300_MV;
		break;
	case MC34708_SW5:
		CHECK_ERROR(pmic_read_reg(MC34708_REG_SW5,
					  &register_val, PMIC_ALL_BITS));
		voltage = BITFEXT(register_val, SW5);
		mV = bit_value_to_mv(voltage, SW5_MIN_MV, SW5_STEP_MV);
		break;
	default:
		break;
	}
	if (mV == 0)
		return -EINVAL;
	else
		return mV * 1000;
}
Esempio n. 2
0
/*!
 * This function implements IOCTL controls on a PMIC device.
 *
 * @param        inode       pointer on the node
 * @param        file        pointer on the file
 * @param        cmd         the command
 * @param        arg         the parameter
 * @return       This function returns 0 if successful.
 */
static int pmic_dev_ioctl(struct inode *inode, struct file *file,
			  unsigned int cmd, unsigned long arg)
{
	register_info reg_info;
	pmic_event_callback_t event_sub;
	type_event event = EVENT_NB;
	int ret = 0;

	if (_IOC_TYPE(cmd) != 'P')
		return -ENOTTY;

	switch (cmd) {
	case PMIC_READ_REG:
		if (copy_from_user(&reg_info, (register_info *) arg,
				   sizeof(register_info))) {
			return -EFAULT;
		}
		ret =
		    pmic_read_reg(reg_info.reg, &(reg_info.reg_value),
				  0x00ffffff);
		pr_debug("read reg %d %x\n", reg_info.reg, reg_info.reg_value);
		if (copy_to_user((register_info *) arg, &reg_info,
				 sizeof(register_info))) {
			return -EFAULT;
		}
		break;

	case PMIC_WRITE_REG:
		if (copy_from_user(&reg_info, (register_info *) arg,
				   sizeof(register_info))) {
			return -EFAULT;
		}
		ret =
		    pmic_write_reg(reg_info.reg, reg_info.reg_value,
				   0x00ffffff);
		pr_debug("write reg %d %x\n", reg_info.reg, reg_info.reg_value);
		if (copy_to_user((register_info *) arg, &reg_info,
				 sizeof(register_info))) {
			return -EFAULT;
		}
		break;

	case PMIC_SUBSCRIBE:
		if (get_user(event, (int __user *)arg)) {
			return -EFAULT;
		}
		event_sub.func = callbackfn;
		event_sub.param = (void *)event;
		ret = pmic_event_subscribe(event, event_sub);
		pr_debug("subscribe done\n");
		break;

	case PMIC_UNSUBSCRIBE:
		if (get_user(event, (int __user *)arg)) {
			return -EFAULT;
		}
		event_sub.func = callbackfn;
		event_sub.param = (void *)event;
		ret = pmic_event_unsubscribe(event, event_sub);
		pr_debug("unsubscribe done\n");
		break;

	case PMIC_NOTIFY_USER:
		if (get_user(event, (int __user *)arg)) {
			return -EFAULT;
		}
		event_sub.func = user_notify_callback;
		event_sub.param = (void *)event;
		ret = pmic_event_subscribe(event, event_sub);
		break;

	case PMIC_GET_NOTIFY:
		down(&event_mutex);
		if (CIRC_CNT(pmic_events.head, pmic_events.tail, CIRC_BUF_MAX)) {
			event = (int)pmic_events.buf[pmic_events.tail];
			pmic_events.tail = (pmic_events.tail + 1) & (CIRC_BUF_MAX - 1);
		} else {
			pr_info("No valid notified event\n");
		}
		up(&event_mutex);

		if (put_user(event, (int __user *)arg)) {
			return -EFAULT;
		}
		break;

	default:
		printk(KERN_ERR "%d unsupported ioctl command\n", (int)cmd);
		return -EINVAL;
	}

	return ret;
}
static int mc13892_regulator_init(struct mc13892 *mc13892)
{
	unsigned int value, register_mask;
	printk("Initializing regulators for Babbage.\n");
	if (mxc_cpu_is_rev(CHIP_REV_2_0) < 0)
		sw2_init.constraints.state_mem.uV = 1100000;
	else if (mxc_cpu_is_rev(CHIP_REV_2_0) == 1) {
		sw2_init.constraints.state_mem.uV = 1250000;
		sw1_init.constraints.state_mem.uV = 1000000;
	}

	/* enable standby controll for all regulators */
	pmic_read_reg(REG_MODE_0, &value, 0xffffff);
	value |= REG_MODE_0_ALL_MASK;
	pmic_write_reg(REG_MODE_0, value, 0xffffff);

	pmic_read_reg(REG_MODE_1, &value, 0xffffff);
	value |= REG_MODE_1_ALL_MASK;
	pmic_write_reg(REG_MODE_1, value, 0xffffff);

	/* enable switch audo mode */
	pmic_read_reg(REG_IDENTIFICATION, &value, 0xffffff);
	/* only for mc13892 2.0A */
	if ((value & 0x0000FFFF) == 0x45d0) {
		pmic_read_reg(REG_SW_4, &value, 0xffffff);
		register_mask = (SWMODE_MASK << SW1MODE_LSB) |
		       (SWMODE_MASK << SW2MODE_LSB);
		value &= ~register_mask;
		value |= (SWMODE_AUTO << SW1MODE_LSB) |
			(SWMODE_AUTO << SW2MODE_LSB);
		pmic_write_reg(REG_SW_4, value, 0xffffff);

		pmic_read_reg(REG_SW_5, &value, 0xffffff);
		register_mask = (SWMODE_MASK << SW3MODE_LSB) |
			(SWMODE_MASK << SW4MODE_LSB);
		value &= ~register_mask;
		value |= (SWMODE_AUTO << SW3MODE_LSB) |
			(SWMODE_AUTO << SW4MODE_LSB);
		pmic_write_reg(REG_SW_5, value, 0xffffff);
	}

	/* Enable coin cell charger */
	value = BITFVAL(COINCHEN, 1) | BITFVAL(VCOIN, VCOIN_3_0V);
	register_mask = BITFMASK(COINCHEN) | BITFMASK(VCOIN);
	pmic_write_reg(REG_POWER_CTL0, value, register_mask);

#if defined(CONFIG_RTC_DRV_MXC_V2) || defined(CONFIG_RTC_DRV_MXC_V2_MODULE)
	value = BITFVAL(DRM, 1);
	register_mask = BITFMASK(DRM);
	pmic_write_reg(REG_POWER_CTL0, value, register_mask);
#endif

	mc13892_register_regulator(mc13892, MC13892_SW1, &sw1_init);
	mc13892_register_regulator(mc13892, MC13892_SW2, &sw2_init);
	mc13892_register_regulator(mc13892, MC13892_SW3, &sw3_init);
	mc13892_register_regulator(mc13892, MC13892_SW4, &sw4_init);
	mc13892_register_regulator(mc13892, MC13892_SWBST, &swbst_init);
	mc13892_register_regulator(mc13892, MC13892_VIOHI, &viohi_init);
	mc13892_register_regulator(mc13892, MC13892_VPLL, &vpll_init);
	mc13892_register_regulator(mc13892, MC13892_VDIG, &vdig_init);
	mc13892_register_regulator(mc13892, MC13892_VSD, &vsd_init);
	mc13892_register_regulator(mc13892, MC13892_VUSB2, &vusb2_init);
	mc13892_register_regulator(mc13892, MC13892_VVIDEO, &vvideo_init);
	mc13892_register_regulator(mc13892, MC13892_VAUDIO, &vaudio_init);
	mc13892_register_regulator(mc13892, MC13892_VCAM, &vcam_init);
	mc13892_register_regulator(mc13892, MC13892_VGEN1, &vgen1_init);
	mc13892_register_regulator(mc13892, MC13892_VGEN2, &vgen2_init);
	mc13892_register_regulator(mc13892, MC13892_VGEN3, &vgen3_init);
	mc13892_register_regulator(mc13892, MC13892_VUSB, &vusb_init);
	mc13892_register_regulator(mc13892, MC13892_GPO1, &gpo1_init);
	mc13892_register_regulator(mc13892, MC13892_GPO2, &gpo2_init);
	mc13892_register_regulator(mc13892, MC13892_GPO3, &gpo3_init);
	mc13892_register_regulator(mc13892, MC13892_GPO4, &gpo4_init);

	regulator_has_full_constraints();

	return 0;
}
Esempio n. 4
0
static int mc13892_charger_update_status(struct mc13892_dev_info *di)
{
	int ret;
#ifndef CONFIG_MACH_MX51_ERDOS
	unsigned int value;
#endif /* CONFIG_MACH_MX51_ERDOS */
	int online;

#ifdef CONFIG_MACH_MX51_ERDOS
	ret = pmic_get_dcinput_voltage ((unsigned short *)0);
	if (ret == 0) {
		online = 1;
	} else if (ret == 1) {
		online = 0;
	} else {
		online = di->charger_online;	/* keep previous */
	}
	ret = 0;
		/*
	 * Battery/DCinput update
		 */
		if (online == 1) {
			gpio_battery_enable ( 0 );
	} else if (online == 0) {
			gpio_battery_enable ( 1 );
		}
	if (online != di->charger_online) {
		di->charger_online = online;
		/*
		 * check power_supply_register.
		 */
		if (di->charger.dev != 0) {
		dev_info(di->charger.dev, "charger status: %s\n",
			online ? "online" : "offline");
		power_supply_changed(&di->charger);
		} else {
			printk ("mc13892_charger_update_status: charger status: %s\n",
				online ? "online" : "offline");
		}
	}
#else
	ret = pmic_read_reg(REG_INT_SENSE0, &value, BITFMASK(BIT_CHG_DETS));

	if (ret == 0) {
		online = BITFEXT(value, BIT_CHG_DETS);
		if (online != di->charger_online) {
			di->charger_online = online;
			dev_info(di->charger.dev, "charger status: %s\n",
				online ? "online" : "offline");
			power_supply_changed(&di->charger);

			cancel_delayed_work(&di->monitor_work);
			queue_delayed_work(di->monitor_wqueue,
				&di->monitor_work, HZ / 10);
			if (online) {
				pmic_start_coulomb_counter();
				pmic_restart_charging();
			} else
				pmic_stop_coulomb_counter();
		}
	}
#endif /* CONFIG_MACH_MX51_ERDOS */

	return ret;
}