/* * Copyright 2013 Freescale Semiconductor, Inc. * * SPDX-License-Identifier: GPL-2.0+ */ /* Power-One ZM7300 DPM */ #include "zm7300.h" #define DPM_WP 0x96 #define WRP_OPCODE 0x01 #define WRM_OPCODE 0x02 #define RRP_OPCODE 0x11 #define DPM_SUCCESS 0x01 #define DPM_EXEC_FAIL 0x00 static const uint16_t hex_to_1_10mv[] = { 5000, 5125, 5250, 5375, 5500, 5625, 5750, 5875, 6000, 6125, 6250, 6375, 6500, 6625, 6750, 6875, 7000, 7125, 7250, 7375, 7500, 7625, 7750, 7875, 8000, 8125, 8250, 8375, 8500, 8625, 8750, 8875, 9000, 9125, 9250, 9375, 9500, /* 0.95mV */ 9625, 9750, 9875, 10000, /* 1.0V */ 10125, 10250, 10375, 10500, 10625, 10750, 10875, 11000, 11125, 11250, 11375, 11500, 11625, 11750, 11875, 12000, 12125, 12250, 12375, 0, /* reserved */ }; /* Read Data d from Register r of POL p */ u8 dpm_rrp(uchar r) { u8 ret[5]; ret[0] = RRP_OPCODE; /* POL is 0 */ ret[1] = 0; ret[2] = r; i2c_read(I2C_DPM_ADDR, 0, -3, ret, 2); if (ret[1] == DPM_SUCCESS) { /* the DPM returned success as status */ debug("RRP_OPCODE returned success data is %x\n", ret[0]); return ret[0]; } else { return -1; } } /* Write Data d into DPM register r (RAM) */ int dpm_wrm(u8 r, u8 d) { u8 ret[5]; ret[0] = WRM_OPCODE; ret[1] = r; ret[2] = d; i2c_read(I2C_DPM_ADDR, 0, -3, ret, 1); if (ret[0] == DPM_SUCCESS) { /* the DPM returned success as status */ debug("WRM_OPCODE returned success data is %x\n", ret[0]); return ret[0]; } else { return -1; } } /* Write Data d into Register r of POL(s) a */ int dpm_wrp(u8 r, u8 d) { u8 ret[7]; ret[0] = WRP_OPCODE; /* only POL0 is present */ ret[1] = 0x01; ret[2] = 0x00; ret[3] = 0x00; ret[4] = 0x00; ret[5] = r; ret[6] = d; i2c_read(I2C_DPM_ADDR, 0, -7, ret, 1); if (ret[0] == DPM_SUCCESS) { /* the DPM returned success as status */ debug("WRP_OPCODE returned success data is %x\n", ret[0]); return 0; } else { return -1; } } /* Uses the DPM command RRP */ u8 zm_read(uchar reg) { u8 d; d = dpm_rrp(reg); return d; } /* ZM_write -- Steps: a. Write data to the register b. Read data from register and compare to written value c. Return return_code & voltage_read */ u8 zm_write(u8 reg, u8 data) { u8 d; /* write data to register */ dpm_wrp(reg, data); /* read register and compare to written value */ d = dpm_rrp(reg); if (d != data) { printf("zm_write : Comparison register data failed\n"); return -1; } return d; } /* zm_write_out_voltage * voltage in 1/10 mV */ int zm_write_voltage(int voltage) { u8 reg = 0x7, vid; uint16_t voltage_read; u8 ret; vid = (voltage - 5000) / ZM_STEP; ret = zm_write(reg, vid); if (ret != -1) { voltage_read = hex_to_1_10mv[ret]; debug("voltage set to %dmV\n", voltage_read/10); return voltage_read; } return -1; } /* zm_read_out_voltage * voltage in 1/10 mV */ int zm_read_voltage(void) { u8 reg = 0x7; u8 ret; int voltage; ret = zm_read(reg); if (ret != -1) { voltage = hex_to_1_10mv[ret]; debug("Voltage read is %dmV\n", voltage/10); return voltage; } else { return -1; } } int zm_disable_wp() { u8 new_wp_value; /* Disable using Write-Protect register 0x96 */ new_wp_value = 0x8; if ((dpm_wrm(DPM_WP, new_wp_value)) < 0) { printf("Disable Write-Protect register failed\n"); return -1; } return 0; } int zm_enable_wp() { u8 orig_wp_value; orig_wp_value = 0x0; /* Enable using Write-Protect register 0x96 */ if ((dpm_wrm(DPM_WP, orig_wp_value)) < 0) { printf("Enable Write-Protect register failed\n"); return -1; } return 0; }