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