blob: 1506ed85d11ca95c79a2cba34c655a70cf031b2c [file] [log] [blame]
Umang Agrawalc1fc0772017-12-19 12:06:49 +05301/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <kernel/timer.h>
30#include <qtimer.h>
31#include <bits.h>
32#include <debug.h>
33#include <smem.h>
34#include <spmi.h>
35#include <platform/iomap.h>
36#include <board.h>
37#include <target.h>
38#include <pm_vib.h>
39
40#define VIB_LDO_BASE (PMI_SECOND_SLAVE_ADDR_BASE + 0x5700)
41#define QPNP_VIB_LDO_STATUS1_REG (VIB_LDO_BASE + 0x08)
42#define QPNP_VIB_LDO_VSET_LB_REG (VIB_LDO_BASE + 0x40)
43#define QPNP_VIB_LDO_VSET_UB_REG (VIB_LDO_BASE + 0x41)
44#define QPNP_VIB_LDO_EN_CTL_REG (VIB_LDO_BASE + 0x46)
45
46#define QPNP_VIB_LDO_VSET_LB_MASK 0xFF
47#define QPNP_VIB_LDO_VSET_UB_MASK 0xFF
48#define QPNP_VIB_LDO_EN_CTL_MASK 0x80
49#define QPNP_VIB_LDO_EN 0x80
50#define QPNP_VIB_LDO_DIS 0x00
51
52#define VREG_READY BIT(7)
53
54#define MAX_WAIT_FOR_VREG_READY_US 1000
55#define VREG_READY_STEP_DELAY_US 100
Umang Agrawalb2e743e2018-04-24 17:18:50 +053056#define VIB_LDO_OVERDRIVE_VOLTAGE_MV 3500
57#define VIB_LDO_NOMINAL_VOLTAGE_MV 3000
Umang Agrawalc1fc0772017-12-19 12:06:49 +053058#define OVERDRIVE_TIME_US 30000
59
60/* Turn on vibrator */
61void pm_vib_ldo_turn_on(void)
62{
63 uint8_t status;
64 uint8_t vreg_timer_count = 0;
65
66 if (!target_is_pmi_enabled())
67 return;
68
69 /* Set overdrive voltage*/
70 pmic_spmi_reg_mask_write(QPNP_VIB_LDO_VSET_LB_REG,
71 QPNP_VIB_LDO_VSET_LB_MASK,
72 (VIB_LDO_OVERDRIVE_VOLTAGE_MV & 0xff));
73 pmic_spmi_reg_mask_write(QPNP_VIB_LDO_VSET_UB_REG,
74 QPNP_VIB_LDO_VSET_UB_MASK,
75 ((VIB_LDO_OVERDRIVE_VOLTAGE_MV >> 8) & 0xff));
76
77 /* Set Register VIB_LDO_EN_CTL to enable vibrator */
78 pmic_spmi_reg_mask_write(QPNP_VIB_LDO_EN_CTL_REG,
79 QPNP_VIB_LDO_EN_CTL_MASK,
80 QPNP_VIB_LDO_EN);
81
82 /* Wait for VREG_READY*/
83 while (1) {
84 status = pmic_spmi_reg_read(QPNP_VIB_LDO_STATUS1_REG);
85 if ( status & VREG_READY ) {
86 break;
87 }
88 else if ( vreg_timer_count < (MAX_WAIT_FOR_VREG_READY_US /
89 VREG_READY_STEP_DELAY_US) ) {
90 vreg_timer_count++;
91 udelay(VREG_READY_STEP_DELAY_US);
92 }
93 else {
94 dprintf(CRITICAL, "LDO failed to start in 1 msec, "
95 "turning off vibrator\n");
96 pm_vib_ldo_turn_off();
97 return;
98 }
99 }
100
101 udelay(OVERDRIVE_TIME_US);
102
103 /* Set normal voltage */
104 pmic_spmi_reg_mask_write(QPNP_VIB_LDO_VSET_LB_REG,
105 QPNP_VIB_LDO_VSET_LB_MASK,
106 (VIB_LDO_NOMINAL_VOLTAGE_MV & 0xff));
107 pmic_spmi_reg_mask_write(QPNP_VIB_LDO_VSET_UB_REG,
108 QPNP_VIB_LDO_VSET_UB_MASK,
109 ((VIB_LDO_NOMINAL_VOLTAGE_MV >> 8) & 0xff));
110
111 vreg_timer_count = 0;
112 /* Wait for VREG_READY*/
113 while (1) {
114 status = pmic_spmi_reg_read(QPNP_VIB_LDO_STATUS1_REG);
115 if ( status & VREG_READY ) {
116 break;
117 }
118 else if ( vreg_timer_count < (MAX_WAIT_FOR_VREG_READY_US /
119 VREG_READY_STEP_DELAY_US) ) {
120 vreg_timer_count++;
121 udelay(VREG_READY_STEP_DELAY_US);
122 }
123 else {
124 dprintf(CRITICAL, "LDO failed to start in 1 msec, "
125 "turning off vibrator\n");
126 pm_vib_ldo_turn_off();
127 return;
128 }
129 }
130
131}
132
133/* Turn off vibrator */
134void pm_vib_ldo_turn_off(void)
135{
136 if (!target_is_pmi_enabled())
137 return;
138
139 /* Clear Register VIB_LDO_EN_CTL to disable vibrator */
140 pmic_spmi_reg_mask_write(QPNP_VIB_LDO_EN_CTL_REG,
141 QPNP_VIB_LDO_EN_CTL_MASK,
142 QPNP_VIB_LDO_DIS);
143}