1*49a45ad9SMatthias Ringwald /*******************************************************************************
2*49a45ad9SMatthias Ringwald * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
3*49a45ad9SMatthias Ringwald *
4*49a45ad9SMatthias Ringwald * Permission is hereby granted, free of charge, to any person obtaining a
5*49a45ad9SMatthias Ringwald * copy of this software and associated documentation files (the "Software"),
6*49a45ad9SMatthias Ringwald * to deal in the Software without restriction, including without limitation
7*49a45ad9SMatthias Ringwald * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*49a45ad9SMatthias Ringwald * and/or sell copies of the Software, and to permit persons to whom the
9*49a45ad9SMatthias Ringwald * Software is furnished to do so, subject to the following conditions:
10*49a45ad9SMatthias Ringwald *
11*49a45ad9SMatthias Ringwald * The above copyright notice and this permission notice shall be included
12*49a45ad9SMatthias Ringwald * in all copies or substantial portions of the Software.
13*49a45ad9SMatthias Ringwald *
14*49a45ad9SMatthias Ringwald * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15*49a45ad9SMatthias Ringwald * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16*49a45ad9SMatthias Ringwald * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17*49a45ad9SMatthias Ringwald * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
18*49a45ad9SMatthias Ringwald * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19*49a45ad9SMatthias Ringwald * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20*49a45ad9SMatthias Ringwald * OTHER DEALINGS IN THE SOFTWARE.
21*49a45ad9SMatthias Ringwald *
22*49a45ad9SMatthias Ringwald * Except as contained in this notice, the name of Maxim Integrated
23*49a45ad9SMatthias Ringwald * Products, Inc. shall not be used except as stated in the Maxim Integrated
24*49a45ad9SMatthias Ringwald * Products, Inc. Branding Policy.
25*49a45ad9SMatthias Ringwald *
26*49a45ad9SMatthias Ringwald * The mere transfer of this software does not imply any licenses
27*49a45ad9SMatthias Ringwald * of trade secrets, proprietary technology, copyrights, patents,
28*49a45ad9SMatthias Ringwald * trademarks, maskwork rights, or any other form of intellectual
29*49a45ad9SMatthias Ringwald * property whatsoever. Maxim Integrated Products, Inc. retains all
30*49a45ad9SMatthias Ringwald * ownership rights.
31*49a45ad9SMatthias Ringwald *
32*49a45ad9SMatthias Ringwald * $Date: 2016-03-11 10:46:37 -0700 (Fri, 11 Mar 2016) $
33*49a45ad9SMatthias Ringwald * $Revision: 21839 $
34*49a45ad9SMatthias Ringwald *
35*49a45ad9SMatthias Ringwald ******************************************************************************/
36*49a45ad9SMatthias Ringwald
37*49a45ad9SMatthias Ringwald /***** Includes *****/
38*49a45ad9SMatthias Ringwald #include <stddef.h>
39*49a45ad9SMatthias Ringwald #include "mxc_config.h"
40*49a45ad9SMatthias Ringwald #include "mxc_sys.h"
41*49a45ad9SMatthias Ringwald #include "max14690n.h"
42*49a45ad9SMatthias Ringwald #include "board.h"
43*49a45ad9SMatthias Ringwald #include "i2cm.h"
44*49a45ad9SMatthias Ringwald #include "lp.h"
45*49a45ad9SMatthias Ringwald
46*49a45ad9SMatthias Ringwald /***** Definitions *****/
47*49a45ad9SMatthias Ringwald #define MAX14690_I2C_ADDR (0x50 >> 1)
48*49a45ad9SMatthias Ringwald #define MAX14690_ADDR_ID 0x00
49*49a45ad9SMatthias Ringwald
50*49a45ad9SMatthias Ringwald #define MAX14690_ADDR_LDO2 0x14
51*49a45ad9SMatthias Ringwald #define MAX14690_LDO_EN 0x02
52*49a45ad9SMatthias Ringwald
53*49a45ad9SMatthias Ringwald /***** Function Prototypes *****/
54*49a45ad9SMatthias Ringwald static void VBUS_Interrupt(void *unused);
55*49a45ad9SMatthias Ringwald
56*49a45ad9SMatthias Ringwald
57*49a45ad9SMatthias Ringwald /******************************************************************************/
MAX14690N_Init(float ldo2v,ldo_enable_mode_t ldo2en,float ldo3v,ldo_enable_mode_t ldo3en)58*49a45ad9SMatthias Ringwald int MAX14690N_Init(float ldo2v, ldo_enable_mode_t ldo2en, float ldo3v, ldo_enable_mode_t ldo3en)
59*49a45ad9SMatthias Ringwald {
60*49a45ad9SMatthias Ringwald uint8_t addr;
61*49a45ad9SMatthias Ringwald uint8_t data[2];
62*49a45ad9SMatthias Ringwald
63*49a45ad9SMatthias Ringwald /* Setup the I2CM Peripheral to talk to the MAX14690 */
64*49a45ad9SMatthias Ringwald sys_cfg_i2cm_t cfg;
65*49a45ad9SMatthias Ringwald cfg.clk_scale = CLKMAN_SCALE_DIV_1;
66*49a45ad9SMatthias Ringwald cfg.io_cfg = max14690_io_cfg;
67*49a45ad9SMatthias Ringwald I2CM_Init(MAX14690_I2CM, &cfg, I2CM_SPEED_100KHZ);
68*49a45ad9SMatthias Ringwald
69*49a45ad9SMatthias Ringwald /* Attempt to read the ID from the device */
70*49a45ad9SMatthias Ringwald addr = MAX14690_ADDR_ID;
71*49a45ad9SMatthias Ringwald if (I2CM_Read(MAX14690_I2CM, MAX14690_I2C_ADDR, &addr, 1, data, 2) != 2) {
72*49a45ad9SMatthias Ringwald return E_COMM_ERR;
73*49a45ad9SMatthias Ringwald }
74*49a45ad9SMatthias Ringwald
75*49a45ad9SMatthias Ringwald /* Configure the initial state of LDO2 */
76*49a45ad9SMatthias Ringwald if ((0.8 <= ldo2v)&&(ldo2v <= 3.6)){
77*49a45ad9SMatthias Ringwald data[0] = MAX14690_REG_LDO2_VSET;
78*49a45ad9SMatthias Ringwald data[1] = (10 * ldo2v) - 8;
79*49a45ad9SMatthias Ringwald if (I2CM_Write(MAX14690_I2CM, MAX14690_I2C_ADDR, NULL, 0, data, 2) != 2) {
80*49a45ad9SMatthias Ringwald return -1;
81*49a45ad9SMatthias Ringwald }
82*49a45ad9SMatthias Ringwald }
83*49a45ad9SMatthias Ringwald data[0] = MAX14690_REG_LDO2_CFG;
84*49a45ad9SMatthias Ringwald data[1] = ldo2en;
85*49a45ad9SMatthias Ringwald if (I2CM_Write(MAX14690_I2CM, MAX14690_I2C_ADDR, NULL, 0, data, 2) != 2) {
86*49a45ad9SMatthias Ringwald return -1;
87*49a45ad9SMatthias Ringwald }
88*49a45ad9SMatthias Ringwald
89*49a45ad9SMatthias Ringwald /* Configure the initial state of LDO3 */
90*49a45ad9SMatthias Ringwald if ((0.8 <= ldo3v)&&(ldo3v <= 3.6)){
91*49a45ad9SMatthias Ringwald data[0] = MAX14690_REG_LDO3_VSET;
92*49a45ad9SMatthias Ringwald data[1] = (10 * ldo3v) - 8;
93*49a45ad9SMatthias Ringwald if (I2CM_Write(MAX14690_I2CM, MAX14690_I2C_ADDR, NULL, 0, data, 2) != 2) {
94*49a45ad9SMatthias Ringwald return -1;
95*49a45ad9SMatthias Ringwald }
96*49a45ad9SMatthias Ringwald } else {
97*49a45ad9SMatthias Ringwald return -1;
98*49a45ad9SMatthias Ringwald }
99*49a45ad9SMatthias Ringwald data[0] = MAX14690_REG_LDO3_CFG;
100*49a45ad9SMatthias Ringwald data[1] = ldo3en;
101*49a45ad9SMatthias Ringwald if (I2CM_Write(MAX14690_I2CM, MAX14690_I2C_ADDR, NULL, 0, data, 2) != 2) {
102*49a45ad9SMatthias Ringwald return -1;
103*49a45ad9SMatthias Ringwald }
104*49a45ad9SMatthias Ringwald
105*49a45ad9SMatthias Ringwald VBUS_Interrupt(NULL);
106*49a45ad9SMatthias Ringwald
107*49a45ad9SMatthias Ringwald /* Configure GPIO for interrupt pin from PMIC */
108*49a45ad9SMatthias Ringwald if (GPIO_Config(&max14690_int) != E_NO_ERROR) {
109*49a45ad9SMatthias Ringwald return E_UNKNOWN;
110*49a45ad9SMatthias Ringwald }
111*49a45ad9SMatthias Ringwald
112*49a45ad9SMatthias Ringwald /* Configure and enable interrupt */
113*49a45ad9SMatthias Ringwald GPIO_RegisterCallback(&max14690_int, VBUS_Interrupt, NULL);
114*49a45ad9SMatthias Ringwald GPIO_IntConfig(&max14690_int, GPIO_INT_FALLING_EDGE);
115*49a45ad9SMatthias Ringwald GPIO_IntEnable(&max14690_int);
116*49a45ad9SMatthias Ringwald NVIC_EnableIRQ(MXC_GPIO_GET_IRQ(max14690_int.port));
117*49a45ad9SMatthias Ringwald
118*49a45ad9SMatthias Ringwald /* Configure interrupt wakeup */
119*49a45ad9SMatthias Ringwald if (LP_ConfigGPIOWakeUpDetect(&max14690_int, 0, LP_WEAK_PULL_UP) != E_NO_ERROR) {
120*49a45ad9SMatthias Ringwald return E_UNKNOWN;
121*49a45ad9SMatthias Ringwald }
122*49a45ad9SMatthias Ringwald
123*49a45ad9SMatthias Ringwald /* Enable the VBUS interrupt */
124*49a45ad9SMatthias Ringwald data[0] = 0x07; /* IntMaskA */
125*49a45ad9SMatthias Ringwald data[1] = 0x08; /* UsbOk */
126*49a45ad9SMatthias Ringwald if (I2CM_Write(MAX14690_I2CM, MAX14690_I2C_ADDR, NULL, 0, data, 2) != 2) {
127*49a45ad9SMatthias Ringwald return -1;
128*49a45ad9SMatthias Ringwald }
129*49a45ad9SMatthias Ringwald
130*49a45ad9SMatthias Ringwald return E_NO_ERROR;
131*49a45ad9SMatthias Ringwald }
132*49a45ad9SMatthias Ringwald
133*49a45ad9SMatthias Ringwald /******************************************************************************/
VBUS_Interrupt(void * unused)134*49a45ad9SMatthias Ringwald static void VBUS_Interrupt(void *unused)
135*49a45ad9SMatthias Ringwald {
136*49a45ad9SMatthias Ringwald uint8_t addr = 0x02; /* StatusA */
137*49a45ad9SMatthias Ringwald uint8_t data[5];
138*49a45ad9SMatthias Ringwald
139*49a45ad9SMatthias Ringwald if (I2CM_Read(MAX14690_I2CM, MAX14690_I2C_ADDR, &addr, 1, data, sizeof(data)) == sizeof(data)) {
140*49a45ad9SMatthias Ringwald if (data[1] & 0x08) { /* UsbOk */
141*49a45ad9SMatthias Ringwald /* VBUS is present. Enable LDO2 */
142*49a45ad9SMatthias Ringwald // MAX14690_EnableLDO2(1);
143*49a45ad9SMatthias Ringwald } else {
144*49a45ad9SMatthias Ringwald /* VBUS is not present. Disable LDO2 */
145*49a45ad9SMatthias Ringwald // MAX14690_EnableLDO2(0);
146*49a45ad9SMatthias Ringwald }
147*49a45ad9SMatthias Ringwald }
148*49a45ad9SMatthias Ringwald }
149*49a45ad9SMatthias Ringwald
150*49a45ad9SMatthias Ringwald /******************************************************************************/
MAX14690_LDO2setMode(ldo_enable_mode_t mode)151*49a45ad9SMatthias Ringwald int MAX14690_LDO2setMode(ldo_enable_mode_t mode)
152*49a45ad9SMatthias Ringwald {
153*49a45ad9SMatthias Ringwald int retval;
154*49a45ad9SMatthias Ringwald uint8_t data[2] = {MAX14690_REG_LDO2_CFG, mode};
155*49a45ad9SMatthias Ringwald
156*49a45ad9SMatthias Ringwald retval = I2CM_Write(MAX14690_I2CM, MAX14690_I2C_ADDR, NULL, 0, data, 2);
157*49a45ad9SMatthias Ringwald if(retval != 2) {
158*49a45ad9SMatthias Ringwald return retval;
159*49a45ad9SMatthias Ringwald }
160*49a45ad9SMatthias Ringwald
161*49a45ad9SMatthias Ringwald return E_NO_ERROR;
162*49a45ad9SMatthias Ringwald }
163*49a45ad9SMatthias Ringwald
164*49a45ad9SMatthias Ringwald /******************************************************************************/
MAX14690_LDO2setV(float voltage)165*49a45ad9SMatthias Ringwald int MAX14690_LDO2setV(float voltage)
166*49a45ad9SMatthias Ringwald {
167*49a45ad9SMatthias Ringwald int retval;
168*49a45ad9SMatthias Ringwald uint8_t data[2] = {MAX14690_REG_LDO2_VSET, 0};
169*49a45ad9SMatthias Ringwald
170*49a45ad9SMatthias Ringwald if ((0.8 <= voltage)&&(voltage <= 3.6)){
171*49a45ad9SMatthias Ringwald data[1] = (10 * voltage) - 8;
172*49a45ad9SMatthias Ringwald } else {
173*49a45ad9SMatthias Ringwald return -1;
174*49a45ad9SMatthias Ringwald }
175*49a45ad9SMatthias Ringwald
176*49a45ad9SMatthias Ringwald retval = I2CM_Write(MAX14690_I2CM, MAX14690_I2C_ADDR, NULL, 0, data, 2);
177*49a45ad9SMatthias Ringwald if(retval != 2) {
178*49a45ad9SMatthias Ringwald return retval;
179*49a45ad9SMatthias Ringwald }
180*49a45ad9SMatthias Ringwald
181*49a45ad9SMatthias Ringwald return E_NO_ERROR;
182*49a45ad9SMatthias Ringwald }
183*49a45ad9SMatthias Ringwald
184*49a45ad9SMatthias Ringwald /******************************************************************************/
MAX14690_LDO3setMode(ldo_enable_mode_t mode)185*49a45ad9SMatthias Ringwald int MAX14690_LDO3setMode(ldo_enable_mode_t mode)
186*49a45ad9SMatthias Ringwald {
187*49a45ad9SMatthias Ringwald int retval;
188*49a45ad9SMatthias Ringwald uint8_t data[2] = {MAX14690_REG_LDO3_CFG, mode};
189*49a45ad9SMatthias Ringwald
190*49a45ad9SMatthias Ringwald retval = I2CM_Write(MAX14690_I2CM, MAX14690_I2C_ADDR, NULL, 0, data, 2);
191*49a45ad9SMatthias Ringwald if(retval != 2) {
192*49a45ad9SMatthias Ringwald return retval;
193*49a45ad9SMatthias Ringwald }
194*49a45ad9SMatthias Ringwald
195*49a45ad9SMatthias Ringwald return E_NO_ERROR;
196*49a45ad9SMatthias Ringwald }
197*49a45ad9SMatthias Ringwald
198*49a45ad9SMatthias Ringwald /******************************************************************************/
MAX14690_LDO3setV(float voltage)199*49a45ad9SMatthias Ringwald int MAX14690_LDO3setV(float voltage)
200*49a45ad9SMatthias Ringwald {
201*49a45ad9SMatthias Ringwald int retval;
202*49a45ad9SMatthias Ringwald uint8_t data[2] = {MAX14690_REG_LDO3_VSET, 0};
203*49a45ad9SMatthias Ringwald
204*49a45ad9SMatthias Ringwald if ((0.8 <= voltage)&&(voltage <= 3.6)){
205*49a45ad9SMatthias Ringwald data[1] = (10 * voltage) - 8;
206*49a45ad9SMatthias Ringwald } else {
207*49a45ad9SMatthias Ringwald return -1;
208*49a45ad9SMatthias Ringwald }
209*49a45ad9SMatthias Ringwald
210*49a45ad9SMatthias Ringwald retval = I2CM_Write(MAX14690_I2CM, MAX14690_I2C_ADDR, NULL, 0, data, 2);
211*49a45ad9SMatthias Ringwald if(retval != 2) {
212*49a45ad9SMatthias Ringwald return retval;
213*49a45ad9SMatthias Ringwald }
214*49a45ad9SMatthias Ringwald
215*49a45ad9SMatthias Ringwald return E_NO_ERROR;
216*49a45ad9SMatthias Ringwald }
217*49a45ad9SMatthias Ringwald
218*49a45ad9SMatthias Ringwald /******************************************************************************/
MAX14690_MuxSet(max14690_mux_ch_t ch,max14690_mux_div_t div)219*49a45ad9SMatthias Ringwald int MAX14690_MuxSet(max14690_mux_ch_t ch, max14690_mux_div_t div)
220*49a45ad9SMatthias Ringwald {
221*49a45ad9SMatthias Ringwald int retval;
222*49a45ad9SMatthias Ringwald uint8_t data[2] = {MAX14690_REG_MON_CFG, 0};
223*49a45ad9SMatthias Ringwald
224*49a45ad9SMatthias Ringwald data[1] = (div << 4) + ch;
225*49a45ad9SMatthias Ringwald
226*49a45ad9SMatthias Ringwald retval = I2CM_Write(MAX14690_I2CM, MAX14690_I2C_ADDR, NULL, 0, data, 2);
227*49a45ad9SMatthias Ringwald if(retval != 2) {
228*49a45ad9SMatthias Ringwald return retval;
229*49a45ad9SMatthias Ringwald }
230*49a45ad9SMatthias Ringwald
231*49a45ad9SMatthias Ringwald return E_NO_ERROR;
232*49a45ad9SMatthias Ringwald }
233