power: twl4030: Power off support
authorPaul Kocialkowski <contact@paulk.fr>
Mon, 20 Jul 2015 13:17:07 +0000 (15:17 +0200)
committerLothar Waßmann <LW@KARO-electronics.de>
Thu, 10 Sep 2015 06:24:13 +0000 (08:24 +0200)
This adds support for powering off (the omap3 SoC) from the twl4030. This is
especially useful when the kernel does not actually power off the device using
this method but reboots and leaves it up to the bootloader to actually turn the
power off.
Reviewed-by: Tom Rini <trini@konsulko.com>
Acked-by: Przemyslaw Marczak <p.marczak@samsung.com>
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
drivers/power/twl4030.c
include/twl4030.h

index 7f1fdd1..8866bf1 100644 (file)
@@ -45,6 +45,66 @@ void twl4030_power_reset_init(void)
        }
 }
 
+/*
+ * Power off
+ */
+void twl4030_power_off(void)
+{
+       u8 data;
+
+       /* PM master unlock (CFG and TST keys) */
+
+       data = 0xCE;
+       twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
+                            TWL4030_PM_MASTER_PROTECT_KEY, data);
+       data = 0xEC;
+       twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
+                            TWL4030_PM_MASTER_PROTECT_KEY, data);
+
+       /* VBAT start disable */
+
+       twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER,
+                           TWL4030_PM_MASTER_CFG_P1_TRANSITION, &data);
+       data &= ~TWL4030_PM_MASTER_CFG_TRANSITION_STARTON_VBAT;
+       twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
+                            TWL4030_PM_MASTER_CFG_P1_TRANSITION, data);
+
+       twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER,
+                           TWL4030_PM_MASTER_CFG_P2_TRANSITION, &data);
+       data &= ~TWL4030_PM_MASTER_CFG_TRANSITION_STARTON_VBAT;
+       twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
+                            TWL4030_PM_MASTER_CFG_P2_TRANSITION, data);
+
+       twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER,
+                           TWL4030_PM_MASTER_CFG_P3_TRANSITION, &data);
+       data &= ~TWL4030_PM_MASTER_CFG_TRANSITION_STARTON_VBAT;
+       twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
+                            TWL4030_PM_MASTER_CFG_P3_TRANSITION, data);
+
+       /* High jitter for PWRANA2 */
+
+       twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER,
+                           TWL4030_PM_MASTER_CFG_PWRANA2, &data);
+       data &= ~(TWL4030_PM_MASTER_CFG_PWRANA2_LOJIT0_LOWV |
+                 TWL4030_PM_MASTER_CFG_PWRANA2_LOJIT1_LOWV);
+       twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
+                            TWL4030_PM_MASTER_CFG_PWRANA2, data);
+
+       /* PM master lock */
+
+       data = 0xFF;
+       twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
+                            TWL4030_PM_MASTER_PROTECT_KEY, data);
+
+       /* Power off */
+
+       twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER,
+                           TWL4030_PM_MASTER_P1_SW_EVENTS, &data);
+       data |= TWL4030_PM_MASTER_SW_EVENTS_DEVOFF;
+       twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
+                            TWL4030_PM_MASTER_P1_SW_EVENTS, data);
+}
+
 /*
  * Set Device Group and Voltage
  */
index 50f8da8..2d0ca18 100644 (file)
 #define TWL4030_PM_MASTER_BB_CFG                       0x6D
 #define TWL4030_PM_MASTER_MISC_TST                     0x6E
 #define TWL4030_PM_MASTER_TRIM1                                0x6F
-/* P[1-3]_SW_EVENTS */
-#define TWL4030_PM_MASTER_SW_EVENTS_STOPON_PWRON       (1 << 6)
-#define TWL4030_PM_MASTER_SW_EVENTS_STOPON_SYSEN       (1 << 5)
-#define TWL4030_PM_MASTER_SW_EVENTS_ENABLE_WARMRESET   (1 << 4)
-#define TWL4030_PM_MASTER_SW_EVENTS_LVL_WAKEUP         (1 << 3)
-#define TWL4030_PM_MASTER_SW_EVENTS_DEVACT             (1 << 2)
-#define TWL4030_PM_MASTER_SW_EVENTS_DEVSLP             (1 << 1)
-#define TWL4030_PM_MASTER_SW_EVENTS_DEVOFF             (1 << 0)
 
 /* Power bus message definitions */
 
 /* Power Reference */
 #define RES_Main_Ref            28
 
+/* P[1-3]_SW_EVENTS */
+#define TWL4030_PM_MASTER_SW_EVENTS_STOPON_PWRON       (1 << 6)
+#define TWL4030_PM_MASTER_SW_EVENTS_STOPON_SYSEN       (1 << 5)
+#define TWL4030_PM_MASTER_SW_EVENTS_ENABLE_WARMRESET   (1 << 4)
+#define TWL4030_PM_MASTER_SW_EVENTS_LVL_WAKEUP         (1 << 3)
+#define TWL4030_PM_MASTER_SW_EVENTS_DEVACT             (1 << 2)
+#define TWL4030_PM_MASTER_SW_EVENTS_DEVSLP             (1 << 1)
+#define TWL4030_PM_MASTER_SW_EVENTS_DEVOFF             (1 << 0)
+
+/* Power transition */
+#define TWL4030_PM_MASTER_CFG_TRANSITION_STARTON_PWON  (1 << 0)
+#define TWL4030_PM_MASTER_CFG_TRANSITION_STARTON_CHG   (1 << 1)
+#define TWL4030_PM_MASTER_CFG_TRANSITION_STARTON_USB   (1 << 2)
+#define TWL4030_PM_MASTER_CFG_TRANSITION_STARTON_RTC   (1 << 3)
+#define TWL4030_PM_MASTER_CFG_TRANSITION_STARTON_VBAT  (1 << 4)
+#define TWL4030_PM_MASTER_CFG_TRANSITION_STARTON_VBUS  (1 << 5)
+#define TWL4030_PM_MASTER_CFG_TRANSITION_STARTON_SWBUG (1 << 7)
+
+/* PWRANA2 */
+#define TWL4030_PM_MASTER_CFG_PWRANA2_LOJIT0_LOWV      (1 << 1)
+#define TWL4030_PM_MASTER_CFG_PWRANA2_LOJIT1_LOWV      (1 << 2)
+
 #define TOTAL_RESOURCES                28
 /*
  * Power Bus Message Format ... these can be sent individually by Linux,
@@ -645,6 +659,8 @@ static inline int twl4030_i2c_read_u8(u8 chip_no, u8 reg, u8 *val)
 
 /* For hardware resetting */
 void twl4030_power_reset_init(void);
+/* For power off */
+void twl4030_power_off(void);
 /* For setting device group and voltage */
 void twl4030_pmrecv_vsel_cfg(u8 vsel_reg, u8 vsel_val,
                             u8 dev_grp, u8 dev_grp_sel);