blob: b5088503321a946ef8ac6d5daedcb09e4b1f7df9 [file] [log] [blame]
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -07001/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
2
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions are
5met:
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
16THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*/
28
29
30/*=============================================================================
31
32 INCLUDE FILES
33
34===============================================================================*/
35
36#include "pm_smbchg_driver.h"
37#include "pm_smbchg_usb_chgpth.h"
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -070038
39/*unlock peripheral for secured access write*/
40static inline pm_err_flag_type pm_smbchg_usb_chgpth_unlock_perph_write(pm_smbchg_data_type *smbchg_ptr);
41
42/*Find the nearest register value corresponding to input_data*/
43static void pm_smbchg_usb_chgpth_return_reg_value(uint32 input_data, uint32 *array, uint32 array_size, pm_register_data_type *reg_value);
44
45pm_err_flag_type pm_smbchg_usb_chgpth_icl_sts(uint32 device_index, input_current_limit_sts *icl_sts)
46{
47 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
48 pm_register_data_type data1, data2;
49
50 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
51
52 if (NULL == smbchg_ptr)
53 {
54 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
55 }
56 else
57 {
58 uint32 *icl_current = smbchg_ptr->chg_range_data->usbin_current_limits;
59
60 pm_register_address_type icl_sts1 = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->icl_sts_1;
61 pm_register_address_type icl_sts2 = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->icl_sts_2;
62
63 err_flag = pm_comm_read_byte(smbchg_ptr->comm_ptr->slave_id, icl_sts1, &data1, 0);
64 err_flag |= pm_comm_read_byte(smbchg_ptr->comm_ptr->slave_id, icl_sts2, &data2, 0);
65
66 icl_sts->is_aicl_complete = (data1 & 0x20) ? TRUE : FALSE;
67 icl_sts->input_current_limit = icl_current[data1 & 0x1F];
68 icl_sts->icl_mode = (input_current_limit_mode)((data2 & 0x30) >> 4);
69 icl_sts->is_usbin_suspended = (data2 & 0x8) ? TRUE : FALSE;
70 icl_sts->is_dcin_suspended = (data2 & 0x4) ? TRUE : FALSE;
71 icl_sts->is_usbin_active_pwr_src = (data2 & 0x2) ? TRUE : FALSE;
72 icl_sts->is_dcin_active_pwr_src = (data2 & 0x1) ? TRUE : FALSE;
73 }
74
75 return err_flag;
76}
77
78
79pm_err_flag_type pm_smbchg_usb_chgpth_get_pwr_pth(uint32 device_index, pm_smbchg_usb_chgpth_pwr_pth_type *pwr_path)
80{
81 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
82 pm_register_data_type data;
83 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
84
85 if (NULL == smbchg_ptr)
86 {
87 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
88 }
89 else
90 {
91 pm_register_address_type pwr_pth_sts = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->pwr_pth_sts;
92
93 err_flag = pm_comm_read_byte(smbchg_ptr->comm_ptr->slave_id, pwr_pth_sts, &data, 0);
94
95 *pwr_path = (pm_smbchg_usb_chgpth_pwr_pth_type)(data & 0x03);
96 }
97
98 return err_flag;
99}
100
101
102/*auto power source detection degitched status*/
103pm_err_flag_type pm_smbchg_usb_chgpth_apsd_dg_sts(uint32 device_index, pm_apsd_dg_sts_type apsd_dg_sts_type, boolean* status)
104{
105 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
106 pm_register_data_type data;
107
108 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
109
110 if (NULL == smbchg_ptr)
111 {
112 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
113 }
114 else if ( NULL == status || PM_SMBCHG_USB_CHGPTH_DG_STS__INVALID == apsd_dg_sts_type)
115 {
116 err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE;
117 }
118 else
119 {
120 pm_register_address_type apsd_dg_sts_reg = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->apsd_dg_sts;
121
122 err_flag = pm_comm_read_byte(smbchg_ptr->comm_ptr->slave_id, apsd_dg_sts_reg, &data, 0);
123
124 *status = (data & (0x1 << apsd_dg_sts_type))? TRUE : FALSE;
125 }
126 return err_flag;
127}
128
129
130pm_err_flag_type pm_smbchg_usb_chgpth_rid_sts(uint32 device_index, pm_smbchg_usb_chgpth_rid_sts_type *rid_sts)
131{
132 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
133 pm_register_data_type data;
134 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
135
136 if (NULL == smbchg_ptr)
137 {
138 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
139 }
140 else
141 {
142 pm_register_address_type rid_sts_reg = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->rid_sts;
143
144 err_flag = pm_comm_read_byte_mask(smbchg_ptr->comm_ptr->slave_id, rid_sts_reg, 0xF, &data, 0);
145
146 switch (data)
147 {
148 case 0x8: *rid_sts = PM_SMBCHG_USB_CHGPTH_RID__FLOAT; break;
149 case 0x4: *rid_sts = PM_SMBCHG_USB_CHGPTH_RID__A; break;
150 case 0x2: *rid_sts = PM_SMBCHG_USB_CHGPTH_RID__B; break;
151 case 0x1: *rid_sts = PM_SMBCHG_USB_CHGPTH_RID__C; break;
152 case 0x0: *rid_sts = PM_SMBCHG_USB_CHGPTH_RID__GND; break;
153 default: *rid_sts = PM_SMBCHG_USB_CHGPTH_RID__INVALID;
154 }
155 }
156
157 return err_flag;
158};
159
160
161
162pm_err_flag_type pm_smbchg_usb_chgpth_hvdcp_sts(uint32 device_index, pm_smbchg_usb_chgpth_hvdcp_sts_type hvdcp_sts, boolean *status)
163{
164
165 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
166 pm_register_data_type data;
167 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
168
169 if (NULL == smbchg_ptr)
170 {
171 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
172 }
173 else if (NULL == status || PM_SMBCHG_USB_CHGPTH__HVDCP_STS_INVALID == hvdcp_sts)
174 {
175 err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE;
176 }
177 else
178 {
179 pm_register_address_type hvdcp_sts_reg = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->hvdcp_sts;
180
181 err_flag = pm_comm_read_byte(smbchg_ptr->comm_ptr->slave_id, hvdcp_sts_reg, &data, 0);
182
183 *status = (data & (0x1 << hvdcp_sts))? TRUE : FALSE;
184
185 }
186 return err_flag;
187}
188
189pm_err_flag_type pm_smbchg_usb_chgpth_input_sts(uint32 device_index, pm_smbchg_usb_chgpth_chgr_type chgr, pm_smbchg_usb_chgpth_input_sts_type *input_sts_type)
190{
191 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
192 pm_register_data_type data;
193 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
194
195 if (NULL == smbchg_ptr)
196 {
197 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
198 }
199 else
200 {
201 pm_register_address_type input_sts = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->input_sts;
202
203 err_flag = pm_comm_read_byte(smbchg_ptr->comm_ptr->slave_id, input_sts, &data, 0);
204 if (PM_ERR_FLAG__SUCCESS == err_flag)
205 {
206 switch (chgr)
207 {
208 case PM_SMBCHG_CHAR_TYPE_USB:
209 data = (data & 0x38) >> 3; break;
210 case PM_SMBCHG_CHAR_TYPE_DC:
211 data = (data & 0x7); break;
212 default:
213 return PM_ERR_FLAG__PAR2_OUT_OF_RANGE;
214 }
215
216 switch (data)
217 {
218 case 0x00:
219 *input_sts_type = PM_SMBCHG_NO_CHGR_DETECTED; break;
220 case 0x01:
221 *input_sts_type = PM_SMBCHG_5V_9V_CHGR_DETECTED; break;
222 case 0x02:
223 *input_sts_type = PM_SMBCHG_UNREGULATED_CHGR_DETECTED; break;
224 case 0x04:
225 *input_sts_type = PM_SMBCHG_9V_CHGR_DETECTED; break;
226 default:
227 *input_sts_type = PM_SMBCHG_INVALID_DETECTED; break;
228 }
229 }
230
231 }
232
233 return err_flag;
234}
235
236pm_err_flag_type pm_smbchg_usb_chgpth_get_valid_usbid(uint32 device_index, uint16 *valid_id)
237{
238 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
239 pm_register_data_type data1, data2;
240 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
241
242 if (NULL == smbchg_ptr)
243 {
244 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
245 }
246 else
247 {
248 pm_register_address_type usbid_valid_id_7_0 = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->usbid_valid_id_7_0;
249 pm_register_address_type usbid_valid_id_11_8 = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->usbid_valid_id_11_8;
250
251 err_flag = pm_comm_read_byte(smbchg_ptr->comm_ptr->slave_id, usbid_valid_id_7_0, &data1, 0);
252 err_flag |= pm_comm_read_byte_mask(smbchg_ptr->comm_ptr->slave_id, usbid_valid_id_11_8, 0x0F, &data2, 0);
253 if (PM_ERR_FLAG__SUCCESS == err_flag)
254 {
255 *valid_id = (uint16)((data2 << 8) | data1);
256 }
257
258 }
259 return err_flag;
260}
261
262
263pm_err_flag_type pm_smbchg_usb_chgpth_set_cmd_il(uint32 device_index, pm_smbchg_usb_chgpth_cmd_il_type chgpth_cmd_il, boolean enable)
264{
265 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
266 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
267 pm_register_data_type data;
268
269 if(NULL == smbchg_ptr)
270 {
271 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
272 }
273 else if(PM_SMBCHG_USBCHGPTH_CMD_IL__INVALID == chgpth_cmd_il)
274 {
275 err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE;
276 }
277 else
278 {
279 pm_register_address_type cmd_il = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->cmd_il;
280
281 data = (enable) ? 0xFF : 0x00;
282
283 err_flag = pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, cmd_il, (0x1 << chgpth_cmd_il), data, 0);
284 }
285
286 return err_flag;
287}
288
289
290pm_err_flag_type pm_smbchg_usb_chgpth_get_cmd_il(uint32 device_index, pm_smbchg_usb_chgpth_cmd_il_type chgpth_cmd_il, boolean *enable)
291{
292 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
293 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
294 pm_register_data_type data;
295 pm_register_address_type cmd_il;
296
297 if (NULL == smbchg_ptr)
298 {
299 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
300 }
301 else if (PM_SMBCHG_USBCHGPTH_CMD_IL__INVALID == chgpth_cmd_il || NULL == enable)
302 {
303 err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE;
304 }
305 else
306 {
307 cmd_il = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->cmd_il;
308 err_flag = pm_comm_read_byte(smbchg_ptr->comm_ptr->slave_id, cmd_il, &data, 0);
309 *enable = (data & (0x1 << chgpth_cmd_il))? TRUE : FALSE;
310 }
311 return err_flag;
312}
313
314pm_err_flag_type pm_smbchg_usb_chgpth_set_iusb_max(uint32 device_index, uint32 i_milli_amp)
315{
316 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
317 pm_register_data_type data;
318 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
319
320 if (NULL == smbchg_ptr)
321 {
322 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
323 }
324 else
325 {
326 pm_register_address_type iusb_max = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->iusb_max;
327
328 if (i_milli_amp > 2500)
329 {
330 data = 0x19;
331 }
332 else if (i_milli_amp < 100)
333 {
334 data = 0x0;
335 }
336 else if (i_milli_amp > 100 && i_milli_amp <= 150)
337 {
338 data = 0x1;
339 }
340 else
341 {
342 /*IUSB_MAX = data * 100*/
343 data = (i_milli_amp + 50) / 100; //rounding
344 }
345
346 err_flag = pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, iusb_max, 0x1F, data, 0);
347 }
348
349 return err_flag;
350}
351
352pm_err_flag_type pm_smbchg_usb_chgpth_get_iusb_max(uint32 device_index, uint32 *i_milli_amp)
353{
354 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
355 pm_register_data_type data;
356 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
357
358 if (NULL == smbchg_ptr)
359 {
360 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
361 }
362 else if (NULL == i_milli_amp)
363 {
364 err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE;
365 }
366 else
367 {
368 pm_register_address_type iusb_max = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->iusb_max;
369 err_flag = pm_comm_read_byte(smbchg_ptr->comm_ptr->slave_id, iusb_max, &data, 0);
370
371 if (PM_ERR_FLAG__SUCCESS == err_flag)
372 {
373 data &= 0x1F;
374 switch (data)
375 {
376 case 0:
377 *i_milli_amp = 100; break;
378 case 1:
379 *i_milli_amp = 150; break;
380 default:
381 *i_milli_amp = data * 100;
382 }
383 }
384 }
385 return err_flag;
386}
387
388pm_err_flag_type pm_smbchg_usb_chgpth_set_enum_timer_stop(uint32 device_index)
389{
390 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
391 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
392
393 if (NULL == smbchg_ptr)
394 {
395 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
396 }
397 else
398 {
399 pm_register_address_type enum_timer_stop = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->enum_timer_stop;
400 err_flag = pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, enum_timer_stop, 0x1, 0x1, 0);
401 }
402 return err_flag;
403}
404
405
406pm_err_flag_type pm_smbchg_usb_chgpth_set_usbin_adptr_allowance(uint32 device_index, pm_smbchg_usbin_adptr_allowance adptr_allowance)
407{
408 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
409
410 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
411
412 if (NULL == smbchg_ptr)
413 {
414 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
415 }
416 else if (adptr_allowance >= PM_SMBCHG_USBIN_ADPTR_ALLOWANCE_INVALID)
417 {
418 err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE;
419 }
420 else
421 {
422 pm_register_address_type usbin_chgr_cfg = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->usbin_chgr_cfg;
423 err_flag = pm_smbchg_usb_chgpth_unlock_perph_write(smbchg_ptr);
424 err_flag |= pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, usbin_chgr_cfg, 0x7, (pm_register_data_type)adptr_allowance, 0);
425 }
426
427 return err_flag;
428}
429
430
431pm_err_flag_type pm_smbchg_usb_chgpth_get_usbin_adptr_allowance(uint32 device_index, pm_smbchg_usbin_adptr_allowance *adptr_allowance)
432{
433 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
434 pm_register_data_type data = 0;
435
436 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
437
438 if (NULL == smbchg_ptr)
439 {
440 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
441 }
442 else if (NULL == adptr_allowance)
443 {
444 err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE;
445 }
446 else
447 {
448 pm_register_address_type usbin_chgr_cfg = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->usbin_chgr_cfg;
449
450 err_flag = pm_comm_read_byte_mask(smbchg_ptr->comm_ptr->slave_id, usbin_chgr_cfg, 0x7, &data, 0);
451 /*valid adptr_allowance is only 0 to 5 but data read is 3 bits*/
452 *adptr_allowance = (data >=PM_SMBCHG_USBIN_ADPTR_ALLOWANCE_INVALID)? PM_SMBCHG_USBIN_ADPTR_ALLOWANCE_INVALID :(pm_smbchg_usbin_adptr_allowance)data;
453 }
454
455 return err_flag;
456}
457
458
459pm_err_flag_type pm_smbchg_usb_chgpth_set_usbin_current_limit(uint32 device_index, uint32 current_ma)
460{
461 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
462 pm_register_data_type data =0;
463
464
465 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
466 if (NULL == smbchg_ptr)
467 {
468 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
469 }
470 else
471 {
472 uint32 *usbin_icl = smbchg_ptr->chg_range_data->usbin_current_limits;
473 pm_register_address_type usbin_il_cfg = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->usbin_il_cfg;
474
475 pm_smbchg_usb_chgpth_return_reg_value(current_ma, usbin_icl, USBIN_SIZE, &data);
476
477 err_flag = pm_smbchg_usb_chgpth_unlock_perph_write(smbchg_ptr);
478 err_flag |= pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, usbin_il_cfg, 0x1F, data, 0);
479 }
480
481 return err_flag;
482}
483
484
485
486pm_err_flag_type pm_smbchg_usb_chgpth_get_usbin_current_limit(uint32 device_index, uint32 *current_ma)
487{
488 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
489 pm_register_data_type data;
490
491 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
492 if (NULL == smbchg_ptr)
493 {
494 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
495 }
496 else if (NULL == current_ma)
497 {
498 err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE;
499 }
500 else
501 {
502 uint32 *usbin_icl = smbchg_ptr->chg_range_data->usbin_current_limits;
503 pm_register_address_type usbin_il_cfg = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->usbin_il_cfg;
504 err_flag |= pm_comm_read_byte_mask(smbchg_ptr->comm_ptr->slave_id, usbin_il_cfg, 0x1F, &data, 0);
505 *current_ma = usbin_icl[data & 0x1F];
506 }
507
508 return err_flag;
509}
510
511
512pm_err_flag_type pm_smbchg_usb_chgpth_config_aicl(uint32 device_index, pm_smbchg_usb_chgpth_aicl_cfg_type usb_aicl_cfg, boolean enable)
513{
514 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
515
516 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
517 if (NULL == smbchg_ptr)
518 {
519 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
520 }
521 else if (PM_SMBCHG_USB_CHGPTH_AICL_CFG__INVALID == usb_aicl_cfg)
522 {
523 err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE;
524 }
525 else
526 {
527 pm_register_address_type usb_aicl_cfg_reg = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->usb_aicl_cfg;
528 err_flag = pm_smbchg_usb_chgpth_unlock_perph_write(smbchg_ptr);
529 err_flag |= pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, usb_aicl_cfg_reg, (0x1 << usb_aicl_cfg), (pm_register_data_type)(enable<<usb_aicl_cfg), 0);
530 }
531
532 return err_flag;
533}
534
535
536pm_err_flag_type pm_smbchg_usb_chgpth_get_aicl_config(uint32 device_index, pm_smbchg_usb_chgpth_aicl_cfg_type usb_aicl_cfg, boolean* enable)
537{
538 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
539 pm_register_data_type data;
540 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
541
542 if (NULL == smbchg_ptr)
543 {
544 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
545 }
546 else if (PM_SMBCHG_USB_CHGPTH_AICL_CFG__INVALID == usb_aicl_cfg)
547 {
548 err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE;
549 }
550 else if (NULL == enable)
551 {
552 err_flag = PM_ERR_FLAG__PAR3_OUT_OF_RANGE;
553 }
554 else
555 {
556 pm_register_address_type usb_aicl_cfg_reg = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->usb_aicl_cfg;
557
558 err_flag = pm_comm_read_byte_mask(smbchg_ptr->comm_ptr->slave_id, usb_aicl_cfg_reg, (0x1<<usb_aicl_cfg), &data, 0);
559
560 *enable = (data)? TRUE: FALSE;
561 }
562
563 return err_flag;
564}
565
566
567
568pm_err_flag_type pm_smbchg_usb_chgpth_config_usb_chgpth(uint32 device_index, pm_usb_chgpth_usb_cfg_type *usb_cfg_type)
569{
570 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
571 pm_register_data_type data;
572 uint8 mask = 0x06;
573 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
574
575 if (NULL == smbchg_ptr)
576 {
577 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
578 }
579 else if (NULL == usb_cfg_type)
580 {
581 err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE;
582 }
583 else
584 {
585 data = ((usb_cfg_type->usb51ac_ctrl_type << 1) |(usb_cfg_type->usb51_cmd_pol_type << 2));
586
587 pm_register_address_type cfg = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->cfg;
588 err_flag = pm_smbchg_usb_chgpth_unlock_perph_write(smbchg_ptr);
589 err_flag |= pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, cfg, mask, data, 0);
590 }
591
592 return err_flag;
593}
594
595
596
597pm_err_flag_type pm_smbchg_usb_chgpth_get_usb_chgpth_config(uint32 device_index, pm_usb_chgpth_usb_cfg_type *usb_cfg_type)
598{
599 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
600 pm_register_data_type data;
601 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
602
603 if (NULL == smbchg_ptr)
604 {
605 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
606 }
607 else if (NULL == usb_cfg_type)
608 {
609 err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE;
610 }
611 else
612 {
613 pm_register_address_type cfg = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->cfg;
614 err_flag = pm_comm_read_byte(smbchg_ptr->comm_ptr->slave_id, cfg, &data, 0);
615
616 usb_cfg_type->usb51ac_ctrl_type = (data & 0x1)? PM_SMBCHG_USB_CHGPTH_USB51AC_CTRL__PIN: PM_SMBCHG_USB_CHGPTH_USB51AC_CTRL__CMD;
617 usb_cfg_type->usb51_cmd_pol_type = (data & 0x2)? PM_SMBCHG_USB_CHGPTH_USB51_CMD_POL__CMD1_100: PM_SMBCHG_USB_CHGPTH_USB51_CMD_POL__CMD1_500;
618 }
619
620 return err_flag;
621}
622
623
624pm_err_flag_type pm_smbchg_usb_chgpth_config_apsd(uint32 device_index, pm_smbchg_usb_chgpth_apsd_cfg_type *apsd_cfg)
625{
626 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
627 pm_register_data_type data;
628 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
629
630 if (NULL == smbchg_ptr)
631 {
632 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
633 }
634 else if (NULL == apsd_cfg)
635 {
636 err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE;
637 }
638 else
639 {
640 data = (apsd_cfg->en_auto_src_detect) |(apsd_cfg->en_dcd_tmout_only << 1)|(apsd_cfg->set_rid_clk_2khz << 2)|(apsd_cfg->force_icl_500ma_vbat_low_sdp << 3)
641 |(apsd_cfg->sdp_suspend << 4)|(apsd_cfg->is_ocd_isel_hc << 5)|(apsd_cfg->usb_fail_pok_hv << 6)|(apsd_cfg->is_input_prority_usbin << 7 );
642
643 pm_register_address_type apsd_cfg_reg = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->apsd_cfg;
644 err_flag = pm_smbchg_usb_chgpth_unlock_perph_write(smbchg_ptr);
645 err_flag |= pm_comm_write_byte(smbchg_ptr->comm_ptr->slave_id, apsd_cfg_reg, data, 0);
646 }
647
648 return err_flag;
649}
650
651
652pm_err_flag_type pm_smbchg_usb_chgpth_get_apsd_config(uint32 device_index, pm_smbchg_usb_chgpth_apsd_cfg_type *apsd_cfg)
653{
654 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
655 pm_register_data_type data;
656
657 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
658
659 if (NULL == smbchg_ptr)
660 {
661 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
662 }
663 else if (NULL == apsd_cfg )
664 {
665 err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE;
666 }
667 else
668 {
669 pm_register_address_type apsd_cfg_reg = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->apsd_cfg;
670 err_flag = pm_comm_read_byte(smbchg_ptr->comm_ptr->slave_id, apsd_cfg_reg, &data, 0);
671
672 apsd_cfg->en_auto_src_detect = (data & 0x1) ? TRUE : FALSE;
673 apsd_cfg->en_dcd_tmout_only = (data & 0x2) ? TRUE : FALSE;
674 apsd_cfg->set_rid_clk_2khz = (data & 0x4) ? TRUE : FALSE;
675 apsd_cfg->force_icl_500ma_vbat_low_sdp = (data & 0x8) ? TRUE : FALSE;
676 apsd_cfg->sdp_suspend = (data & 0x10) ? TRUE : FALSE;
677 apsd_cfg->is_ocd_isel_hc = (data & 0x20) ? TRUE : FALSE;
678 apsd_cfg->usb_fail_pok_hv = (data & 0x40) ? TRUE : FALSE;
679 apsd_cfg->is_input_prority_usbin = (data & 0x80) ? TRUE : FALSE;
680 }
681 return err_flag;
682}
683
684
685
686pm_err_flag_type pm_smbchg_chgpth_set_input_priority(uint32 device_index, pm_smbchg_chgpth_input_priority_type chgpth_priority)
687{
688 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
689 pm_smbchg_usb_chgpth_apsd_cfg_type apsd_cfg;
690
691 if (chgpth_priority >= PM_SMBCHG_USBCHGPTH_INPUT_PRIORITY_INVALID)
692 {
693 err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE;
694 }
695 else
696 {
697 //Get the current configuration
698 err_flag = pm_smbchg_usb_chgpth_get_apsd_config(device_index, &apsd_cfg);
699
700 if (err_flag == PM_ERR_FLAG__SUCCESS)
701 {
702 switch (chgpth_priority)
703 {
704 case PM_SMBCHG_USBCHGPTH_INPUT_PRIORITY_DCIN:
705 {
706 apsd_cfg.is_input_prority_usbin = 0;
707 }
708 break;
709 case PM_SMBCHG_USBCHGPTH_INPUT_PRIORITY_USBIN:
710 {
711 apsd_cfg.is_input_prority_usbin = 1;
712 }
713 break;
714 default:
715 err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE;
716 break;
717 }
718
719 err_flag |= pm_smbchg_usb_chgpth_config_apsd(device_index, &apsd_cfg);
720 }
721 }
722 return err_flag;
723}
724
725
726pm_err_flag_type pm_smbchg_usb_chgpth_irq_enable(uint32 device_index, pm_smbchg_usb_chgpth_irq_type irq, boolean enable)
727{
728 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
729 pm_register_address_type irq_reg;
730 pm_register_data_type data = 1 << irq;
731 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
732
733 if (NULL == smbchg_ptr)
734 {
735 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
736 }
737 else if (irq >= PM_SMBCHG_USB_CHGPTH_IRQ_INVALID)
738 {
739 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
740 }
741 else
742 {
743 if (enable)
744 {
745 irq_reg = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->int_en_set;
746 }
747 else
748 {
749 irq_reg = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->int_en_clr;
750 }
751
752 err_flag = pm_comm_write_byte(smbchg_ptr->comm_ptr->slave_id, irq_reg, data, 0);
753 }
754
755 return err_flag;
756}
757
758pm_err_flag_type pm_smbchg_usb_chgpth_irq_clear(uint32 device_index, pm_smbchg_usb_chgpth_irq_type irq)
759{
760 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
761 pm_register_data_type data = 1 << irq;
762 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
763
764 if (NULL == smbchg_ptr)
765 {
766 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
767 }
768 else if (irq >= PM_SMBCHG_USB_CHGPTH_IRQ_INVALID)
769 {
770 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
771 }
772 else
773 {
774 pm_register_address_type int_latched_clr = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->int_latched_clr;
775 err_flag = pm_comm_write_byte(smbchg_ptr->comm_ptr->slave_id, int_latched_clr, data, 0);
776 }
777 return err_flag;
778}
779
780
781pm_err_flag_type pm_smbchg_usb_chgpth_irq_set_trigger(uint32 device_index, pm_smbchg_usb_chgpth_irq_type irq, pm_irq_trigger_type trigger)
782{
783 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
784 uint8 mask = 1 << irq;
785 pm_register_data_type set_type, polarity_high, polarity_low;
786 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
787
788 if (NULL == smbchg_ptr)
789 {
790 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
791 }
792 else if (irq >= PM_SMBCHG_USB_CHGPTH_IRQ_INVALID)
793 {
794 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
795 }
796 else
797 {
798 pm_register_address_type int_set_type = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->int_set_type;
799 pm_register_address_type int_polarity_high = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->int_polarity_high;
800 pm_register_address_type int_polarity_low = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->int_polarity_low;
801
802 switch (trigger)
803 {
804 case PM_IRQ_TRIGGER_ACTIVE_LOW:
805 set_type = 0x00;
806 polarity_high = 0x00;
807 polarity_low = 0xFF;
808 break;
809 case PM_IRQ_TRIGGER_ACTIVE_HIGH:
810 set_type = 0x00;
811 polarity_high = 0xFF;
812 polarity_low = 0x00;
813 break;
814 case PM_IRQ_TRIGGER_RISING_EDGE:
815 set_type = 0xFF;
816 polarity_high = 0xFF;
817 polarity_low = 0x00;
818 break;
819 case PM_IRQ_TRIGGER_FALLING_EDGE:
820 set_type = 0xFF;
821 polarity_high = 0x00;
822 polarity_low = 0xFF;
823 break;
824 case PM_IRQ_TRIGGER_DUAL_EDGE:
825 set_type = 0xFF;
826 polarity_high = 0xFF;
827 polarity_low = 0xFF;
828 break;
829 default:
830 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
831 }
832 err_flag = pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, int_set_type, mask, set_type, 0);
833 err_flag |= pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, int_polarity_high, mask, polarity_high, 0);
834 err_flag |= pm_comm_write_byte_mask(smbchg_ptr->comm_ptr->slave_id, int_polarity_low, mask, polarity_low, 0);
835 }
836
837 return err_flag;
838}
839
840pm_err_flag_type pm_smbchg_usb_chgpth_irq_status(uint32 device_index, pm_smbchg_usb_chgpth_irq_type irq, pm_irq_status_type type, boolean *status)
841{
842 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
843 pm_register_data_type data;
844 uint8 mask = 1 << irq;
845 pm_register_address_type int_sts;
846 pm_smbchg_data_type *smbchg_ptr = pm_smbchg_get_data(device_index);
847
848 if (NULL == smbchg_ptr)
849 {
850 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
851 }
852 else if (irq >= PM_SMBCHG_USB_CHGPTH_IRQ_INVALID)
853 {
854 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
855 }
856 else
857 {
858 switch (type)
859 {
860 case PM_IRQ_STATUS_RT:
861 int_sts = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->int_rt_sts;
862 break;
863 case PM_IRQ_STATUS_LATCHED:
864 int_sts = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->int_latched_sts;
865 break;
866 case PM_IRQ_STATUS_PENDING:
867 int_sts = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->int_pending_sts;
868 break;
869 default:
870 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
871 }
872
873 err_flag = pm_comm_read_byte_mask(smbchg_ptr->comm_ptr->slave_id, int_sts, mask, &data, 0);
874 *status = data ? TRUE : FALSE;
875 }
876 return err_flag;
877}
878
879
880static inline pm_err_flag_type pm_smbchg_usb_chgpth_unlock_perph_write(pm_smbchg_data_type *smbchg_ptr)
881{
882 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
883
884 if (NULL == smbchg_ptr)
885 {
886 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
887 }
888 else
889 {
890 pm_register_address_type sec_access = smbchg_ptr->smbchg_register->usb_chgpth_register->base_address + smbchg_ptr->smbchg_register->usb_chgpth_register->sec_access;
891 err_flag = pm_comm_write_byte(smbchg_ptr->comm_ptr->slave_id, sec_access, 0xA5, 0);
892 }
893
894 return err_flag;
895}
896
897
898/*Find the nearest register value corresponding to input_data*/
899static void pm_smbchg_usb_chgpth_return_reg_value(uint32 input_data, uint32 *array, uint32 array_size, pm_register_data_type *reg_value)
900{
901 uint32 loc = 0;
902
903 /*checking lower bound*/
904 input_data = (array[0]>input_data)? array[0]: input_data;
905
906 while (loc < array_size)
907 {
908 if (input_data < array[loc])
909 {
910 break;
911 }
912 else
913 {
914 loc++;
915 }
916 }
917
918 *reg_value = (loc) ? (loc - 1) : 0;
919
920 return;
921}
922
923
924
925/*@todo: need more info to implement below
926pm_smbchg_usb_chgpth_set_wi_pwr_options(uint32 device_index)
927pm_smbchg_usb_chgpth_get_wi_pwr_options(uint32 device_index)
928*/