blob: 4eac64fd0efae1e9f2d29927b747d69d2db6fbb0 [file] [log] [blame]
Deepa Dinamani22799652012-07-21 12:26:22 -07001/* Copyright (c) 2012, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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
Deepa Dinamani9a612932012-08-14 16:15:03 -070029#include <bits.h>
Deepa Dinamani22799652012-07-21 12:26:22 -070030#include <debug.h>
31#include <reg.h>
32#include <spmi.h>
33#include <pm8x41_hw.h>
Deepa Dinamani9a612932012-08-14 16:15:03 -070034#include <pm8x41.h>
35#include <platform/timer.h>
Deepa Dinamani22799652012-07-21 12:26:22 -070036
Deepa Dinamani9a612932012-08-14 16:15:03 -070037/* Local Macros */
38#define REG_READ(_a) pm8x41_reg_read(_a)
39#define REG_WRITE(_a, _v) pm8x41_reg_write(_a, _v)
40
41#define REG_OFFSET(_addr) ((_addr) & 0xFF)
42#define PERIPH_ID(_addr) (((_addr) & 0xFF00) >> 8)
43#define SLAVE_ID(_addr) ((_addr) >> 16)
44
45
46/* Local functions */
47static uint8_t pm8x41_reg_read(uint32_t addr)
48{
49 uint8_t val = 0;
50 struct pmic_arb_cmd cmd;
51 struct pmic_arb_param param;
52
53 cmd.address = PERIPH_ID(addr);
54 cmd.offset = REG_OFFSET(addr);
55 cmd.slave_id = SLAVE_ID(addr);
56 cmd.priority = 0;
57
58 param.buffer = &val;
59 param.size = 1;
60
61 pmic_arb_read_cmd(&cmd, &param);
62
63 return val;
64}
65
66static void pm8x41_reg_write(uint32_t addr, uint8_t val)
Deepa Dinamani22799652012-07-21 12:26:22 -070067{
68 struct pmic_arb_cmd cmd;
69 struct pmic_arb_param param;
Deepa Dinamani22799652012-07-21 12:26:22 -070070
Deepa Dinamani9a612932012-08-14 16:15:03 -070071 cmd.address = PERIPH_ID(addr);
72 cmd.offset = REG_OFFSET(addr);
73 cmd.slave_id = SLAVE_ID(addr);
Deepa Dinamani22799652012-07-21 12:26:22 -070074 cmd.priority = 0;
Deepa Dinamani22799652012-07-21 12:26:22 -070075
Deepa Dinamani9a612932012-08-14 16:15:03 -070076 param.buffer = &val;
77 param.size = 1;
Deepa Dinamani22799652012-07-21 12:26:22 -070078
Deepa Dinamani9a612932012-08-14 16:15:03 -070079 pmic_arb_write_cmd(&cmd, &param);
80}
Deepa Dinamani22799652012-07-21 12:26:22 -070081
Deepa Dinamani9a612932012-08-14 16:15:03 -070082/* Exported functions */
83
84/* Set the boot done flag */
85void pm8x41_set_boot_done()
86{
87 uint8_t val;
88
89 val = REG_READ(SMBB_MISC_BOOT_DONE);
90 val |= BIT(BOOT_DONE_BIT);
91 REG_WRITE(SMBB_MISC_BOOT_DONE, val);
92}
93
94/* Configure GPIO */
95int pm8x41_gpio_config(uint8_t gpio, struct pm8x41_gpio *config)
96{
97 uint8_t val;
98 uint32_t gpio_base = GPIO_N_PERIPHERAL_BASE(gpio);
99
100 /* Disable the GPIO */
101 val = REG_READ(gpio_base + GPIO_EN_CTL);
102 val &= ~BIT(PERPH_EN_BIT);
103 REG_WRITE(gpio_base + GPIO_EN_CTL, val);
104
105 /* Select the mode */
106 val = config->function | (config->direction << 4);
107 REG_WRITE(gpio_base + GPIO_MODE_CTL, val);
108
109 /* Set the right pull */
110 val = config->pull;
111 REG_WRITE(gpio_base + GPIO_DIG_PULL_CTL, val);
112
113 /* Select the VIN */
114 val = config->vin_sel;
115 REG_WRITE(gpio_base + GPIO_DIG_VIN_CTL, val);
116
117 /* Enable the GPIO */
118 val = REG_READ(gpio_base + GPIO_EN_CTL);
119 val |= BIT(PERPH_EN_BIT);
120 REG_WRITE(gpio_base + GPIO_EN_CTL, val);
121
122 return 1;
123}
124
125/* Reads the status of requested gpio */
126int pm8x41_gpio_get(uint8_t gpio, uint8_t *status)
127{
128 uint32_t gpio_base = GPIO_N_PERIPHERAL_BASE(gpio);
129
130 *status = REG_READ(gpio_base + GPIO_STATUS);
131
132 /* Return the value of the GPIO pin */
133 *status &= BIT(GPIO_STATUS_VAL_BIT);
134
135 dprintf(SPEW, "GPIO %d status is %d\n", gpio, *status);
136
137 return 1;
138}
139
140/* Prepare PON RESIN S2 reset */
141void pm8x41_vol_down_key_prepare()
142{
143 uint8_t val;
144
145 /* disable s2 reset */
146 REG_WRITE(PON_RESIN_N_RESET_S2_CTL, 0x0);
147
148 /* configure s1 timer to 0 */
149 REG_WRITE(PON_RESIN_N_RESET_S1_TIMER, 0x0);
150
151 /* configure s2 timer to 2s */
152 REG_WRITE(PON_RESIN_N_RESET_S2_TIMER, PON_RESIN_N_RESET_S2_TIMER_MAX_VALUE);
153
154 /* configure reset type */
155 REG_WRITE(PON_RESIN_N_RESET_S2_CTL, S2_RESET_TYPE_WARM);
156
157 val = REG_READ(PON_RESIN_N_RESET_S2_CTL);
158
159 /* enable s2 reset */
160 val |= BIT(S2_RESET_EN_BIT);
161 REG_WRITE(PON_RESIN_N_RESET_S2_CTL, val);
162}
163
164/* Volume_Down key detect cleanup */
165void pm8x41_vol_down_key_done()
166{
167 /* disable s2 reset */
168 REG_WRITE(PON_RESIN_N_RESET_S2_CTL, 0x0);
169}
170
171/* Volume_Down key status */
172int pm8x41_vol_down_key_status()
173{
174 uint8_t rt_sts = 0;
175
176 /* Enable S2 reset so we can detect the volume down key press */
177 pm8x41_vol_down_key_prepare();
178
179 /* Delay before interrupt triggering.
180 * See PON_DEBOUNCE_CTL reg.
181 */
182 mdelay(100);
183
184 rt_sts = REG_READ(PON_INT_RT_STS);
185
186 /* Must disable S2 reset otherwise PMIC will reset if key
187 * is held longer than S2 timer.
188 */
189 pm8x41_vol_down_key_done();
190
191 return (rt_sts & BIT(RESIN_BARK_INT_BIT));
Deepa Dinamani22799652012-07-21 12:26:22 -0700192}