/*! * This function is the work handler of mcu interrupt. * It reads the events status and trigger the pseudo irq. */ static void mcu_event_handler(struct work_struct *work) { int i, err; unsigned int flag1, flag2; /* read int flags and ack int */ for (i = 0; i < 3; i++) { err = mcu_pmic_read_reg(REG_MCU_INT_FLAG_1, &flag1, 0xFFFFFFFF); err |= mcu_pmic_read_reg(REG_MCU_INT_FLAG_2, &flag2, 0xFFFFFFFF); err |= mcu_pmic_write_reg(REG_MCU_INT_FLAG_1, 0, 0xFFFFFFFF); err |= mcu_pmic_write_reg(REG_MCU_INT_FLAG_2, 0, 0xFFFFFFFF); if (err == 0) break; } if (i >= 3) { printk(KERN_ERR "Reads MCU event fail\n"); goto no_new_events; } for (i = 0; flag1 && (i < MCU_INT_RTC); i++, flag1 >>= 1) if (flag1 & 1) set_bit(i, &pseudo_irq_pending); for (i = MCU_INT_RTC; flag2 && (i <= MCU_INT_KEYPAD); i++, flag2 >>= 1) if (flag2 & 1) set_bit(i, &pseudo_irq_pending); no_new_events: if (pseudo_irq_pending & pseudo_irq_enable) mxc_pseudo_irq_trigger(); enable_irq(gpio_to_irq(0)); }
static void mcu_state_handler(struct work_struct *work) { int err, i; unsigned int event1, event2; event1 = pseudo_irq_enable & ((1 << MCU_INT_RTC) - 1); event2 = pseudo_irq_enable >> MCU_INT_RTC; if (is_suspend_ops_started()) return; for (i = 0; i < 3; i++) { err = mcu_pmic_write_reg(REG_MCU_INT_ENABLE_1, event1, 0xFF); err |= mcu_pmic_write_reg(REG_MCU_INT_ENABLE_2, event2, 0xFF); if (err == 0) break; } if (i >= 3) printk(KERN_ERR "Change MCU event mask fail\n"); }
static int mxc_pseudo_irq_suspend(struct platform_device *dev, pm_message_t mesg) { int err, i; unsigned int event1, event2; if (!pseudo_irq_wakeup) return 0; event1 = pseudo_irq_wakeup & ((1 << MCU_INT_RTC) - 1); event2 = pseudo_irq_wakeup >> MCU_INT_RTC; for (i = 0; i < 3; i++) { err = mcu_pmic_write_reg(REG_MCU_INT_ENABLE_1, event1, 0xFF); err |= mcu_pmic_write_reg(REG_MCU_INT_ENABLE_2, event2, 0xFF); if (err == 0) break; } pseudo_suspend = 1; return err; }
int pmic_gpio_set_bit_val(int reg, unsigned int bit, unsigned int val) { int reg_name; u8 reg_mask = 0; if (bit > 7) return -1; switch (reg) { case MCU_GPIO_REG_RESET_1: reg_name = REG_MCU_RESET_1; break; case MCU_GPIO_REG_RESET_2: reg_name = REG_MCU_RESET_2; break; case MCU_GPIO_REG_POWER_CONTROL: reg_name = REG_MCU_POWER_CTL; break; case MCU_GPIO_REG_GPIO_CONTROL_1: reg_name = REG_MCU_GPIO_1; break; case MCU_GPIO_REG_GPIO_CONTROL_2: reg_name = REG_MCU_GPIO_2; break; default: return -1; } SET_BIT_IN_BYTE(reg_mask, bit); if (0 == val) CHECK_ERROR(mcu_pmic_write_reg(reg_name, 0, reg_mask)); else CHECK_ERROR(mcu_pmic_write_reg(reg_name, reg_mask, reg_mask)); return 0; }
/*! * make max8660 - mc9s08dz60 enter low-power mode */ static void pmic_power_off(void) { mcu_pmic_write_reg(REG_MCU_POWER_CTL, 0x10, 0x10); }