Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

power: supply: ds2760_battery: merge ds2760 supply driver with its w1 slave companion

This patch removes the w1 slave driver that used to register the w1 family
and instanciate a platform device at runtime. The code now lives in the
supply driver instead to avoid that level of indirection.

The old device name "ds2760-battery.0" is preserved, so userspace
applications can access the same virtual device nodes as before.

Note that because the w1 core does not currently have a framework for
suspend/resume, the driver now registers a PM notifier callback.

Signed-off-by: Daniel Mack <daniel@zonque.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>

authored by

Daniel Mack and committed by
Sebastian Reichel
bf497355 fae68031

+232 -338
+1 -1
drivers/power/supply/Kconfig
··· 92 92 93 93 config BATTERY_DS2760 94 94 tristate "DS2760 battery driver (HP iPAQ & others)" 95 - depends on W1 && W1_SLAVE_DS2760 95 + depends on W1 96 96 help 97 97 Say Y here to enable support for batteries with ds2760 chip. 98 98
+231 -90
drivers/power/supply/ds2760_battery.c
··· 27 27 #include <linux/slab.h> 28 28 #include <linux/platform_device.h> 29 29 #include <linux/power_supply.h> 30 - 30 + #include <linux/suspend.h> 31 31 #include <linux/w1.h> 32 - #include "../../w1/slaves/w1_ds2760.h" 32 + 33 + static unsigned int cache_time = 1000; 34 + module_param(cache_time, uint, 0644); 35 + MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); 36 + 37 + static bool pmod_enabled; 38 + module_param(pmod_enabled, bool, 0644); 39 + MODULE_PARM_DESC(pmod_enabled, "PMOD enable bit"); 40 + 41 + static unsigned int rated_capacity; 42 + module_param(rated_capacity, uint, 0644); 43 + MODULE_PARM_DESC(rated_capacity, "rated battery capacity, 10*mAh or index"); 44 + 45 + static unsigned int current_accum; 46 + module_param(current_accum, uint, 0644); 47 + MODULE_PARM_DESC(current_accum, "current accumulator value"); 48 + 49 + #define W1_FAMILY_DS2760 0x30 50 + 51 + /* Known commands to the DS2760 chip */ 52 + #define W1_DS2760_SWAP 0xAA 53 + #define W1_DS2760_READ_DATA 0x69 54 + #define W1_DS2760_WRITE_DATA 0x6C 55 + #define W1_DS2760_COPY_DATA 0x48 56 + #define W1_DS2760_RECALL_DATA 0xB8 57 + #define W1_DS2760_LOCK 0x6A 58 + 59 + /* Number of valid register addresses */ 60 + #define DS2760_DATA_SIZE 0x40 61 + 62 + #define DS2760_PROTECTION_REG 0x00 63 + 64 + #define DS2760_STATUS_REG 0x01 65 + #define DS2760_STATUS_IE (1 << 2) 66 + #define DS2760_STATUS_SWEN (1 << 3) 67 + #define DS2760_STATUS_RNAOP (1 << 4) 68 + #define DS2760_STATUS_PMOD (1 << 5) 69 + 70 + #define DS2760_EEPROM_REG 0x07 71 + #define DS2760_SPECIAL_FEATURE_REG 0x08 72 + #define DS2760_VOLTAGE_MSB 0x0c 73 + #define DS2760_VOLTAGE_LSB 0x0d 74 + #define DS2760_CURRENT_MSB 0x0e 75 + #define DS2760_CURRENT_LSB 0x0f 76 + #define DS2760_CURRENT_ACCUM_MSB 0x10 77 + #define DS2760_CURRENT_ACCUM_LSB 0x11 78 + #define DS2760_TEMP_MSB 0x18 79 + #define DS2760_TEMP_LSB 0x19 80 + #define DS2760_EEPROM_BLOCK0 0x20 81 + #define DS2760_ACTIVE_FULL 0x20 82 + #define DS2760_EEPROM_BLOCK1 0x30 83 + #define DS2760_STATUS_WRITE_REG 0x31 84 + #define DS2760_RATED_CAPACITY 0x32 85 + #define DS2760_CURRENT_OFFSET_BIAS 0x33 86 + #define DS2760_ACTIVE_EMPTY 0x3b 33 87 34 88 struct ds2760_device_info { 35 89 struct device *dev; ··· 109 55 int full_counter; 110 56 struct power_supply *bat; 111 57 struct power_supply_desc bat_desc; 112 - struct device *w1_dev; 113 58 struct workqueue_struct *monitor_wqueue; 114 59 struct delayed_work monitor_work; 115 60 struct delayed_work set_charged_work; 61 + struct notifier_block pm_notifier; 116 62 }; 117 63 118 - static unsigned int cache_time = 1000; 119 - module_param(cache_time, uint, 0644); 120 - MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); 64 + static int w1_ds2760_io(struct device *dev, char *buf, int addr, size_t count, 65 + int io) 66 + { 67 + struct w1_slave *sl = container_of(dev, struct w1_slave, dev); 121 68 122 - static bool pmod_enabled; 123 - module_param(pmod_enabled, bool, 0644); 124 - MODULE_PARM_DESC(pmod_enabled, "PMOD enable bit"); 69 + if (!dev) 70 + return 0; 125 71 126 - static unsigned int rated_capacity; 127 - module_param(rated_capacity, uint, 0644); 128 - MODULE_PARM_DESC(rated_capacity, "rated battery capacity, 10*mAh or index"); 72 + mutex_lock(&sl->master->bus_mutex); 129 73 130 - static unsigned int current_accum; 131 - module_param(current_accum, uint, 0644); 132 - MODULE_PARM_DESC(current_accum, "current accumulator value"); 74 + if (addr > DS2760_DATA_SIZE || addr < 0) { 75 + count = 0; 76 + goto out; 77 + } 78 + if (addr + count > DS2760_DATA_SIZE) 79 + count = DS2760_DATA_SIZE - addr; 133 80 81 + if (!w1_reset_select_slave(sl)) { 82 + if (!io) { 83 + w1_write_8(sl->master, W1_DS2760_READ_DATA); 84 + w1_write_8(sl->master, addr); 85 + count = w1_read_block(sl->master, buf, count); 86 + } else { 87 + w1_write_8(sl->master, W1_DS2760_WRITE_DATA); 88 + w1_write_8(sl->master, addr); 89 + w1_write_block(sl->master, buf, count); 90 + /* XXX w1_write_block returns void, not n_written */ 91 + } 92 + } 93 + 94 + out: 95 + mutex_unlock(&sl->master->bus_mutex); 96 + 97 + return count; 98 + } 99 + 100 + static int w1_ds2760_read(struct device *dev, 101 + char *buf, int addr, 102 + size_t count) 103 + { 104 + return w1_ds2760_io(dev, buf, addr, count, 0); 105 + } 106 + 107 + static int w1_ds2760_write(struct device *dev, 108 + char *buf, 109 + int addr, size_t count) 110 + { 111 + return w1_ds2760_io(dev, buf, addr, count, 1); 112 + } 113 + 114 + static int w1_ds2760_eeprom_cmd(struct device *dev, int addr, int cmd) 115 + { 116 + struct w1_slave *sl = container_of(dev, struct w1_slave, dev); 117 + 118 + if (!dev) 119 + return -EINVAL; 120 + 121 + mutex_lock(&sl->master->bus_mutex); 122 + 123 + if (w1_reset_select_slave(sl) == 0) { 124 + w1_write_8(sl->master, cmd); 125 + w1_write_8(sl->master, addr); 126 + } 127 + 128 + mutex_unlock(&sl->master->bus_mutex); 129 + return 0; 130 + } 131 + 132 + static int w1_ds2760_store_eeprom(struct device *dev, int addr) 133 + { 134 + return w1_ds2760_eeprom_cmd(dev, addr, W1_DS2760_COPY_DATA); 135 + } 136 + 137 + static int w1_ds2760_recall_eeprom(struct device *dev, int addr) 138 + { 139 + return w1_ds2760_eeprom_cmd(dev, addr, W1_DS2760_RECALL_DATA); 140 + } 141 + 142 + static ssize_t w1_slave_read(struct file *filp, struct kobject *kobj, 143 + struct bin_attribute *bin_attr, char *buf, 144 + loff_t off, size_t count) 145 + { 146 + struct device *dev = container_of(kobj, struct device, kobj); 147 + return w1_ds2760_read(dev, buf, off, count); 148 + } 149 + 150 + static BIN_ATTR_RO(w1_slave, DS2760_DATA_SIZE); 151 + 152 + static struct bin_attribute *w1_ds2760_bin_attrs[] = { 153 + &bin_attr_w1_slave, 154 + NULL, 155 + }; 156 + 157 + static const struct attribute_group w1_ds2760_group = { 158 + .bin_attrs = w1_ds2760_bin_attrs, 159 + }; 160 + 161 + static const struct attribute_group *w1_ds2760_groups[] = { 162 + &w1_ds2760_group, 163 + NULL, 164 + }; 134 165 /* Some batteries have their rated capacity stored a N * 10 mAh, while 135 166 * others use an index into this table. */ 136 167 static int rated_capacities[] = { ··· 277 138 count = DS2760_TEMP_LSB - start + 1; 278 139 } 279 140 280 - ret = w1_ds2760_read(di->w1_dev, di->raw + start, start, count); 141 + ret = w1_ds2760_read(di->dev, di->raw + start, start, count); 281 142 if (ret != count) { 282 143 dev_warn(di->dev, "call to w1_ds2760_read failed (0x%p)\n", 283 - di->w1_dev); 144 + di->dev); 284 145 return 1; 285 146 } 286 147 ··· 381 242 acr[0] = acr_val >> 8; 382 243 acr[1] = acr_val & 0xff; 383 244 384 - if (w1_ds2760_write(di->w1_dev, acr, DS2760_CURRENT_ACCUM_MSB, 2) < 2) 245 + if (w1_ds2760_write(di->dev, acr, DS2760_CURRENT_ACCUM_MSB, 2) < 2) 385 246 dev_warn(di->dev, "ACR write failed\n"); 386 247 } 387 248 ··· 436 297 if (status == di->raw[DS2760_STATUS_REG]) 437 298 return; 438 299 439 - w1_ds2760_write(di->w1_dev, &status, DS2760_STATUS_WRITE_REG, 1); 440 - w1_ds2760_store_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1); 441 - w1_ds2760_recall_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1); 300 + w1_ds2760_write(di->dev, &status, DS2760_STATUS_WRITE_REG, 1); 301 + w1_ds2760_store_eeprom(di->dev, DS2760_EEPROM_BLOCK1); 302 + w1_ds2760_recall_eeprom(di->dev, DS2760_EEPROM_BLOCK1); 442 303 } 443 304 444 305 static void ds2760_battery_write_rated_capacity(struct ds2760_device_info *di, ··· 447 308 if (rated_capacity == di->raw[DS2760_RATED_CAPACITY]) 448 309 return; 449 310 450 - w1_ds2760_write(di->w1_dev, &rated_capacity, DS2760_RATED_CAPACITY, 1); 451 - w1_ds2760_store_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1); 452 - w1_ds2760_recall_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1); 311 + w1_ds2760_write(di->dev, &rated_capacity, DS2760_RATED_CAPACITY, 1); 312 + w1_ds2760_store_eeprom(di->dev, DS2760_EEPROM_BLOCK1); 313 + w1_ds2760_recall_eeprom(di->dev, DS2760_EEPROM_BLOCK1); 453 314 } 454 315 455 316 static void ds2760_battery_write_active_full(struct ds2760_device_info *di, ··· 464 325 tmp[1] == di->raw[DS2760_ACTIVE_FULL + 1]) 465 326 return; 466 327 467 - w1_ds2760_write(di->w1_dev, tmp, DS2760_ACTIVE_FULL, sizeof(tmp)); 468 - w1_ds2760_store_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK0); 469 - w1_ds2760_recall_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK0); 328 + w1_ds2760_write(di->dev, tmp, DS2760_ACTIVE_FULL, sizeof(tmp)); 329 + w1_ds2760_store_eeprom(di->dev, DS2760_EEPROM_BLOCK0); 330 + w1_ds2760_recall_eeprom(di->dev, DS2760_EEPROM_BLOCK0); 470 331 471 332 /* Write to the di->raw[] buffer directly - the DS2760_ACTIVE_FULL 472 333 * values won't be read back by ds2760_battery_read_status() */ ··· 522 383 523 384 dev_dbg(di->dev, "%s: bias = %d\n", __func__, bias); 524 385 525 - w1_ds2760_write(di->w1_dev, &bias, DS2760_CURRENT_OFFSET_BIAS, 1); 526 - w1_ds2760_store_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1); 527 - w1_ds2760_recall_eeprom(di->w1_dev, DS2760_EEPROM_BLOCK1); 386 + w1_ds2760_write(di->dev, &bias, DS2760_CURRENT_OFFSET_BIAS, 1); 387 + w1_ds2760_store_eeprom(di->dev, DS2760_EEPROM_BLOCK1); 388 + w1_ds2760_recall_eeprom(di->dev, DS2760_EEPROM_BLOCK1); 528 389 529 390 /* Write to the di->raw[] buffer directly - the CURRENT_OFFSET_BIAS 530 391 * value won't be read back by ds2760_battery_read_status() */ ··· 643 504 POWER_SUPPLY_PROP_CAPACITY, 644 505 }; 645 506 646 - static int ds2760_battery_probe(struct platform_device *pdev) 507 + static int ds2760_pm_notifier(struct notifier_block *notifier, 508 + unsigned long pm_event, 509 + void *unused) 510 + { 511 + struct ds2760_device_info *di = 512 + container_of(notifier, struct ds2760_device_info, pm_notifier); 513 + 514 + switch (pm_event) { 515 + case PM_HIBERNATION_PREPARE: 516 + case PM_SUSPEND_PREPARE: 517 + di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; 518 + break; 519 + 520 + case PM_POST_RESTORE: 521 + case PM_POST_HIBERNATION: 522 + case PM_POST_SUSPEND: 523 + di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; 524 + power_supply_changed(di->bat); 525 + mod_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ); 526 + 527 + break; 528 + 529 + case PM_RESTORE_PREPARE: 530 + default: 531 + break; 532 + } 533 + 534 + return NOTIFY_DONE; 535 + } 536 + 537 + static int w1_ds2760_add_slave(struct w1_slave *sl) 647 538 { 648 539 struct power_supply_config psy_cfg = {}; 649 - char status; 650 - int retval = 0; 651 540 struct ds2760_device_info *di; 541 + struct device *dev = &sl->dev; 542 + int retval = 0; 543 + char name[32]; 544 + char status; 652 545 653 - di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL); 546 + di = devm_kzalloc(dev, sizeof(*di), GFP_KERNEL); 654 547 if (!di) { 655 548 retval = -ENOMEM; 656 549 goto di_alloc_failed; 657 550 } 658 551 659 - platform_set_drvdata(pdev, di); 552 + snprintf(name, sizeof(name), "ds2760-battery.%d", dev->id); 660 553 661 - di->dev = &pdev->dev; 662 - di->w1_dev = pdev->dev.parent; 663 - di->bat_desc.name = dev_name(&pdev->dev); 554 + di->dev = dev; 555 + di->bat_desc.name = name; 664 556 di->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY; 665 557 di->bat_desc.properties = ds2760_battery_props; 666 558 di->bat_desc.num_properties = ARRAY_SIZE(ds2760_battery_props); ··· 703 533 di->bat_desc.external_power_changed = 704 534 ds2760_battery_external_power_changed; 705 535 706 - psy_cfg.drv_data = di; 536 + psy_cfg.drv_data = di; 707 537 708 538 di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; 539 + 540 + sl->family_data = di; 709 541 710 542 /* enable sleep mode feature */ 711 543 ds2760_battery_read_status(di); ··· 728 556 if (current_accum) 729 557 ds2760_battery_set_current_accum(di, current_accum); 730 558 731 - di->bat = power_supply_register(&pdev->dev, &di->bat_desc, &psy_cfg); 559 + di->bat = power_supply_register(dev, &di->bat_desc, &psy_cfg); 732 560 if (IS_ERR(di->bat)) { 733 561 dev_err(di->dev, "failed to register battery\n"); 734 562 retval = PTR_ERR(di->bat); ··· 738 566 INIT_DELAYED_WORK(&di->monitor_work, ds2760_battery_work); 739 567 INIT_DELAYED_WORK(&di->set_charged_work, 740 568 ds2760_battery_set_charged_work); 741 - di->monitor_wqueue = alloc_ordered_workqueue(dev_name(&pdev->dev), 742 - WQ_MEM_RECLAIM); 569 + di->monitor_wqueue = alloc_ordered_workqueue(name, WQ_MEM_RECLAIM); 743 570 if (!di->monitor_wqueue) { 744 571 retval = -ESRCH; 745 572 goto workqueue_failed; 746 573 } 747 574 queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ * 1); 575 + 576 + di->pm_notifier.notifier_call = ds2760_pm_notifier; 577 + register_pm_notifier(&di->pm_notifier); 748 578 749 579 goto success; 750 580 ··· 758 584 return retval; 759 585 } 760 586 761 - static int ds2760_battery_remove(struct platform_device *pdev) 587 + static void w1_ds2760_remove_slave(struct w1_slave *sl) 762 588 { 763 - struct ds2760_device_info *di = platform_get_drvdata(pdev); 589 + struct ds2760_device_info *di = sl->family_data; 764 590 591 + unregister_pm_notifier(&di->pm_notifier); 765 592 cancel_delayed_work_sync(&di->monitor_work); 766 593 cancel_delayed_work_sync(&di->set_charged_work); 767 594 destroy_workqueue(di->monitor_wqueue); 768 595 power_supply_unregister(di->bat); 769 - 770 - return 0; 771 596 } 772 597 773 - #ifdef CONFIG_PM 774 - 775 - static int ds2760_battery_suspend(struct platform_device *pdev, 776 - pm_message_t state) 777 - { 778 - struct ds2760_device_info *di = platform_get_drvdata(pdev); 779 - 780 - di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; 781 - 782 - return 0; 783 - } 784 - 785 - static int ds2760_battery_resume(struct platform_device *pdev) 786 - { 787 - struct ds2760_device_info *di = platform_get_drvdata(pdev); 788 - 789 - di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; 790 - power_supply_changed(di->bat); 791 - 792 - mod_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ); 793 - 794 - return 0; 795 - } 796 - 797 - #else 798 - 799 - #define ds2760_battery_suspend NULL 800 - #define ds2760_battery_resume NULL 801 - 802 - #endif /* CONFIG_PM */ 803 - 804 - MODULE_ALIAS("platform:ds2760-battery"); 805 - 806 - static struct platform_driver ds2760_battery_driver = { 807 - .driver = { 808 - .name = "ds2760-battery", 809 - }, 810 - .probe = ds2760_battery_probe, 811 - .remove = ds2760_battery_remove, 812 - .suspend = ds2760_battery_suspend, 813 - .resume = ds2760_battery_resume, 598 + static struct w1_family_ops w1_ds2760_fops = { 599 + .add_slave = w1_ds2760_add_slave, 600 + .remove_slave = w1_ds2760_remove_slave, 601 + .groups = w1_ds2760_groups, 814 602 }; 815 603 816 - module_platform_driver(ds2760_battery_driver); 604 + static struct w1_family w1_ds2760_family = { 605 + .fid = W1_FAMILY_DS2760, 606 + .fops = &w1_ds2760_fops, 607 + }; 608 + module_w1_family(w1_ds2760_family); 817 609 818 - MODULE_LICENSE("GPL"); 819 610 MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>, " 820 611 "Matt Reimer <mreimer@vpop.net>, " 821 612 "Anton Vorontsov <cbou@mail.ru>"); 822 - MODULE_DESCRIPTION("ds2760 battery driver"); 613 + MODULE_DESCRIPTION("1-wire Driver Dallas 2760 battery monitor chip"); 614 + MODULE_LICENSE("GPL"); 615 + MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2760));
-12
drivers/w1/slaves/Kconfig
··· 100 100 Say Y here if you want to use a 1-wire 101 101 DS2438 Smart Battery Monitor device support 102 102 103 - config W1_SLAVE_DS2760 104 - tristate "Dallas 2760 battery monitor chip (HP iPAQ & others)" 105 - help 106 - If you enable this you will have the DS2760 battery monitor 107 - chip support. 108 - 109 - The battery monitor chip is used in many batteries/devices 110 - as the one who is responsible for charging/discharging/monitoring 111 - Li+ batteries. 112 - 113 - If you are unsure, say N. 114 - 115 103 config W1_SLAVE_DS2780 116 104 tristate "Dallas 2780 battery monitor chip" 117 105 help
-1
drivers/w1/slaves/Makefile
··· 14 14 obj-$(CONFIG_W1_SLAVE_DS2805) += w1_ds2805.o 15 15 obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o 16 16 obj-$(CONFIG_W1_SLAVE_DS2438) += w1_ds2438.o 17 - obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o 18 17 obj-$(CONFIG_W1_SLAVE_DS2780) += w1_ds2780.o 19 18 obj-$(CONFIG_W1_SLAVE_DS2781) += w1_ds2781.o 20 19 obj-$(CONFIG_W1_SLAVE_DS28E04) += w1_ds28e04.o
-175
drivers/w1/slaves/w1_ds2760.c
··· 1 - /* 2 - * 1-Wire implementation for the ds2760 chip 3 - * 4 - * Copyright © 2004-2005, Szabolcs Gyurko <szabolcs.gyurko@tlt.hu> 5 - * 6 - * Use consistent with the GNU GPL is permitted, 7 - * provided that this copyright notice is 8 - * preserved in its entirety in all copies and derived works. 9 - * 10 - */ 11 - 12 - #include <linux/kernel.h> 13 - #include <linux/module.h> 14 - #include <linux/device.h> 15 - #include <linux/types.h> 16 - #include <linux/platform_device.h> 17 - #include <linux/mutex.h> 18 - #include <linux/idr.h> 19 - #include <linux/gfp.h> 20 - 21 - #include <linux/w1.h> 22 - 23 - #include "w1_ds2760.h" 24 - 25 - #define W1_FAMILY_DS2760 0x30 26 - 27 - static int w1_ds2760_io(struct device *dev, char *buf, int addr, size_t count, 28 - int io) 29 - { 30 - struct w1_slave *sl = container_of(dev, struct w1_slave, dev); 31 - 32 - if (!dev) 33 - return 0; 34 - 35 - mutex_lock(&sl->master->bus_mutex); 36 - 37 - if (addr > DS2760_DATA_SIZE || addr < 0) { 38 - count = 0; 39 - goto out; 40 - } 41 - if (addr + count > DS2760_DATA_SIZE) 42 - count = DS2760_DATA_SIZE - addr; 43 - 44 - if (!w1_reset_select_slave(sl)) { 45 - if (!io) { 46 - w1_write_8(sl->master, W1_DS2760_READ_DATA); 47 - w1_write_8(sl->master, addr); 48 - count = w1_read_block(sl->master, buf, count); 49 - } else { 50 - w1_write_8(sl->master, W1_DS2760_WRITE_DATA); 51 - w1_write_8(sl->master, addr); 52 - w1_write_block(sl->master, buf, count); 53 - /* XXX w1_write_block returns void, not n_written */ 54 - } 55 - } 56 - 57 - out: 58 - mutex_unlock(&sl->master->bus_mutex); 59 - 60 - return count; 61 - } 62 - 63 - int w1_ds2760_read(struct device *dev, char *buf, int addr, size_t count) 64 - { 65 - return w1_ds2760_io(dev, buf, addr, count, 0); 66 - } 67 - EXPORT_SYMBOL(w1_ds2760_read); 68 - 69 - int w1_ds2760_write(struct device *dev, char *buf, int addr, size_t count) 70 - { 71 - return w1_ds2760_io(dev, buf, addr, count, 1); 72 - } 73 - EXPORT_SYMBOL(w1_ds2760_write); 74 - 75 - static int w1_ds2760_eeprom_cmd(struct device *dev, int addr, int cmd) 76 - { 77 - struct w1_slave *sl = container_of(dev, struct w1_slave, dev); 78 - 79 - if (!dev) 80 - return -EINVAL; 81 - 82 - mutex_lock(&sl->master->bus_mutex); 83 - 84 - if (w1_reset_select_slave(sl) == 0) { 85 - w1_write_8(sl->master, cmd); 86 - w1_write_8(sl->master, addr); 87 - } 88 - 89 - mutex_unlock(&sl->master->bus_mutex); 90 - return 0; 91 - } 92 - 93 - int w1_ds2760_store_eeprom(struct device *dev, int addr) 94 - { 95 - return w1_ds2760_eeprom_cmd(dev, addr, W1_DS2760_COPY_DATA); 96 - } 97 - EXPORT_SYMBOL(w1_ds2760_store_eeprom); 98 - 99 - int w1_ds2760_recall_eeprom(struct device *dev, int addr) 100 - { 101 - return w1_ds2760_eeprom_cmd(dev, addr, W1_DS2760_RECALL_DATA); 102 - } 103 - EXPORT_SYMBOL(w1_ds2760_recall_eeprom); 104 - 105 - static ssize_t w1_slave_read(struct file *filp, struct kobject *kobj, 106 - struct bin_attribute *bin_attr, char *buf, 107 - loff_t off, size_t count) 108 - { 109 - struct device *dev = container_of(kobj, struct device, kobj); 110 - return w1_ds2760_read(dev, buf, off, count); 111 - } 112 - 113 - static BIN_ATTR_RO(w1_slave, DS2760_DATA_SIZE); 114 - 115 - static struct bin_attribute *w1_ds2760_bin_attrs[] = { 116 - &bin_attr_w1_slave, 117 - NULL, 118 - }; 119 - 120 - static const struct attribute_group w1_ds2760_group = { 121 - .bin_attrs = w1_ds2760_bin_attrs, 122 - }; 123 - 124 - static const struct attribute_group *w1_ds2760_groups[] = { 125 - &w1_ds2760_group, 126 - NULL, 127 - }; 128 - 129 - static int w1_ds2760_add_slave(struct w1_slave *sl) 130 - { 131 - int ret; 132 - struct platform_device *pdev; 133 - 134 - pdev = platform_device_alloc("ds2760-battery", PLATFORM_DEVID_AUTO); 135 - if (!pdev) 136 - return -ENOMEM; 137 - pdev->dev.parent = &sl->dev; 138 - 139 - ret = platform_device_add(pdev); 140 - if (ret) 141 - goto pdev_add_failed; 142 - 143 - dev_set_drvdata(&sl->dev, pdev); 144 - 145 - return 0; 146 - 147 - pdev_add_failed: 148 - platform_device_put(pdev); 149 - 150 - return ret; 151 - } 152 - 153 - static void w1_ds2760_remove_slave(struct w1_slave *sl) 154 - { 155 - struct platform_device *pdev = dev_get_drvdata(&sl->dev); 156 - 157 - platform_device_unregister(pdev); 158 - } 159 - 160 - static struct w1_family_ops w1_ds2760_fops = { 161 - .add_slave = w1_ds2760_add_slave, 162 - .remove_slave = w1_ds2760_remove_slave, 163 - .groups = w1_ds2760_groups, 164 - }; 165 - 166 - static struct w1_family w1_ds2760_family = { 167 - .fid = W1_FAMILY_DS2760, 168 - .fops = &w1_ds2760_fops, 169 - }; 170 - module_w1_family(w1_ds2760_family); 171 - 172 - MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>"); 173 - MODULE_DESCRIPTION("1-wire Driver Dallas 2760 battery monitor chip"); 174 - MODULE_LICENSE("GPL"); 175 - MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2760));
-59
drivers/w1/slaves/w1_ds2760.h
··· 1 - /* 2 - * 1-Wire implementation for the ds2760 chip 3 - * 4 - * Copyright © 2004-2005, Szabolcs Gyurko <szabolcs.gyurko@tlt.hu> 5 - * 6 - * Use consistent with the GNU GPL is permitted, 7 - * provided that this copyright notice is 8 - * preserved in its entirety in all copies and derived works. 9 - * 10 - */ 11 - 12 - #ifndef __w1_ds2760_h__ 13 - #define __w1_ds2760_h__ 14 - 15 - /* Known commands to the DS2760 chip */ 16 - #define W1_DS2760_SWAP 0xAA 17 - #define W1_DS2760_READ_DATA 0x69 18 - #define W1_DS2760_WRITE_DATA 0x6C 19 - #define W1_DS2760_COPY_DATA 0x48 20 - #define W1_DS2760_RECALL_DATA 0xB8 21 - #define W1_DS2760_LOCK 0x6A 22 - 23 - /* Number of valid register addresses */ 24 - #define DS2760_DATA_SIZE 0x40 25 - 26 - #define DS2760_PROTECTION_REG 0x00 27 - 28 - #define DS2760_STATUS_REG 0x01 29 - #define DS2760_STATUS_IE (1 << 2) 30 - #define DS2760_STATUS_SWEN (1 << 3) 31 - #define DS2760_STATUS_RNAOP (1 << 4) 32 - #define DS2760_STATUS_PMOD (1 << 5) 33 - 34 - #define DS2760_EEPROM_REG 0x07 35 - #define DS2760_SPECIAL_FEATURE_REG 0x08 36 - #define DS2760_VOLTAGE_MSB 0x0c 37 - #define DS2760_VOLTAGE_LSB 0x0d 38 - #define DS2760_CURRENT_MSB 0x0e 39 - #define DS2760_CURRENT_LSB 0x0f 40 - #define DS2760_CURRENT_ACCUM_MSB 0x10 41 - #define DS2760_CURRENT_ACCUM_LSB 0x11 42 - #define DS2760_TEMP_MSB 0x18 43 - #define DS2760_TEMP_LSB 0x19 44 - #define DS2760_EEPROM_BLOCK0 0x20 45 - #define DS2760_ACTIVE_FULL 0x20 46 - #define DS2760_EEPROM_BLOCK1 0x30 47 - #define DS2760_STATUS_WRITE_REG 0x31 48 - #define DS2760_RATED_CAPACITY 0x32 49 - #define DS2760_CURRENT_OFFSET_BIAS 0x33 50 - #define DS2760_ACTIVE_EMPTY 0x3b 51 - 52 - extern int w1_ds2760_read(struct device *dev, char *buf, int addr, 53 - size_t count); 54 - extern int w1_ds2760_write(struct device *dev, char *buf, int addr, 55 - size_t count); 56 - extern int w1_ds2760_store_eeprom(struct device *dev, int addr); 57 - extern int w1_ds2760_recall_eeprom(struct device *dev, int addr); 58 - 59 - #endif /* !__w1_ds2760_h__ */