1 // SPDX-License-Identifier: GPL-2.0+ 2 3 #include <linux/devm-helpers.h> 4 #include <linux/delay.h> 5 #include <linux/gpio/consumer.h> 6 #include <linux/i2c.h> 7 #include <linux/interrupt.h> 8 #include <linux/module.h> 9 #include <linux/property.h> 10 #include <linux/power_supply.h> 11 #include <linux/types.h> 12 13 /* Register Addresses (B=byte; W=word; S=string) */ 14 #define REGB_STATUS 0x02 15 #define REGW_VOLTAGE_NOW 0x20 16 #define REGW_CURRENT_NOW 0x24 17 #define REGW_CAPACITY 0x28 18 #define REGW_CHARGE_NOW 0x2a 19 #define REGW_CHARGE_FULL 0x2c 20 #define REGW_CYCLE_COUNT 0x3a 21 #define REGW_CHARGE_FULL_DESIGN 0x3c 22 #define REGW_VOLTAGE_MAX_DESIGN 0x3e 23 #define REGW_SERIAL_NUMBER 0x44 24 #define REGS_MANUFACTURER 0x46 25 #define REGS_MODEL_NAME 0x52 26 #define REGS_TECHNOLOGY 0x5a 27 #define REGB_ONLINE 0x67 28 29 struct srt_ec_device { 30 struct i2c_client *client; 31 32 struct power_supply *bat; 33 struct power_supply *psy; 34 35 struct gpio_desc *enable_gpiod; 36 struct delayed_work poll_work; 37 38 unsigned int technology; 39 unsigned int capacity; 40 41 const char *serial; 42 char manufacturer[13]; 43 char model_name[10]; 44 }; 45 46 static const enum power_supply_property srt_bat_power_supply_props[] = { 47 POWER_SUPPLY_PROP_CAPACITY, 48 POWER_SUPPLY_PROP_CHARGE_NOW, 49 POWER_SUPPLY_PROP_CHARGE_FULL, 50 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 51 POWER_SUPPLY_PROP_CURRENT_NOW, 52 POWER_SUPPLY_PROP_CYCLE_COUNT, 53 POWER_SUPPLY_PROP_MANUFACTURER, 54 POWER_SUPPLY_PROP_MODEL_NAME, 55 POWER_SUPPLY_PROP_ONLINE, 56 POWER_SUPPLY_PROP_PRESENT, 57 POWER_SUPPLY_PROP_SERIAL_NUMBER, 58 POWER_SUPPLY_PROP_STATUS, 59 POWER_SUPPLY_PROP_TECHNOLOGY, 60 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 61 POWER_SUPPLY_PROP_VOLTAGE_NOW, 62 }; 63 64 static const enum power_supply_property srt_psy_power_supply_props[] = { 65 POWER_SUPPLY_PROP_ONLINE, 66 POWER_SUPPLY_PROP_PRESENT, 67 }; 68 69 static int srt_bat_get_value(struct i2c_client *client, int reg, int *val) 70 { 71 int ret; 72 73 switch (reg) { 74 case REGW_CHARGE_NOW: 75 case REGW_CHARGE_FULL_DESIGN: 76 case REGW_CHARGE_FULL: 77 case REGW_VOLTAGE_MAX_DESIGN: 78 case REGW_VOLTAGE_NOW: 79 ret = i2c_smbus_read_word_data(client, reg); 80 if (ret < 0) 81 return ret; 82 83 *val = ret * 1000; 84 break; 85 86 case REGW_CURRENT_NOW: 87 ret = i2c_smbus_read_word_data(client, reg); 88 if (ret < 0) 89 return ret; 90 91 *val = (s16)ret * 1000; 92 break; 93 94 case REGW_CAPACITY: 95 case REGW_CYCLE_COUNT: 96 ret = i2c_smbus_read_word_data(client, reg); 97 if (ret < 0) 98 return ret; 99 100 *val = ret; 101 break; 102 103 case REGB_STATUS: 104 ret = i2c_smbus_read_byte_data(client, reg); 105 if (ret < 0) 106 return ret; 107 108 if (ret & BIT(0)) 109 *val = POWER_SUPPLY_STATUS_CHARGING; 110 else 111 *val = POWER_SUPPLY_STATUS_DISCHARGING; 112 break; 113 114 case REGB_ONLINE: 115 ret = i2c_smbus_read_byte_data(client, reg); 116 if (ret < 0) 117 return ret; 118 119 *val = (ret & BIT(1)) >> 1; 120 break; 121 122 default: 123 return -EINVAL; 124 } 125 126 return 0; 127 } 128 129 static int srt_bat_power_supply_get_property(struct power_supply *psy, 130 enum power_supply_property psp, 131 union power_supply_propval *val) 132 { 133 struct srt_ec_device *srt = power_supply_get_drvdata(psy); 134 struct i2c_client *client = srt->client; 135 int ret = 0; 136 137 switch (psp) { 138 case POWER_SUPPLY_PROP_MANUFACTURER: 139 val->strval = srt->manufacturer; 140 break; 141 case POWER_SUPPLY_PROP_MODEL_NAME: 142 val->strval = srt->model_name; 143 break; 144 case POWER_SUPPLY_PROP_SERIAL_NUMBER: 145 val->strval = srt->serial; 146 break; 147 case POWER_SUPPLY_PROP_CAPACITY: 148 ret = srt_bat_get_value(client, REGW_CAPACITY, &val->intval); 149 break; 150 case POWER_SUPPLY_PROP_CHARGE_NOW: 151 ret = srt_bat_get_value(client, REGW_CHARGE_NOW, &val->intval); 152 break; 153 case POWER_SUPPLY_PROP_CHARGE_FULL: 154 ret = srt_bat_get_value(client, REGW_CHARGE_FULL, &val->intval); 155 break; 156 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 157 ret = srt_bat_get_value(client, REGW_CHARGE_FULL_DESIGN, 158 &val->intval); 159 break; 160 case POWER_SUPPLY_PROP_CURRENT_NOW: 161 ret = srt_bat_get_value(client, REGW_CURRENT_NOW, &val->intval); 162 break; 163 case POWER_SUPPLY_PROP_CYCLE_COUNT: 164 ret = srt_bat_get_value(client, REGW_CYCLE_COUNT, &val->intval); 165 break; 166 case POWER_SUPPLY_PROP_PRESENT: 167 val->intval = 1; 168 break; 169 case POWER_SUPPLY_PROP_ONLINE: 170 ret = srt_bat_get_value(client, REGB_ONLINE, &val->intval); 171 break; 172 case POWER_SUPPLY_PROP_STATUS: 173 if (srt->capacity < 100) 174 ret = srt_bat_get_value(client, REGB_STATUS, &val->intval); 175 else 176 val->intval = POWER_SUPPLY_STATUS_FULL; 177 break; 178 case POWER_SUPPLY_PROP_TECHNOLOGY: 179 val->intval = srt->technology; 180 break; 181 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 182 ret = srt_bat_get_value(client, REGW_VOLTAGE_MAX_DESIGN, 183 &val->intval); 184 break; 185 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 186 ret = srt_bat_get_value(client, REGW_VOLTAGE_NOW, &val->intval); 187 break; 188 default: 189 return -EINVAL; 190 } 191 192 return ret; 193 } 194 195 static int srt_psy_power_supply_get_property(struct power_supply *psy, 196 enum power_supply_property psp, 197 union power_supply_propval *val) 198 { 199 struct srt_ec_device *srt = power_supply_get_drvdata(psy); 200 struct i2c_client *client = srt->client; 201 int ret; 202 203 switch (psp) { 204 case POWER_SUPPLY_PROP_ONLINE: 205 case POWER_SUPPLY_PROP_PRESENT: 206 ret = i2c_smbus_read_byte_data(client, REGB_ONLINE); 207 if (ret < 0) 208 return ret; 209 210 val->intval = ret & BIT(0); 211 break; 212 default: 213 return -EINVAL; 214 } 215 216 return 0; 217 } 218 219 static void srt_bat_poll_work(struct work_struct *work) 220 { 221 struct srt_ec_device *srt = 222 container_of(work, struct srt_ec_device, poll_work.work); 223 int ret, capacity; 224 225 ret = srt_bat_get_value(srt->client, REGW_CAPACITY, &capacity); 226 if (!ret && capacity != srt->capacity) { 227 srt->capacity = capacity; 228 power_supply_changed(srt->bat); 229 } 230 231 /* continuously send uevent notification */ 232 schedule_delayed_work(&srt->poll_work, 30 * HZ); 233 } 234 235 static irqreturn_t srt_psy_detect_irq(int irq, void *dev_id) 236 { 237 struct srt_ec_device *srt = dev_id; 238 239 power_supply_changed(srt->psy); 240 241 return IRQ_HANDLED; 242 } 243 244 static const struct power_supply_desc srt_bat_power_supply_desc = { 245 .name = "surface-rt-battery", 246 .type = POWER_SUPPLY_TYPE_BATTERY, 247 .properties = srt_bat_power_supply_props, 248 .num_properties = ARRAY_SIZE(srt_bat_power_supply_props), 249 .get_property = srt_bat_power_supply_get_property, 250 .external_power_changed = power_supply_changed, 251 }; 252 253 static const struct power_supply_desc srt_psy_power_supply_desc = { 254 .name = "surface-rt-ac-adapter", 255 .type = POWER_SUPPLY_TYPE_MAINS, 256 .properties = srt_psy_power_supply_props, 257 .num_properties = ARRAY_SIZE(srt_psy_power_supply_props), 258 .get_property = srt_psy_power_supply_get_property, 259 }; 260 261 static char *battery_supplied_to[] = { "surface-rt-battery" }; 262 263 static int srt_ec_probe(struct i2c_client *client) 264 { 265 struct power_supply_config bat_cfg = {}; 266 struct power_supply_config psy_cfg = {}; 267 struct device *dev = &client->dev; 268 struct srt_ec_device *srt; 269 char str_buf[4]; 270 int ret; 271 272 srt = devm_kzalloc(dev, sizeof(*srt), GFP_KERNEL); 273 if (!srt) 274 return -ENOMEM; 275 276 i2c_set_clientdata(client, srt); 277 srt->client = client; 278 279 srt->enable_gpiod = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH); 280 if (IS_ERR(srt->enable_gpiod)) 281 return dev_err_probe(dev, PTR_ERR(srt->enable_gpiod), 282 "failed to get enable gpio\n"); 283 284 /* wait till EC is ready */ 285 usleep_range(1000, 1500); 286 287 ret = i2c_smbus_read_word_data(client, REGW_SERIAL_NUMBER); 288 if (ret < 0) 289 return ret; 290 291 srt->serial = devm_kasprintf(dev, GFP_KERNEL, "%04x", ret); 292 if (!srt->serial) 293 return -ENOMEM; 294 295 ret = i2c_smbus_read_i2c_block_data(client, REGS_MANUFACTURER, 296 sizeof(srt->manufacturer) - 1, 297 srt->manufacturer); 298 if (ret < 0) 299 return ret; 300 301 ret = i2c_smbus_read_i2c_block_data(client, REGS_MODEL_NAME, 302 sizeof(srt->model_name) - 1, 303 srt->model_name); 304 if (ret < 0) 305 return ret; 306 307 ret = i2c_smbus_read_i2c_block_data(client, REGS_TECHNOLOGY, 308 sizeof(str_buf), str_buf); 309 if (ret < 0) 310 return ret; 311 312 if (!strncmp(str_buf, "LION", 4)) 313 srt->technology = POWER_SUPPLY_TECHNOLOGY_LION; 314 else 315 srt->technology = POWER_SUPPLY_TECHNOLOGY_UNKNOWN; 316 317 bat_cfg.drv_data = srt; 318 bat_cfg.fwnode = dev_fwnode(dev); 319 320 srt->bat = devm_power_supply_register(dev, &srt_bat_power_supply_desc, 321 &bat_cfg); 322 if (IS_ERR(srt->bat)) 323 return dev_err_probe(dev, PTR_ERR(srt->bat), 324 "failed to register battery power supply\n"); 325 326 psy_cfg.drv_data = srt; 327 psy_cfg.fwnode = dev_fwnode(dev); 328 psy_cfg.supplied_to = battery_supplied_to; 329 psy_cfg.num_supplicants = ARRAY_SIZE(battery_supplied_to); 330 331 srt->psy = devm_power_supply_register(dev, &srt_psy_power_supply_desc, 332 &psy_cfg); 333 if (IS_ERR(srt->psy)) 334 return dev_err_probe(dev, PTR_ERR(srt->psy), 335 "failed to register AC power supply\n"); 336 337 ret = devm_request_threaded_irq(dev, client->irq, NULL, srt_psy_detect_irq, 338 IRQF_ONESHOT, client->name, srt); 339 if (ret < 0) 340 return dev_err_probe(dev, ret, "failed to request interrupt\n"); 341 342 ret = devm_delayed_work_autocancel(dev, &srt->poll_work, srt_bat_poll_work); 343 if (ret < 0) 344 return ret; 345 346 schedule_delayed_work(&srt->poll_work, HZ); 347 348 return 0; 349 } 350 351 static int srt_ec_suspend(struct device *dev) 352 { 353 struct srt_ec_device *srt = dev_get_drvdata(dev); 354 355 cancel_delayed_work_sync(&srt->poll_work); 356 357 return 0; 358 } 359 360 static int srt_ec_resume(struct device *dev) 361 { 362 struct srt_ec_device *srt = dev_get_drvdata(dev); 363 364 schedule_delayed_work(&srt->poll_work, HZ); 365 366 return 0; 367 } 368 369 static DEFINE_SIMPLE_DEV_PM_OPS(srt_ec_pm_ops, srt_ec_suspend, srt_ec_resume); 370 371 static const struct of_device_id srt_ec_of_match[] = { 372 { .compatible = "microsoft,surface-rt-ec" }, 373 { } 374 }; 375 MODULE_DEVICE_TABLE(of, srt_ec_of_match); 376 377 static struct i2c_driver srt_ec_driver = { 378 .driver = { 379 .name = "surface-rt-ec", 380 .of_match_table = srt_ec_of_match, 381 .pm = &srt_ec_pm_ops, 382 }, 383 .probe = srt_ec_probe, 384 }; 385 module_i2c_driver(srt_ec_driver); 386 387 MODULE_AUTHOR("Jonas Schwöbel <jonasschwoebel@yahoo.de>"); 388 MODULE_DESCRIPTION("Surface RT Embedded Controller driver"); 389 MODULE_LICENSE("GPL"); 390