14150f242SShaveta Leekha /* 24150f242SShaveta Leekha * Copyright 2013 Freescale Semiconductor, Inc. 34150f242SShaveta Leekha * 44150f242SShaveta Leekha * SPDX-License-Identifier: GPL-2.0+ 54150f242SShaveta Leekha */ 64150f242SShaveta Leekha 74150f242SShaveta Leekha /* Power-One ZM7300 DPM */ 84150f242SShaveta Leekha #include "zm7300.h" 94150f242SShaveta Leekha 104150f242SShaveta Leekha #define DPM_WP 0x96 114150f242SShaveta Leekha #define WRP_OPCODE 0x01 124150f242SShaveta Leekha #define WRM_OPCODE 0x02 134150f242SShaveta Leekha #define RRP_OPCODE 0x11 144150f242SShaveta Leekha 154150f242SShaveta Leekha #define DPM_SUCCESS 0x01 164150f242SShaveta Leekha #define DPM_EXEC_FAIL 0x00 174150f242SShaveta Leekha 184150f242SShaveta Leekha static const uint16_t hex_to_1_10mv[] = { 194150f242SShaveta Leekha 5000, 204150f242SShaveta Leekha 5125, 214150f242SShaveta Leekha 5250, 224150f242SShaveta Leekha 5375, 234150f242SShaveta Leekha 5500, 244150f242SShaveta Leekha 5625, 254150f242SShaveta Leekha 5750, 264150f242SShaveta Leekha 5875, 274150f242SShaveta Leekha 6000, 284150f242SShaveta Leekha 6125, 294150f242SShaveta Leekha 6250, 304150f242SShaveta Leekha 6375, 314150f242SShaveta Leekha 6500, 324150f242SShaveta Leekha 6625, 334150f242SShaveta Leekha 6750, 344150f242SShaveta Leekha 6875, 354150f242SShaveta Leekha 7000, 364150f242SShaveta Leekha 7125, 374150f242SShaveta Leekha 7250, 384150f242SShaveta Leekha 7375, 394150f242SShaveta Leekha 7500, 404150f242SShaveta Leekha 7625, 414150f242SShaveta Leekha 7750, 424150f242SShaveta Leekha 7875, 434150f242SShaveta Leekha 8000, 444150f242SShaveta Leekha 8125, 454150f242SShaveta Leekha 8250, 464150f242SShaveta Leekha 8375, 474150f242SShaveta Leekha 8500, 484150f242SShaveta Leekha 8625, 494150f242SShaveta Leekha 8750, 504150f242SShaveta Leekha 8875, 514150f242SShaveta Leekha 9000, 524150f242SShaveta Leekha 9125, 534150f242SShaveta Leekha 9250, 544150f242SShaveta Leekha 9375, 554150f242SShaveta Leekha 9500, /* 0.95mV */ 564150f242SShaveta Leekha 9625, 574150f242SShaveta Leekha 9750, 584150f242SShaveta Leekha 9875, 594150f242SShaveta Leekha 10000, /* 1.0V */ 604150f242SShaveta Leekha 10125, 614150f242SShaveta Leekha 10250, 624150f242SShaveta Leekha 10375, 634150f242SShaveta Leekha 10500, 644150f242SShaveta Leekha 10625, 654150f242SShaveta Leekha 10750, 664150f242SShaveta Leekha 10875, 674150f242SShaveta Leekha 11000, 684150f242SShaveta Leekha 11125, 694150f242SShaveta Leekha 11250, 704150f242SShaveta Leekha 11375, 714150f242SShaveta Leekha 11500, 724150f242SShaveta Leekha 11625, 734150f242SShaveta Leekha 11750, 744150f242SShaveta Leekha 11875, 754150f242SShaveta Leekha 12000, 764150f242SShaveta Leekha 12125, 774150f242SShaveta Leekha 12250, 784150f242SShaveta Leekha 12375, 794150f242SShaveta Leekha 0, /* reserved */ 804150f242SShaveta Leekha }; 814150f242SShaveta Leekha 824150f242SShaveta Leekha 834150f242SShaveta Leekha /* Read Data d from Register r of POL p */ 844150f242SShaveta Leekha u8 dpm_rrp(uchar r) 854150f242SShaveta Leekha { 864150f242SShaveta Leekha u8 ret[5]; 874150f242SShaveta Leekha 884150f242SShaveta Leekha ret[0] = RRP_OPCODE; 894150f242SShaveta Leekha /* POL is 0 */ 904150f242SShaveta Leekha ret[1] = 0; 914150f242SShaveta Leekha ret[2] = r; 924150f242SShaveta Leekha i2c_read(I2C_DPM_ADDR, 0, -3, ret, 2); 934150f242SShaveta Leekha if (ret[1] == DPM_SUCCESS) { /* the DPM returned success as status */ 944150f242SShaveta Leekha debug("RRP_OPCODE returned success data is %x\n", ret[0]); 954150f242SShaveta Leekha return ret[0]; 964150f242SShaveta Leekha } else { 974150f242SShaveta Leekha return -1; 984150f242SShaveta Leekha } 994150f242SShaveta Leekha } 1004150f242SShaveta Leekha 1014150f242SShaveta Leekha /* Write Data d into DPM register r (RAM) */ 1024150f242SShaveta Leekha int dpm_wrm(u8 r, u8 d) 1034150f242SShaveta Leekha { 1044150f242SShaveta Leekha u8 ret[5]; 1054150f242SShaveta Leekha 1064150f242SShaveta Leekha ret[0] = WRM_OPCODE; 1074150f242SShaveta Leekha ret[1] = r; 1084150f242SShaveta Leekha ret[2] = d; 1094150f242SShaveta Leekha i2c_read(I2C_DPM_ADDR, 0, -3, ret, 1); 1104150f242SShaveta Leekha if (ret[0] == DPM_SUCCESS) { /* the DPM returned success as status */ 1114150f242SShaveta Leekha debug("WRM_OPCODE returned success data is %x\n", ret[0]); 1124150f242SShaveta Leekha return ret[0]; 1134150f242SShaveta Leekha } else { 1144150f242SShaveta Leekha return -1; 1154150f242SShaveta Leekha } 1164150f242SShaveta Leekha } 1174150f242SShaveta Leekha 1184150f242SShaveta Leekha /* Write Data d into Register r of POL(s) a */ 1194150f242SShaveta Leekha int dpm_wrp(u8 r, u8 d) 1204150f242SShaveta Leekha { 1214150f242SShaveta Leekha u8 ret[7]; 1224150f242SShaveta Leekha 1234150f242SShaveta Leekha ret[0] = WRP_OPCODE; 1244150f242SShaveta Leekha /* only POL0 is present */ 1254150f242SShaveta Leekha ret[1] = 0x01; 1264150f242SShaveta Leekha ret[2] = 0x00; 1274150f242SShaveta Leekha ret[3] = 0x00; 1284150f242SShaveta Leekha ret[4] = 0x00; 1294150f242SShaveta Leekha ret[5] = r; 1304150f242SShaveta Leekha ret[6] = d; 1314150f242SShaveta Leekha i2c_read(I2C_DPM_ADDR, 0, -7, ret, 1); 1324150f242SShaveta Leekha if (ret[0] == DPM_SUCCESS) { /* the DPM returned success as status */ 1334150f242SShaveta Leekha debug("WRP_OPCODE returned success data is %x\n", ret[0]); 1344150f242SShaveta Leekha return 0; 1354150f242SShaveta Leekha } else { 1364150f242SShaveta Leekha return -1; 1374150f242SShaveta Leekha } 1384150f242SShaveta Leekha } 1394150f242SShaveta Leekha 1404150f242SShaveta Leekha /* Uses the DPM command RRP */ 1414150f242SShaveta Leekha u8 zm_read(uchar reg) 1424150f242SShaveta Leekha { 143*63a7578eSMasahiro Yamada return dpm_rrp(reg); 1444150f242SShaveta Leekha } 1454150f242SShaveta Leekha 1464150f242SShaveta Leekha /* ZM_write -- 1474150f242SShaveta Leekha Steps: 1484150f242SShaveta Leekha a. Write data to the register 1494150f242SShaveta Leekha b. Read data from register and compare to written value 1504150f242SShaveta Leekha c. Return return_code & voltage_read 1514150f242SShaveta Leekha */ 1524150f242SShaveta Leekha u8 zm_write(u8 reg, u8 data) 1534150f242SShaveta Leekha { 1544150f242SShaveta Leekha u8 d; 1554150f242SShaveta Leekha 1564150f242SShaveta Leekha /* write data to register */ 1574150f242SShaveta Leekha dpm_wrp(reg, data); 1584150f242SShaveta Leekha 1594150f242SShaveta Leekha /* read register and compare to written value */ 1604150f242SShaveta Leekha d = dpm_rrp(reg); 1614150f242SShaveta Leekha if (d != data) { 1624150f242SShaveta Leekha printf("zm_write : Comparison register data failed\n"); 1634150f242SShaveta Leekha return -1; 1644150f242SShaveta Leekha } 1654150f242SShaveta Leekha 1664150f242SShaveta Leekha return d; 1674150f242SShaveta Leekha } 1684150f242SShaveta Leekha 1694150f242SShaveta Leekha /* zm_write_out_voltage 1704150f242SShaveta Leekha * voltage in 1/10 mV 1714150f242SShaveta Leekha */ 1724150f242SShaveta Leekha int zm_write_voltage(int voltage) 1734150f242SShaveta Leekha { 1744150f242SShaveta Leekha u8 reg = 0x7, vid; 1754150f242SShaveta Leekha uint16_t voltage_read; 1764150f242SShaveta Leekha u8 ret; 1774150f242SShaveta Leekha 1784150f242SShaveta Leekha vid = (voltage - 5000) / ZM_STEP; 1794150f242SShaveta Leekha 1804150f242SShaveta Leekha ret = zm_write(reg, vid); 1814150f242SShaveta Leekha if (ret != -1) { 1824150f242SShaveta Leekha voltage_read = hex_to_1_10mv[ret]; 1834150f242SShaveta Leekha debug("voltage set to %dmV\n", voltage_read/10); 1844150f242SShaveta Leekha return voltage_read; 1854150f242SShaveta Leekha } 1864150f242SShaveta Leekha return -1; 1874150f242SShaveta Leekha } 1884150f242SShaveta Leekha 1894150f242SShaveta Leekha /* zm_read_out_voltage 1904150f242SShaveta Leekha * voltage in 1/10 mV 1914150f242SShaveta Leekha */ 1924150f242SShaveta Leekha int zm_read_voltage(void) 1934150f242SShaveta Leekha { 1944150f242SShaveta Leekha u8 reg = 0x7; 1954150f242SShaveta Leekha u8 ret; 1964150f242SShaveta Leekha int voltage; 1974150f242SShaveta Leekha 1984150f242SShaveta Leekha ret = zm_read(reg); 1994150f242SShaveta Leekha if (ret != -1) { 2004150f242SShaveta Leekha voltage = hex_to_1_10mv[ret]; 2014150f242SShaveta Leekha debug("Voltage read is %dmV\n", voltage/10); 2024150f242SShaveta Leekha return voltage; 2034150f242SShaveta Leekha } else { 2044150f242SShaveta Leekha return -1; 2054150f242SShaveta Leekha } 2064150f242SShaveta Leekha } 2074150f242SShaveta Leekha 2084150f242SShaveta Leekha int zm_disable_wp() 2094150f242SShaveta Leekha { 2104150f242SShaveta Leekha u8 new_wp_value; 2114150f242SShaveta Leekha 2124150f242SShaveta Leekha /* Disable using Write-Protect register 0x96 */ 2134150f242SShaveta Leekha new_wp_value = 0x8; 2144150f242SShaveta Leekha if ((dpm_wrm(DPM_WP, new_wp_value)) < 0) { 2154150f242SShaveta Leekha printf("Disable Write-Protect register failed\n"); 2164150f242SShaveta Leekha return -1; 2174150f242SShaveta Leekha } 2184150f242SShaveta Leekha return 0; 2194150f242SShaveta Leekha } 2204150f242SShaveta Leekha 2214150f242SShaveta Leekha int zm_enable_wp() 2224150f242SShaveta Leekha { 2234150f242SShaveta Leekha u8 orig_wp_value; 2244150f242SShaveta Leekha orig_wp_value = 0x0; 2254150f242SShaveta Leekha 2264150f242SShaveta Leekha /* Enable using Write-Protect register 0x96 */ 2274150f242SShaveta Leekha if ((dpm_wrm(DPM_WP, orig_wp_value)) < 0) { 2284150f242SShaveta Leekha printf("Enable Write-Protect register failed\n"); 2294150f242SShaveta Leekha return -1; 2304150f242SShaveta Leekha } 2314150f242SShaveta Leekha return 0; 2324150f242SShaveta Leekha } 2334150f242SShaveta Leekha 234