xref: /btstack/port/max32630-fthr/board/max14690n.c (revision 49a45ad9fdd8e9904c01b63e1d7d6091211e6efb)
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