1/* 2 * Copyright (c) 2012, ETH Zurich. 3 * All rights reserved. 4 * 5 * This file is distributed under the terms in the attached LICENSE file. 6 * If you do not find this file, copies can be found by writing to: 7 * ETH Zurich D-INFK, CAB F.78, Universitaetstr 6, CH-8092 Zurich. 8 */ 9#include "i2c.h" 10#include "twl6030.h" 11 12// I2C slave address for id1 reads and writes is 0x48 13#define ID1_I2C_ADDR 0x48 14 15 16inline uint8_t _ti_twl6030_id1_read_8(void *d, size_t off) 17{ 18 errval_t err; 19 20 struct i2c_msg msg[2]; 21 22 uint8_t reg = off & 0xff; 23 uint8_t result = 0; 24 25 TWL_DEBUG("id1_read_8(reg=0x%"PRIx8")\n", reg); 26 27 /* set register to read from */ 28 msg[0].slave = ID1_I2C_ADDR; 29 msg[0].flags = I2C_WR | I2C_NOSTOP; 30 msg[0].length = 1; 31 msg[0].buf = ® 32 33 /* read data back */ 34 msg[1].slave = ID1_I2C_ADDR; 35 msg[1].flags = I2C_RD; 36 msg[1].length = 1; 37 msg[1].buf = &result; 38 39 err = ti_i2c_transfer(I2C_HC, msg, 2); 40 41 if (err_is_fail(err)) { 42 TWL_DEBUG("ti_i2c_transfer: %"PRIuERRV"\n", err); 43 return 0; 44 } 45 46 return result; 47} 48 49inline void _ti_twl6030_id1_write_8(void *d, size_t off, uint8_t regval) 50{ 51 struct i2c_msg msg; 52 errval_t err; 53 54 uint8_t addr = off & 0xff; 55 uint8_t msgbuf[2]; 56 57 msgbuf[0] = addr; 58 msgbuf[1] = regval; 59 60 msg.slave = ID1_I2C_ADDR; 61 msg.flags = I2C_WR; 62 msg.length = 2; 63 msg.buf = msgbuf; 64 65 err = ti_i2c_transfer(I2C_HC, &msg, 1); 66 67 if (err_is_fail(err)) { 68 TWL_DEBUG("ti_i2c_transfer failed in mackerel: %"PRIuERRV"\n", err); 69 } 70 71 return; 72} 73 74void ti_twl6030_init(struct twl6030_driver_state* st) 75{ 76 TWL_DEBUG("%s:%d\n", __FUNCTION__, __LINE__); 77 ti_i2c_init(st, I2C_HC); 78} 79 80void ti_twl6030_vmmc_pr(ti_twl6030_t twl) 81{ 82#define PBS (8*1024) 83static char PRBUF[PBS]; 84#define PRBUFL PRBUF, (PBS-1) 85 86 ti_twl6030_pr(PRBUFL, &twl); 87 TWL_DEBUG("%s\n", PRBUF); 88} 89 90static ti_twl6030_vsel_t millis_to_vsel(int millis) 91{ 92 switch (millis) { 93 case 0: 94 return ti_twl6030_v0v0; 95 case 1000: 96 return ti_twl6030_v1v0; 97 case 1100: 98 return ti_twl6030_v1v1; 99 case 1200: 100 return ti_twl6030_v1v2; 101 case 1300: 102 return ti_twl6030_v1v3; 103 case 1400: 104 return ti_twl6030_v1v4; 105 case 1500: 106 return ti_twl6030_v1v5; 107 case 1600: 108 return ti_twl6030_v1v6; 109 case 1700: 110 return ti_twl6030_v1v7; 111 case 1800: 112 return ti_twl6030_v1v8; 113 case 1900: 114 return ti_twl6030_v1v9; 115 case 2000: 116 return ti_twl6030_v2v0; 117 case 2100: 118 return ti_twl6030_v2v1; 119 case 2200: 120 return ti_twl6030_v2v2; 121 case 2300: 122 return ti_twl6030_v2v3; 123 case 2400: 124 return ti_twl6030_v2v4; 125 case 2500: 126 return ti_twl6030_v2v5; 127 case 2600: 128 return ti_twl6030_v2v6; 129 case 2700: 130 return ti_twl6030_v2v7; 131 case 2750: 132 return ti_twl6030_v2v75; 133 case 2800: 134 return ti_twl6030_v2v8; 135 case 2900: 136 return ti_twl6030_v2v9; 137 case 3000: 138 return ti_twl6030_v3v0; 139 case 3100: 140 return ti_twl6030_v3v1; 141 case 3200: 142 return ti_twl6030_v3v2; 143 case 3300: 144 return ti_twl6030_v3v3; 145 default: 146 TWL_DEBUG("voltage (%d) not available, returning 0.0V\n", millis); 147 return ti_twl6030_v0v0; 148 } 149} 150 151 152void ti_twl6030_vmmc_off(ti_twl6030_t twl) 153{ 154 // turn off 155 ti_twl6030_cfg_state_w_t st = ti_twl6030_cfg_state_w_default; 156 st = ti_twl6030_cfg_state_w_grp_app_insert(st, 0x1); 157 st = ti_twl6030_cfg_state_w_grp_con_insert(st, 0x1); 158 st = ti_twl6030_cfg_state_w_grp_mod_insert(st, 0x1); 159 st = ti_twl6030_cfg_state_w_state_insert(st, 0x0); 160 161 ti_twl6030_vmmc_cfg_state_w_rawwr(&twl, st); 162} 163 164void ti_twl6030_vmmc_on(ti_twl6030_t twl) 165{ 166 // turn on 167 ti_twl6030_cfg_state_w_t st = ti_twl6030_cfg_state_w_default; 168 st = ti_twl6030_cfg_state_w_grp_app_insert(st, 0x1); 169 st = ti_twl6030_cfg_state_w_grp_con_insert(st, 0x1); 170 st = ti_twl6030_cfg_state_w_grp_mod_insert(st, 0x1); 171 st = ti_twl6030_cfg_state_w_state_insert(st, 0x1); 172 ti_twl6030_vmmc_cfg_state_w_wr(&twl, st); 173} 174 175static volatile uint32_t dummy = 0; 176static void wait_msec(long msec) 177{ 178 int i = 0, sum = 0; 179 long end = (1200000 * msec / 8); 180 181 // Cannot use volatile variables in loop 182 while (++i < end) { 183 sum += i + end; 184 } 185 186 dummy += sum; 187} 188 189 190errval_t ti_twl6030_set_vmmc_vsel(ti_twl6030_t twl, int millis) 191{ 192 TWL_DEBUG("ti_twl6030_vmmc_vsel\n"); 193 //ti_twl6030_mmcctrl_vmmc_auto_off_wrf(&twl, 0x0); 194 ti_twl6030_mmcctrl_sw_fc_wrf(&twl, 0x1); 195 196 ti_twl6030_vmmc_off(twl); 197 wait_msec(10); 198 199 ti_twl6030_vsel_t vsel = millis_to_vsel(millis); 200 ti_twl6030_vmmc_cfg_voltage_vsel_wrf(&twl, vsel); 201 202 ti_twl6030_vmmc_on(twl); 203 //ti_twl6030_mmcctrl_vmmc_auto_off_wrf(&twl, 0x0); 204 205 ti_twl6030_vmmc_pr(twl); 206 207 208 return SYS_ERR_OK; 209} 210