1200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck/* 2200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck * Hardware monitoring driver for ZL6100 and compatibles 3200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck * 4200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck * Copyright (c) 2011 Ericsson AB. 5200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck * 6200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck * This program is free software; you can redistribute it and/or modify 7200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck * it under the terms of the GNU General Public License as published by 8200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck * the Free Software Foundation; either version 2 of the License, or 9200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck * (at your option) any later version. 10200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck * 11200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck * This program is distributed in the hope that it will be useful, 12200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck * but WITHOUT ANY WARRANTY; without even the implied warranty of 13200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck * GNU General Public License for more details. 15200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck * 16200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck * You should have received a copy of the GNU General Public License 17200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck * along with this program; if not, write to the Free Software 18200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck */ 20200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 21200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck#include <linux/kernel.h> 22200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck#include <linux/module.h> 23200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck#include <linux/init.h> 24200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck#include <linux/err.h> 25200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck#include <linux/slab.h> 26200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck#include <linux/i2c.h> 27200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck#include <linux/ktime.h> 28200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck#include <linux/delay.h> 29200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck#include "pmbus.h" 30200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 313360a106f8b4f87d3f3b0f1fd06c0c66fe45a87bGuenter Roeckenum chips { zl2004, zl2005, zl2006, zl2008, zl2105, zl2106, zl6100, zl6105, 323360a106f8b4f87d3f3b0f1fd06c0c66fe45a87bGuenter Roeck zl9101, zl9117 }; 33200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 34200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeckstruct zl6100_data { 35200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck int id; 36200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck ktime_t access; /* chip access time */ 377ad6307ad6968ce25cecf209d4822d4c722be030Guenter Roeck int delay; /* Delay between chip accesses in uS */ 38200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck struct pmbus_driver_info info; 39200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck}; 40200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 41200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck#define to_zl6100_data(x) container_of(x, struct zl6100_data, info) 42200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 4356badacb922ac6117c8231716265301118b22b17Guenter Roeck#define ZL6100_MFR_CONFIG 0xd0 44200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck#define ZL6100_DEVICE_ID 0xe4 45200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 4656badacb922ac6117c8231716265301118b22b17Guenter Roeck#define ZL6100_MFR_XTEMP_ENABLE (1 << 7) 4756badacb922ac6117c8231716265301118b22b17Guenter Roeck 48200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck#define ZL6100_WAIT_TIME 1000 /* uS */ 49200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 50200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeckstatic ushort delay = ZL6100_WAIT_TIME; 51200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeckmodule_param(delay, ushort, 0644); 52200855e52db1b1834121ba57fbd89c5b4911e02cGuenter RoeckMODULE_PARM_DESC(delay, "Delay between chip accesses in uS"); 53200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 54200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck/* Some chips need a delay between accesses */ 55200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeckstatic inline void zl6100_wait(const struct zl6100_data *data) 56200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck{ 577ad6307ad6968ce25cecf209d4822d4c722be030Guenter Roeck if (data->delay) { 58200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck s64 delta = ktime_us_delta(ktime_get(), data->access); 597ad6307ad6968ce25cecf209d4822d4c722be030Guenter Roeck if (delta < data->delay) 607ad6307ad6968ce25cecf209d4822d4c722be030Guenter Roeck udelay(data->delay - delta); 61200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck } 62200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck} 63200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 64200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeckstatic int zl6100_read_word_data(struct i2c_client *client, int page, int reg) 65200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck{ 66200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 67200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck struct zl6100_data *data = to_zl6100_data(info); 68200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck int ret; 69200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 70200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck if (page || reg >= PMBUS_VIRT_BASE) 71200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck return -ENXIO; 72200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 73bc581e6fcc3bd901d20765638422ef957559a8d1Guenter Roeck if (data->id == zl2005) { 74bc581e6fcc3bd901d20765638422ef957559a8d1Guenter Roeck /* 75bc581e6fcc3bd901d20765638422ef957559a8d1Guenter Roeck * Limit register detection is not reliable on ZL2005. 76bc581e6fcc3bd901d20765638422ef957559a8d1Guenter Roeck * Make sure registers are not erroneously detected. 77bc581e6fcc3bd901d20765638422ef957559a8d1Guenter Roeck */ 78bc581e6fcc3bd901d20765638422ef957559a8d1Guenter Roeck switch (reg) { 79bc581e6fcc3bd901d20765638422ef957559a8d1Guenter Roeck case PMBUS_VOUT_OV_WARN_LIMIT: 80bc581e6fcc3bd901d20765638422ef957559a8d1Guenter Roeck case PMBUS_VOUT_UV_WARN_LIMIT: 81bc581e6fcc3bd901d20765638422ef957559a8d1Guenter Roeck case PMBUS_IOUT_OC_WARN_LIMIT: 82bc581e6fcc3bd901d20765638422ef957559a8d1Guenter Roeck return -ENXIO; 83bc581e6fcc3bd901d20765638422ef957559a8d1Guenter Roeck } 84bc581e6fcc3bd901d20765638422ef957559a8d1Guenter Roeck } 85bc581e6fcc3bd901d20765638422ef957559a8d1Guenter Roeck 86200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck zl6100_wait(data); 87200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck ret = pmbus_read_word_data(client, page, reg); 88200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck data->access = ktime_get(); 89200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 90200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck return ret; 91200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck} 92200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 93200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeckstatic int zl6100_read_byte_data(struct i2c_client *client, int page, int reg) 94200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck{ 95200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 96200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck struct zl6100_data *data = to_zl6100_data(info); 97200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck int ret; 98200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 99200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck if (page > 0) 100200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck return -ENXIO; 101200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 102200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck zl6100_wait(data); 103200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck ret = pmbus_read_byte_data(client, page, reg); 104200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck data->access = ktime_get(); 105200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 106200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck return ret; 107200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck} 108200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 109200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeckstatic int zl6100_write_word_data(struct i2c_client *client, int page, int reg, 110200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck u16 word) 111200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck{ 112200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 113200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck struct zl6100_data *data = to_zl6100_data(info); 114200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck int ret; 115200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 116200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck if (page || reg >= PMBUS_VIRT_BASE) 117200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck return -ENXIO; 118200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 119200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck zl6100_wait(data); 120200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck ret = pmbus_write_word_data(client, page, reg, word); 121200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck data->access = ktime_get(); 122200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 123200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck return ret; 124200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck} 125200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 126200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeckstatic int zl6100_write_byte(struct i2c_client *client, int page, u8 value) 127200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck{ 128200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 129200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck struct zl6100_data *data = to_zl6100_data(info); 130200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck int ret; 131200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 132200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck if (page > 0) 133200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck return -ENXIO; 134200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 135200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck zl6100_wait(data); 136200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck ret = pmbus_write_byte(client, page, value); 137200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck data->access = ktime_get(); 138200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 139200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck return ret; 140200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck} 141200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 142200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeckstatic const struct i2c_device_id zl6100_id[] = { 143443830f6fd986b894da2ea7403163a64c0925f54Guenter Roeck {"bmr450", zl2005}, 144443830f6fd986b894da2ea7403163a64c0925f54Guenter Roeck {"bmr451", zl2005}, 145443830f6fd986b894da2ea7403163a64c0925f54Guenter Roeck {"bmr462", zl2008}, 146443830f6fd986b894da2ea7403163a64c0925f54Guenter Roeck {"bmr463", zl2008}, 147443830f6fd986b894da2ea7403163a64c0925f54Guenter Roeck {"bmr464", zl2008}, 148200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck {"zl2004", zl2004}, 149bc581e6fcc3bd901d20765638422ef957559a8d1Guenter Roeck {"zl2005", zl2005}, 150200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck {"zl2006", zl2006}, 151200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck {"zl2008", zl2008}, 152200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck {"zl2105", zl2105}, 153200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck {"zl2106", zl2106}, 154200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck {"zl6100", zl6100}, 155200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck {"zl6105", zl6105}, 1563360a106f8b4f87d3f3b0f1fd06c0c66fe45a87bGuenter Roeck {"zl9101", zl9101}, 1573360a106f8b4f87d3f3b0f1fd06c0c66fe45a87bGuenter Roeck {"zl9117", zl9117}, 158200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck { } 159200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck}; 160200855e52db1b1834121ba57fbd89c5b4911e02cGuenter RoeckMODULE_DEVICE_TABLE(i2c, zl6100_id); 161200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 162200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeckstatic int zl6100_probe(struct i2c_client *client, 163200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck const struct i2c_device_id *id) 164200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck{ 165200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck int ret; 166200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck struct zl6100_data *data; 167200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck struct pmbus_driver_info *info; 168200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck u8 device_id[I2C_SMBUS_BLOCK_MAX + 1]; 169200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck const struct i2c_device_id *mid; 170200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 171200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck if (!i2c_check_functionality(client->adapter, 17256badacb922ac6117c8231716265301118b22b17Guenter Roeck I2C_FUNC_SMBUS_READ_WORD_DATA 173200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck | I2C_FUNC_SMBUS_READ_BLOCK_DATA)) 174200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck return -ENODEV; 175200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 176200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck ret = i2c_smbus_read_block_data(client, ZL6100_DEVICE_ID, 177200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck device_id); 178200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck if (ret < 0) { 179200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck dev_err(&client->dev, "Failed to read device ID\n"); 180200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck return ret; 181200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck } 182200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck device_id[ret] = '\0'; 183200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck dev_info(&client->dev, "Device ID %s\n", device_id); 184200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 185200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck mid = NULL; 186200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck for (mid = zl6100_id; mid->name[0]; mid++) { 187200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck if (!strncasecmp(mid->name, device_id, strlen(mid->name))) 188200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck break; 189200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck } 190200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck if (!mid->name[0]) { 191200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck dev_err(&client->dev, "Unsupported device\n"); 192200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck return -ENODEV; 193200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck } 194200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck if (id->driver_data != mid->driver_data) 195200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck dev_notice(&client->dev, 196200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck "Device mismatch: Configured %s, detected %s\n", 197200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck id->name, mid->name); 198200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 1998b313ca7f1b98263ce22519b25a9c2a362eeb898Guenter Roeck data = devm_kzalloc(&client->dev, sizeof(struct zl6100_data), 2008b313ca7f1b98263ce22519b25a9c2a362eeb898Guenter Roeck GFP_KERNEL); 201200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck if (!data) 202200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck return -ENOMEM; 203200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 204200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck data->id = mid->driver_data; 205200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 206200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck /* 207fecfb64422d91a9621a3f96ab75c3a5f13e80b58Guenter Roeck * According to information from the chip vendor, all currently 208fecfb64422d91a9621a3f96ab75c3a5f13e80b58Guenter Roeck * supported chips are known to require a wait time between I2C 209fecfb64422d91a9621a3f96ab75c3a5f13e80b58Guenter Roeck * accesses. 210200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck */ 2117ad6307ad6968ce25cecf209d4822d4c722be030Guenter Roeck data->delay = delay; 212200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 213200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck /* 214200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck * Since there was a direct I2C device access above, wait before 215200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck * accessing the chip again. 216200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck */ 217200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck data->access = ktime_get(); 218200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck zl6100_wait(data); 219200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 220200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck info = &data->info; 221200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 222200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck info->pages = 1; 223200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT 224200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 225200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT 22656badacb922ac6117c8231716265301118b22b17Guenter Roeck | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; 22756badacb922ac6117c8231716265301118b22b17Guenter Roeck 22856badacb922ac6117c8231716265301118b22b17Guenter Roeck ret = i2c_smbus_read_word_data(client, ZL6100_MFR_CONFIG); 22956badacb922ac6117c8231716265301118b22b17Guenter Roeck if (ret < 0) 2308b313ca7f1b98263ce22519b25a9c2a362eeb898Guenter Roeck return ret; 2318b313ca7f1b98263ce22519b25a9c2a362eeb898Guenter Roeck 23256badacb922ac6117c8231716265301118b22b17Guenter Roeck if (ret & ZL6100_MFR_XTEMP_ENABLE) 23356badacb922ac6117c8231716265301118b22b17Guenter Roeck info->func[0] |= PMBUS_HAVE_TEMP2; 23456badacb922ac6117c8231716265301118b22b17Guenter Roeck 23556badacb922ac6117c8231716265301118b22b17Guenter Roeck data->access = ktime_get(); 23656badacb922ac6117c8231716265301118b22b17Guenter Roeck zl6100_wait(data); 237200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 238200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck info->read_word_data = zl6100_read_word_data; 239200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck info->read_byte_data = zl6100_read_byte_data; 240200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck info->write_word_data = zl6100_write_word_data; 241200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck info->write_byte = zl6100_write_byte; 242200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 2438b313ca7f1b98263ce22519b25a9c2a362eeb898Guenter Roeck return pmbus_do_probe(client, mid, info); 244200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck} 245200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 246200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeckstatic struct i2c_driver zl6100_driver = { 247200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck .driver = { 248200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck .name = "zl6100", 249200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck }, 250200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck .probe = zl6100_probe, 251dd285ad7373bf5d21cceacb3b7a5eb8b72d37085Guenter Roeck .remove = pmbus_do_remove, 252200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck .id_table = zl6100_id, 253200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck}; 254200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 255f0967eea80ec2a19a4fe1ad27e3ff1b22c79a3c7Axel Linmodule_i2c_driver(zl6100_driver); 256200855e52db1b1834121ba57fbd89c5b4911e02cGuenter Roeck 257200855e52db1b1834121ba57fbd89c5b4911e02cGuenter RoeckMODULE_AUTHOR("Guenter Roeck"); 258200855e52db1b1834121ba57fbd89c5b4911e02cGuenter RoeckMODULE_DESCRIPTION("PMBus driver for ZL6100 and compatibles"); 259200855e52db1b1834121ba57fbd89c5b4911e02cGuenter RoeckMODULE_LICENSE("GPL"); 260