twl6030.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. * (C) Copyright 2010
  3. * Texas Instruments, <www.ti.com>
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. #include <config.h>
  8. #ifdef CONFIG_TWL6030_POWER
  9. #include <twl6030.h>
  10. static struct twl6030_data *twl;
  11. static struct twl6030_data twl6030_info = {
  12. .chip_type = chip_TWL6030,
  13. .adc_rbase = GPCH0_LSB,
  14. .adc_ctrl = CTRL_P2,
  15. .adc_enable = CTRL_P2_SP2,
  16. .vbat_mult = TWL6030_VBAT_MULT,
  17. .vbat_shift = TWL6030_VBAT_SHIFT,
  18. };
  19. static struct twl6030_data twl6032_info = {
  20. .chip_type = chip_TWL6032,
  21. .adc_rbase = TWL6032_GPCH0_LSB,
  22. .adc_ctrl = TWL6032_CTRL_P1,
  23. .adc_enable = CTRL_P1_SP1,
  24. .vbat_mult = TWL6032_VBAT_MULT,
  25. .vbat_shift = TWL6032_VBAT_SHIFT,
  26. };
  27. static int twl6030_gpadc_read_channel(u8 channel_no)
  28. {
  29. u8 lsb = 0;
  30. u8 msb = 0;
  31. int ret = 0;
  32. ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC,
  33. twl->adc_rbase + channel_no * 2, &lsb);
  34. if (ret)
  35. return ret;
  36. ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC,
  37. twl->adc_rbase + 1 + channel_no * 2, &msb);
  38. if (ret)
  39. return ret;
  40. return (msb << 8) | lsb;
  41. }
  42. static int twl6030_gpadc_sw2_trigger(void)
  43. {
  44. u8 val;
  45. int ret = 0;
  46. ret = twl6030_i2c_write_u8(TWL6030_CHIP_ADC,
  47. twl->adc_ctrl, twl->adc_enable);
  48. if (ret)
  49. return ret;
  50. /* Waiting until the SW1 conversion ends*/
  51. val = CTRL_P2_BUSY;
  52. while (!((val & CTRL_P2_EOCP2) && (!(val & CTRL_P2_BUSY)))) {
  53. ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC,
  54. twl->adc_ctrl, &val);
  55. if (ret)
  56. return ret;
  57. udelay(1000);
  58. }
  59. return 0;
  60. }
  61. void twl6030_stop_usb_charging(void)
  62. {
  63. twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CONTROLLER_CTRL1, 0);
  64. return;
  65. }
  66. void twl6030_start_usb_charging(void)
  67. {
  68. twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
  69. CHARGERUSB_VICHRG, CHARGERUSB_VICHRG_1500);
  70. twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
  71. CHARGERUSB_CINLIMIT, CHARGERUSB_CIN_LIMIT_NONE);
  72. twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
  73. CONTROLLER_INT_MASK, MBAT_TEMP);
  74. twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
  75. CHARGERUSB_INT_MASK, MASK_MCHARGERUSB_THMREG);
  76. twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
  77. CHARGERUSB_VOREG, CHARGERUSB_VOREG_4P0);
  78. twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
  79. CHARGERUSB_CTRL2, CHARGERUSB_CTRL2_VITERM_400);
  80. twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_CTRL1, TERM);
  81. /* Enable USB charging */
  82. twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
  83. CONTROLLER_CTRL1, CONTROLLER_CTRL1_EN_CHARGER);
  84. return;
  85. }
  86. int twl6030_get_battery_current(void)
  87. {
  88. int battery_current = 0;
  89. u8 msb = 0;
  90. u8 lsb = 0;
  91. twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, FG_REG_11, &msb);
  92. twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, FG_REG_10, &lsb);
  93. battery_current = ((msb << 8) | lsb);
  94. /* convert 10 bit signed number to 16 bit signed number */
  95. if (battery_current >= 0x2000)
  96. battery_current = (battery_current - 0x4000);
  97. battery_current = battery_current * 3000 / 4096;
  98. printf("Battery Current: %d mA\n", battery_current);
  99. return battery_current;
  100. }
  101. int twl6030_get_battery_voltage(void)
  102. {
  103. int battery_volt = 0;
  104. int ret = 0;
  105. u8 vbatch;
  106. if (twl->chip_type == chip_TWL6030) {
  107. vbatch = TWL6030_GPADC_VBAT_CHNL;
  108. } else {
  109. ret = twl6030_i2c_write_u8(TWL6030_CHIP_ADC,
  110. TWL6032_GPSELECT_ISB,
  111. TWL6032_GPADC_VBAT_CHNL);
  112. if (ret)
  113. return ret;
  114. vbatch = 0;
  115. }
  116. /* Start GPADC SW conversion */
  117. ret = twl6030_gpadc_sw2_trigger();
  118. if (ret) {
  119. printf("Failed to convert battery voltage\n");
  120. return ret;
  121. }
  122. /* measure Vbat voltage */
  123. battery_volt = twl6030_gpadc_read_channel(vbatch);
  124. if (battery_volt < 0) {
  125. printf("Failed to read battery voltage\n");
  126. return ret;
  127. }
  128. battery_volt = (battery_volt * twl->vbat_mult) >> twl->vbat_shift;
  129. printf("Battery Voltage: %d mV\n", battery_volt);
  130. return battery_volt;
  131. }
  132. void twl6030_init_battery_charging(void)
  133. {
  134. u8 val = 0;
  135. int battery_volt = 0;
  136. int ret = 0;
  137. ret = twl6030_i2c_read_u8(TWL6030_CHIP_USB, USB_PRODUCT_ID_LSB, &val);
  138. if (ret) {
  139. puts("twl6030_init_battery_charging(): could not determine chip!\n");
  140. return;
  141. }
  142. if (val == 0x30) {
  143. twl = &twl6030_info;
  144. } else if (val == 0x32) {
  145. twl = &twl6032_info;
  146. } else {
  147. puts("twl6030_init_battery_charging(): unsupported chip type\n");
  148. return;
  149. }
  150. /* Enable VBAT measurement */
  151. if (twl->chip_type == chip_TWL6030) {
  152. twl6030_i2c_write_u8(TWL6030_CHIP_PM, MISC1, VBAT_MEAS);
  153. twl6030_i2c_write_u8(TWL6030_CHIP_ADC,
  154. TWL6030_GPADC_CTRL,
  155. GPADC_CTRL_SCALER_DIV4);
  156. } else {
  157. twl6030_i2c_write_u8(TWL6030_CHIP_ADC,
  158. TWL6032_GPADC_CTRL2,
  159. GPADC_CTRL2_CH18_SCALER_EN);
  160. }
  161. /* Enable GPADC module */
  162. ret = twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, TOGGLE1, FGS | GPADCS);
  163. if (ret) {
  164. printf("Failed to enable GPADC\n");
  165. return;
  166. }
  167. battery_volt = twl6030_get_battery_voltage();
  168. if (battery_volt < 0)
  169. return;
  170. if (battery_volt < 3000)
  171. printf("Main battery voltage too low!\n");
  172. /* Check for the presence of USB charger */
  173. twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, CONTROLLER_STAT1, &val);
  174. /* check for battery presence indirectly via Fuel gauge */
  175. if ((val & VBUS_DET) && (battery_volt < 3300))
  176. twl6030_start_usb_charging();
  177. return;
  178. }
  179. void twl6030_power_mmc_init()
  180. {
  181. /* set voltage to 3.0 and turnon for APP */
  182. twl6030_i2c_write_u8(TWL6030_CHIP_PM, VMMC_CFG_VOLTATE, 0x15);
  183. twl6030_i2c_write_u8(TWL6030_CHIP_PM, VMMC_CFG_STATE, 0x21);
  184. }
  185. void twl6030_usb_device_settings()
  186. {
  187. u8 data = 0;
  188. /* Select APP Group and set state to ON */
  189. twl6030_i2c_write_u8(TWL6030_CHIP_PM, VUSB_CFG_STATE, 0x21);
  190. twl6030_i2c_read_u8(TWL6030_CHIP_PM, MISC2, &data);
  191. data |= 0x10;
  192. /* Select the input supply for VBUS regulator */
  193. twl6030_i2c_write_u8(TWL6030_CHIP_PM, MISC2, data);
  194. }
  195. #endif