ucd9200.c (5340B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Hardware monitoring driver for ucd9200 series Digital PWM System Controllers 4 * 5 * Copyright (C) 2011 Ericsson AB. 6 */ 7 8#include <linux/kernel.h> 9#include <linux/module.h> 10#include <linux/of_device.h> 11#include <linux/init.h> 12#include <linux/err.h> 13#include <linux/slab.h> 14#include <linux/i2c.h> 15#include <linux/pmbus.h> 16#include "pmbus.h" 17 18#define UCD9200_PHASE_INFO 0xd2 19#define UCD9200_DEVICE_ID 0xfd 20 21enum chips { ucd9200, ucd9220, ucd9222, ucd9224, ucd9240, ucd9244, ucd9246, 22 ucd9248 }; 23 24static const struct i2c_device_id ucd9200_id[] = { 25 {"ucd9200", ucd9200}, 26 {"ucd9220", ucd9220}, 27 {"ucd9222", ucd9222}, 28 {"ucd9224", ucd9224}, 29 {"ucd9240", ucd9240}, 30 {"ucd9244", ucd9244}, 31 {"ucd9246", ucd9246}, 32 {"ucd9248", ucd9248}, 33 {} 34}; 35MODULE_DEVICE_TABLE(i2c, ucd9200_id); 36 37static const struct of_device_id __maybe_unused ucd9200_of_match[] = { 38 { 39 .compatible = "ti,cd9200", 40 .data = (void *)ucd9200 41 }, 42 { 43 .compatible = "ti,cd9220", 44 .data = (void *)ucd9220 45 }, 46 { 47 .compatible = "ti,cd9222", 48 .data = (void *)ucd9222 49 }, 50 { 51 .compatible = "ti,cd9224", 52 .data = (void *)ucd9224 53 }, 54 { 55 .compatible = "ti,cd9240", 56 .data = (void *)ucd9240 57 }, 58 { 59 .compatible = "ti,cd9244", 60 .data = (void *)ucd9244 61 }, 62 { 63 .compatible = "ti,cd9246", 64 .data = (void *)ucd9246 65 }, 66 { 67 .compatible = "ti,cd9248", 68 .data = (void *)ucd9248 69 }, 70 { }, 71}; 72MODULE_DEVICE_TABLE(of, ucd9200_of_match); 73 74static int ucd9200_probe(struct i2c_client *client) 75{ 76 u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1]; 77 struct pmbus_driver_info *info; 78 const struct i2c_device_id *mid; 79 enum chips chip; 80 int i, j, ret; 81 82 if (!i2c_check_functionality(client->adapter, 83 I2C_FUNC_SMBUS_BYTE_DATA | 84 I2C_FUNC_SMBUS_BLOCK_DATA)) 85 return -ENODEV; 86 87 ret = i2c_smbus_read_block_data(client, UCD9200_DEVICE_ID, 88 block_buffer); 89 if (ret < 0) { 90 dev_err(&client->dev, "Failed to read device ID\n"); 91 return ret; 92 } 93 block_buffer[ret] = '\0'; 94 dev_info(&client->dev, "Device ID %s\n", block_buffer); 95 96 for (mid = ucd9200_id; mid->name[0]; mid++) { 97 if (!strncasecmp(mid->name, block_buffer, strlen(mid->name))) 98 break; 99 } 100 if (!mid->name[0]) { 101 dev_err(&client->dev, "Unsupported device\n"); 102 return -ENODEV; 103 } 104 105 if (client->dev.of_node) 106 chip = (enum chips)of_device_get_match_data(&client->dev); 107 else 108 chip = mid->driver_data; 109 110 if (chip != ucd9200 && strcmp(client->name, mid->name) != 0) 111 dev_notice(&client->dev, 112 "Device mismatch: Configured %s, detected %s\n", 113 client->name, mid->name); 114 115 info = devm_kzalloc(&client->dev, sizeof(struct pmbus_driver_info), 116 GFP_KERNEL); 117 if (!info) 118 return -ENOMEM; 119 120 ret = i2c_smbus_read_block_data(client, UCD9200_PHASE_INFO, 121 block_buffer); 122 if (ret < 0) { 123 dev_err(&client->dev, "Failed to read phase information\n"); 124 return ret; 125 } 126 127 /* 128 * Calculate number of configured pages (rails) from PHASE_INFO 129 * register. 130 * Rails have to be sequential, so we can abort after finding 131 * the first unconfigured rail. 132 */ 133 info->pages = 0; 134 for (i = 0; i < ret; i++) { 135 if (!block_buffer[i]) 136 break; 137 info->pages++; 138 } 139 if (!info->pages) { 140 dev_err(&client->dev, "No rails configured\n"); 141 return -ENODEV; 142 } 143 dev_info(&client->dev, "%d rails configured\n", info->pages); 144 145 /* 146 * Set PHASE registers on all pages to 0xff to ensure that phase 147 * specific commands will apply to all phases of a given page (rail). 148 * This only affects the READ_IOUT and READ_TEMPERATURE2 registers. 149 * READ_IOUT will return the sum of currents of all phases of a rail, 150 * and READ_TEMPERATURE2 will return the maximum temperature detected 151 * for the phases of the rail. 152 */ 153 for (i = 0; i < info->pages; i++) { 154 /* 155 * Setting PAGE & PHASE fails once in a while for no obvious 156 * reason, so we need to retry a couple of times. 157 */ 158 for (j = 0; j < 3; j++) { 159 ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, i); 160 if (ret < 0) 161 continue; 162 ret = i2c_smbus_write_byte_data(client, PMBUS_PHASE, 163 0xff); 164 if (ret < 0) 165 continue; 166 break; 167 } 168 if (ret < 0) { 169 dev_err(&client->dev, 170 "Failed to initialize PHASE registers\n"); 171 return ret; 172 } 173 } 174 if (info->pages > 1) 175 i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0); 176 177 info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT | 178 PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | 179 PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | 180 PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | 181 PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP | 182 PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP; 183 184 for (i = 1; i < info->pages; i++) 185 info->func[i] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | 186 PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | 187 PMBUS_HAVE_POUT | 188 PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP; 189 190 /* ucd9240 supports a single fan */ 191 if (mid->driver_data == ucd9240) 192 info->func[0] |= PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12; 193 194 return pmbus_do_probe(client, info); 195} 196 197/* This is the driver that will be inserted */ 198static struct i2c_driver ucd9200_driver = { 199 .driver = { 200 .name = "ucd9200", 201 .of_match_table = of_match_ptr(ucd9200_of_match), 202 }, 203 .probe_new = ucd9200_probe, 204 .id_table = ucd9200_id, 205}; 206 207module_i2c_driver(ucd9200_driver); 208 209MODULE_AUTHOR("Guenter Roeck"); 210MODULE_DESCRIPTION("PMBus driver for TI UCD922x, UCD924x"); 211MODULE_LICENSE("GPL"); 212MODULE_IMPORT_NS(PMBUS);