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, ®ister_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, ®ister_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, ®ister_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, ®ister_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, ®ister_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, ®ister_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, ®ister_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; }
/*! * 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(®_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, ®_info, sizeof(register_info))) { return -EFAULT; } break; case PMIC_WRITE_REG: if (copy_from_user(®_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, ®_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; }
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; }