1*4150f242SShaveta Leekha /* 2*4150f242SShaveta Leekha * Copyright 2013 Freescale Semiconductor, Inc. 3*4150f242SShaveta Leekha * 4*4150f242SShaveta Leekha * SPDX-License-Identifier: GPL-2.0+ 5*4150f242SShaveta Leekha */ 6*4150f242SShaveta Leekha 7*4150f242SShaveta Leekha /* Power-One ZM7300 DPM */ 8*4150f242SShaveta Leekha #include "zm7300.h" 9*4150f242SShaveta Leekha 10*4150f242SShaveta Leekha #define DPM_WP 0x96 11*4150f242SShaveta Leekha #define WRP_OPCODE 0x01 12*4150f242SShaveta Leekha #define WRM_OPCODE 0x02 13*4150f242SShaveta Leekha #define RRP_OPCODE 0x11 14*4150f242SShaveta Leekha 15*4150f242SShaveta Leekha #define DPM_SUCCESS 0x01 16*4150f242SShaveta Leekha #define DPM_EXEC_FAIL 0x00 17*4150f242SShaveta Leekha 18*4150f242SShaveta Leekha static const uint16_t hex_to_1_10mv[] = { 19*4150f242SShaveta Leekha 5000, 20*4150f242SShaveta Leekha 5125, 21*4150f242SShaveta Leekha 5250, 22*4150f242SShaveta Leekha 5375, 23*4150f242SShaveta Leekha 5500, 24*4150f242SShaveta Leekha 5625, 25*4150f242SShaveta Leekha 5750, 26*4150f242SShaveta Leekha 5875, 27*4150f242SShaveta Leekha 6000, 28*4150f242SShaveta Leekha 6125, 29*4150f242SShaveta Leekha 6250, 30*4150f242SShaveta Leekha 6375, 31*4150f242SShaveta Leekha 6500, 32*4150f242SShaveta Leekha 6625, 33*4150f242SShaveta Leekha 6750, 34*4150f242SShaveta Leekha 6875, 35*4150f242SShaveta Leekha 7000, 36*4150f242SShaveta Leekha 7125, 37*4150f242SShaveta Leekha 7250, 38*4150f242SShaveta Leekha 7375, 39*4150f242SShaveta Leekha 7500, 40*4150f242SShaveta Leekha 7625, 41*4150f242SShaveta Leekha 7750, 42*4150f242SShaveta Leekha 7875, 43*4150f242SShaveta Leekha 8000, 44*4150f242SShaveta Leekha 8125, 45*4150f242SShaveta Leekha 8250, 46*4150f242SShaveta Leekha 8375, 47*4150f242SShaveta Leekha 8500, 48*4150f242SShaveta Leekha 8625, 49*4150f242SShaveta Leekha 8750, 50*4150f242SShaveta Leekha 8875, 51*4150f242SShaveta Leekha 9000, 52*4150f242SShaveta Leekha 9125, 53*4150f242SShaveta Leekha 9250, 54*4150f242SShaveta Leekha 9375, 55*4150f242SShaveta Leekha 9500, /* 0.95mV */ 56*4150f242SShaveta Leekha 9625, 57*4150f242SShaveta Leekha 9750, 58*4150f242SShaveta Leekha 9875, 59*4150f242SShaveta Leekha 10000, /* 1.0V */ 60*4150f242SShaveta Leekha 10125, 61*4150f242SShaveta Leekha 10250, 62*4150f242SShaveta Leekha 10375, 63*4150f242SShaveta Leekha 10500, 64*4150f242SShaveta Leekha 10625, 65*4150f242SShaveta Leekha 10750, 66*4150f242SShaveta Leekha 10875, 67*4150f242SShaveta Leekha 11000, 68*4150f242SShaveta Leekha 11125, 69*4150f242SShaveta Leekha 11250, 70*4150f242SShaveta Leekha 11375, 71*4150f242SShaveta Leekha 11500, 72*4150f242SShaveta Leekha 11625, 73*4150f242SShaveta Leekha 11750, 74*4150f242SShaveta Leekha 11875, 75*4150f242SShaveta Leekha 12000, 76*4150f242SShaveta Leekha 12125, 77*4150f242SShaveta Leekha 12250, 78*4150f242SShaveta Leekha 12375, 79*4150f242SShaveta Leekha 0, /* reserved */ 80*4150f242SShaveta Leekha }; 81*4150f242SShaveta Leekha 82*4150f242SShaveta Leekha 83*4150f242SShaveta Leekha /* Read Data d from Register r of POL p */ 84*4150f242SShaveta Leekha u8 dpm_rrp(uchar r) 85*4150f242SShaveta Leekha { 86*4150f242SShaveta Leekha u8 ret[5]; 87*4150f242SShaveta Leekha 88*4150f242SShaveta Leekha ret[0] = RRP_OPCODE; 89*4150f242SShaveta Leekha /* POL is 0 */ 90*4150f242SShaveta Leekha ret[1] = 0; 91*4150f242SShaveta Leekha ret[2] = r; 92*4150f242SShaveta Leekha i2c_read(I2C_DPM_ADDR, 0, -3, ret, 2); 93*4150f242SShaveta Leekha if (ret[1] == DPM_SUCCESS) { /* the DPM returned success as status */ 94*4150f242SShaveta Leekha debug("RRP_OPCODE returned success data is %x\n", ret[0]); 95*4150f242SShaveta Leekha return ret[0]; 96*4150f242SShaveta Leekha } else { 97*4150f242SShaveta Leekha return -1; 98*4150f242SShaveta Leekha } 99*4150f242SShaveta Leekha } 100*4150f242SShaveta Leekha 101*4150f242SShaveta Leekha /* Write Data d into DPM register r (RAM) */ 102*4150f242SShaveta Leekha int dpm_wrm(u8 r, u8 d) 103*4150f242SShaveta Leekha { 104*4150f242SShaveta Leekha u8 ret[5]; 105*4150f242SShaveta Leekha 106*4150f242SShaveta Leekha ret[0] = WRM_OPCODE; 107*4150f242SShaveta Leekha ret[1] = r; 108*4150f242SShaveta Leekha ret[2] = d; 109*4150f242SShaveta Leekha i2c_read(I2C_DPM_ADDR, 0, -3, ret, 1); 110*4150f242SShaveta Leekha if (ret[0] == DPM_SUCCESS) { /* the DPM returned success as status */ 111*4150f242SShaveta Leekha debug("WRM_OPCODE returned success data is %x\n", ret[0]); 112*4150f242SShaveta Leekha return ret[0]; 113*4150f242SShaveta Leekha } else { 114*4150f242SShaveta Leekha return -1; 115*4150f242SShaveta Leekha } 116*4150f242SShaveta Leekha } 117*4150f242SShaveta Leekha 118*4150f242SShaveta Leekha /* Write Data d into Register r of POL(s) a */ 119*4150f242SShaveta Leekha int dpm_wrp(u8 r, u8 d) 120*4150f242SShaveta Leekha { 121*4150f242SShaveta Leekha u8 ret[7]; 122*4150f242SShaveta Leekha 123*4150f242SShaveta Leekha ret[0] = WRP_OPCODE; 124*4150f242SShaveta Leekha /* only POL0 is present */ 125*4150f242SShaveta Leekha ret[1] = 0x01; 126*4150f242SShaveta Leekha ret[2] = 0x00; 127*4150f242SShaveta Leekha ret[3] = 0x00; 128*4150f242SShaveta Leekha ret[4] = 0x00; 129*4150f242SShaveta Leekha ret[5] = r; 130*4150f242SShaveta Leekha ret[6] = d; 131*4150f242SShaveta Leekha i2c_read(I2C_DPM_ADDR, 0, -7, ret, 1); 132*4150f242SShaveta Leekha if (ret[0] == DPM_SUCCESS) { /* the DPM returned success as status */ 133*4150f242SShaveta Leekha debug("WRP_OPCODE returned success data is %x\n", ret[0]); 134*4150f242SShaveta Leekha return 0; 135*4150f242SShaveta Leekha } else { 136*4150f242SShaveta Leekha return -1; 137*4150f242SShaveta Leekha } 138*4150f242SShaveta Leekha } 139*4150f242SShaveta Leekha 140*4150f242SShaveta Leekha /* Uses the DPM command RRP */ 141*4150f242SShaveta Leekha u8 zm_read(uchar reg) 142*4150f242SShaveta Leekha { 143*4150f242SShaveta Leekha u8 d; 144*4150f242SShaveta Leekha d = dpm_rrp(reg); 145*4150f242SShaveta Leekha return d; 146*4150f242SShaveta Leekha } 147*4150f242SShaveta Leekha 148*4150f242SShaveta Leekha /* ZM_write -- 149*4150f242SShaveta Leekha Steps: 150*4150f242SShaveta Leekha a. Write data to the register 151*4150f242SShaveta Leekha b. Read data from register and compare to written value 152*4150f242SShaveta Leekha c. Return return_code & voltage_read 153*4150f242SShaveta Leekha */ 154*4150f242SShaveta Leekha u8 zm_write(u8 reg, u8 data) 155*4150f242SShaveta Leekha { 156*4150f242SShaveta Leekha u8 d; 157*4150f242SShaveta Leekha 158*4150f242SShaveta Leekha /* write data to register */ 159*4150f242SShaveta Leekha dpm_wrp(reg, data); 160*4150f242SShaveta Leekha 161*4150f242SShaveta Leekha /* read register and compare to written value */ 162*4150f242SShaveta Leekha d = dpm_rrp(reg); 163*4150f242SShaveta Leekha if (d != data) { 164*4150f242SShaveta Leekha printf("zm_write : Comparison register data failed\n"); 165*4150f242SShaveta Leekha return -1; 166*4150f242SShaveta Leekha } 167*4150f242SShaveta Leekha 168*4150f242SShaveta Leekha return d; 169*4150f242SShaveta Leekha } 170*4150f242SShaveta Leekha 171*4150f242SShaveta Leekha /* zm_write_out_voltage 172*4150f242SShaveta Leekha * voltage in 1/10 mV 173*4150f242SShaveta Leekha */ 174*4150f242SShaveta Leekha int zm_write_voltage(int voltage) 175*4150f242SShaveta Leekha { 176*4150f242SShaveta Leekha u8 reg = 0x7, vid; 177*4150f242SShaveta Leekha uint16_t voltage_read; 178*4150f242SShaveta Leekha u8 ret; 179*4150f242SShaveta Leekha 180*4150f242SShaveta Leekha vid = (voltage - 5000) / ZM_STEP; 181*4150f242SShaveta Leekha 182*4150f242SShaveta Leekha ret = zm_write(reg, vid); 183*4150f242SShaveta Leekha if (ret != -1) { 184*4150f242SShaveta Leekha voltage_read = hex_to_1_10mv[ret]; 185*4150f242SShaveta Leekha debug("voltage set to %dmV\n", voltage_read/10); 186*4150f242SShaveta Leekha return voltage_read; 187*4150f242SShaveta Leekha } 188*4150f242SShaveta Leekha return -1; 189*4150f242SShaveta Leekha } 190*4150f242SShaveta Leekha 191*4150f242SShaveta Leekha /* zm_read_out_voltage 192*4150f242SShaveta Leekha * voltage in 1/10 mV 193*4150f242SShaveta Leekha */ 194*4150f242SShaveta Leekha int zm_read_voltage(void) 195*4150f242SShaveta Leekha { 196*4150f242SShaveta Leekha u8 reg = 0x7; 197*4150f242SShaveta Leekha u8 ret; 198*4150f242SShaveta Leekha int voltage; 199*4150f242SShaveta Leekha 200*4150f242SShaveta Leekha ret = zm_read(reg); 201*4150f242SShaveta Leekha if (ret != -1) { 202*4150f242SShaveta Leekha voltage = hex_to_1_10mv[ret]; 203*4150f242SShaveta Leekha debug("Voltage read is %dmV\n", voltage/10); 204*4150f242SShaveta Leekha return voltage; 205*4150f242SShaveta Leekha } else { 206*4150f242SShaveta Leekha return -1; 207*4150f242SShaveta Leekha } 208*4150f242SShaveta Leekha } 209*4150f242SShaveta Leekha 210*4150f242SShaveta Leekha int zm_disable_wp() 211*4150f242SShaveta Leekha { 212*4150f242SShaveta Leekha u8 new_wp_value; 213*4150f242SShaveta Leekha 214*4150f242SShaveta Leekha /* Disable using Write-Protect register 0x96 */ 215*4150f242SShaveta Leekha new_wp_value = 0x8; 216*4150f242SShaveta Leekha if ((dpm_wrm(DPM_WP, new_wp_value)) < 0) { 217*4150f242SShaveta Leekha printf("Disable Write-Protect register failed\n"); 218*4150f242SShaveta Leekha return -1; 219*4150f242SShaveta Leekha } 220*4150f242SShaveta Leekha return 0; 221*4150f242SShaveta Leekha } 222*4150f242SShaveta Leekha 223*4150f242SShaveta Leekha int zm_enable_wp() 224*4150f242SShaveta Leekha { 225*4150f242SShaveta Leekha u8 orig_wp_value; 226*4150f242SShaveta Leekha orig_wp_value = 0x0; 227*4150f242SShaveta Leekha 228*4150f242SShaveta Leekha /* Enable using Write-Protect register 0x96 */ 229*4150f242SShaveta Leekha if ((dpm_wrm(DPM_WP, orig_wp_value)) < 0) { 230*4150f242SShaveta Leekha printf("Enable Write-Protect register failed\n"); 231*4150f242SShaveta Leekha return -1; 232*4150f242SShaveta Leekha } 233*4150f242SShaveta Leekha return 0; 234*4150f242SShaveta Leekha } 235*4150f242SShaveta Leekha 236