| // SPDX-License-Identifier: GPL-2.0+ |
| /* |
| * Copyright 2013 Freescale Semiconductor, Inc. |
| */ |
| |
| /* Power-One ZM7300 DPM */ |
| #include "zm7300.h" |
| #include <log.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) |
| { |
| return dpm_rrp(reg); |
| } |
| |
| /* 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; |
| } |