···1-Any w1 device must be connected to w1 bus master device - for example2-ds9490 usb device or w1-over-GPIO or RS232 converter.3-Driver for w1 bus master must provide several functions(you can find4-them in struct w1_bus_master definition in w1.h) which then will be5-called by w1 core to send various commands over w1 bus(by default it is6-reset and search commands). When some device is found on the bus, w1 core7-checks if driver for it's family is loaded.8-If driver is loaded w1 core creates new w1_slave object and registers it9-in the system(creates some generic sysfs files(struct w1_family_ops in10-w1_family.h), notifies any registered listener and so on...).11-It is device driver's business to provide any communication method12-upstream.13-For example w1_therm driver(ds18?20 thermal sensor family driver)14-provides temperature reading function which is bound to ->rbin() method15-of the above w1_family_ops structure.16-w1_smem - driver for simple 64bit memory cell provides ID reading17-method.000000000000000000000000000001819You can call above methods by reading appropriate sysfs files.00000000000000000000000000000000000000000000
···1+The 1-wire (w1) subsystem2+------------------------------------------------------------------3+The 1-wire bus is a simple master-slave bus that communicates via a single4+signal wire (plus ground, so two wires).5+6+Devices communicate on the bus by pulling the signal to ground via an open7+drain output and by sampling the logic level of the signal line.8+9+The w1 subsystem provides the framework for managing w1 masters and10+communication with slaves.11+12+All w1 slave devices must be connected to a w1 bus master device.13+14+Example w1 master devices:15+ DS9490 usb device16+ W1-over-GPIO17+ DS2482 (i2c to w1 bridge)18+ Emulated devices, such as a RS232 converter, parallel port adapter, etc19+20+21+What does the w1 subsystem do?22+------------------------------------------------------------------23+When a w1 master driver registers with the w1 subsystem, the following occurs:24+25+ - sysfs entries for that w1 master are created26+ - the w1 bus is periodically searched for new slave devices27+28+When a device is found on the bus, w1 core checks if driver for it's family is29+loaded. If so, the family driver is attached to the slave.30+If there is no driver for the family, a simple sysfs entry is created31+for the slave device.32+33+34+W1 device families35+------------------------------------------------------------------36+Slave devices are handled by a driver written for a family of w1 devices.37+38+A family driver populates a struct w1_family_ops (see w1_family.h) and39+registers with the w1 subsystem.40+41+Current family drivers:42+w1_therm - (ds18?20 thermal sensor family driver)43+ provides temperature reading function which is bound to ->rbin() method44+ of the above w1_family_ops structure.45+46+w1_smem - driver for simple 64bit memory cell provides ID reading method.4748You can call above methods by reading appropriate sysfs files.49+50+51+What does a w1 master driver need to implement?52+------------------------------------------------------------------53+54+The driver for w1 bus master must provide at minimum two functions.55+56+Emulated devices must provide the ability to set the output signal level57+(write_bit) and sample the signal level (read_bit).58+59+Devices that support the 1-wire natively must provide the ability to write and60+sample a bit (touch_bit) and reset the bus (reset_bus).61+62+Most hardware provides higher-level functions that offload w1 handling.63+See struct w1_bus_master definition in w1.h for details.64+65+66+w1 master sysfs interface67+------------------------------------------------------------------68+<xx-xxxxxxxxxxxxx> - a directory for a found device. The format is family-serial69+bus - (standard) symlink to the w1 bus70+driver - (standard) symlink to the w1 driver71+w1_master_attempts - the number of times a search was attempted72+w1_master_max_slave_count73+ - the maximum slaves that may be attached to a master74+w1_master_name - the name of the device (w1_bus_masterX)75+w1_master_search - the number of searches left to do, -1=continual (default)76+w1_master_slave_count77+ - the number of slaves found78+w1_master_slaves - the names of the slaves, one per line79+w1_master_timeout - the delay in seconds between searches80+81+If you have a w1 bus that never changes (you don't add or remove devices),82+you can set w1_master_search to a positive value to disable searches.83+84+85+w1 slave sysfs interface86+------------------------------------------------------------------87+bus - (standard) symlink to the w1 bus88+driver - (standard) symlink to the w1 driver89+name - the device name, usually the same as the directory name90+w1_slave - (optional) a binary file whose meaning depends on the91+ family driver92+
+8-8
drivers/w1/Kconfig
···3config W14 tristate "Dallas's 1-wire support"5 ---help---6- Dallas's 1-wire bus is usefull to connect slow 1-pin devices 7 such as iButtons and thermal sensors.8-9 If you want W1 support, you should say Y here.1011 This W1 support can also be built as a module. If so, the module···17 help18 Say Y here if you want to communicate with your 1-wire devices19 using Matrox's G400 GPIO pins.20-21- This support is also available as a module. If so, the module 22 will be called matrox_w1.ko.2324config W1_DS9490···27 help28 Say Y here if you want to have a driver for DS9490R UWB <-> W1 bridge.2930- This support is also available as a module. If so, the module 31 will be called ds9490r.ko.3233-config W1_DS9490_BRIDGE34 tristate "DS9490R USB <-> W1 transport layer for 1-wire"35 depends on W1_DS949036 help37 Say Y here if you want to communicate with your 1-wire devices38 using DS9490R USB bridge.3940- This support is also available as a module. If so, the module 41 will be called ds_w1_bridge.ko.4243config W1_THERM···51 tristate "Simple 64bit memory family implementation"52 depends on W153 help54- Say Y here if you want to connect 1-wire 55 simple 64bit memory rom(ds2401/ds2411/ds1990*) to you wire.5657endmenu
···3config W14 tristate "Dallas's 1-wire support"5 ---help---6+ Dallas's 1-wire bus is usefull to connect slow 1-pin devices7 such as iButtons and thermal sensors.8+9 If you want W1 support, you should say Y here.1011 This W1 support can also be built as a module. If so, the module···17 help18 Say Y here if you want to communicate with your 1-wire devices19 using Matrox's G400 GPIO pins.20+21+ This support is also available as a module. If so, the module22 will be called matrox_w1.ko.2324config W1_DS9490···27 help28 Say Y here if you want to have a driver for DS9490R UWB <-> W1 bridge.2930+ This support is also available as a module. If so, the module31 will be called ds9490r.ko.3233+config W1_DS9490R_BRIDGE34 tristate "DS9490R USB <-> W1 transport layer for 1-wire"35 depends on W1_DS949036 help37 Say Y here if you want to communicate with your 1-wire devices38 using DS9490R USB bridge.3940+ This support is also available as a module. If so, the module41 will be called ds_w1_bridge.ko.4243config W1_THERM···51 tristate "Simple 64bit memory family implementation"52 depends on W153 help54+ Say Y here if you want to connect 1-wire55 simple 64bit memory rom(ds2401/ds2411/ds1990*) to you wire.5657endmenu
+2-2
drivers/w1/ds_w1_bridge.c
···83 return byte;84}8586-static void ds9490r_write_block(unsigned long data, u8 *buf, int len)87{88 struct ds_device *dev = (struct ds_device *)data;8990- ds_write_block(dev, buf, len);91}9293static u8 ds9490r_read_block(unsigned long data, u8 *buf, int len)
···83 return byte;84}8586+static void ds9490r_write_block(unsigned long data, const u8 *buf, int len)87{88 struct ds_device *dev = (struct ds_device *)data;8990+ ds_write_block(dev, (u8 *)buf, len);91}9293static u8 ds9490r_read_block(unsigned long data, u8 *buf, int len)
+5-5
drivers/w1/matrox_w1.c
···1/*2- * matrox_w1.c3 *4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>5- * 6 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License as published by···59 .remove = __devexit_p(matrox_w1_remove),60};6162-/* 63 * Matrox G400 DDC registers.64 */65···177178 dev->bus_master = (struct w1_bus_master *)(dev + 1);179180- /* 181- * True for G400, for some other we need resource 0, see drivers/video/matrox/matroxfb_base.c 182 */183184 dev->phys_addr = pci_resource_start(pdev, 1);
···1/*2+ * matrox_w1.c3 *4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>5+ *6 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License as published by···59 .remove = __devexit_p(matrox_w1_remove),60};6162+/*63 * Matrox G400 DDC registers.64 */65···177178 dev->bus_master = (struct w1_bus_master *)(dev + 1);179180+ /*181+ * True for G400, for some other we need resource 0, see drivers/video/matrox/matroxfb_base.c182 */183184 dev->phys_addr = pci_resource_start(pdev, 1);
+270-276
drivers/w1/w1.c
···1/*2- * w1.c3 *4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>5- * 6 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License as published by···59static int control_needs_exit;60static DECLARE_COMPLETION(w1_control_complete);61000000000000062static int w1_master_match(struct device *dev, struct device_driver *drv)63{64 return 1;···112 return sprintf(buf, "No family registered.\n");113}11400000000000000115static struct bus_type w1_bus_type = {116 .name = "w1",117 .match = w1_master_match,···146 .release = &w1_master_release147};148149-static struct device_attribute w1_slave_attribute = {150- .attr = {151- .name = "name",152- .mode = S_IRUGO,153- .owner = THIS_MODULE154- },155- .show = &w1_default_read_name,156-};157-158-static struct device_attribute w1_slave_attribute_val = {159- .attr = {160- .name = "value",161- .mode = S_IRUGO,162- .owner = THIS_MODULE163- },164- .show = &w1_default_read_name,165-};166-167static ssize_t w1_master_attribute_show_name(struct device *dev, struct device_attribute *attr, char *buf)168{169- struct w1_master *md = container_of (dev, struct w1_master, dev);170 ssize_t count;171-172 if (down_interruptible (&md->mutex))173 return -EBUSY;174175 count = sprintf(buf, "%s\n", md->name);176-000000000000000000000000000000000177 up(&md->mutex);178179 return count;···198{199 struct w1_master *md = container_of(dev, struct w1_master, dev);200 ssize_t count;201-202 if (down_interruptible(&md->mutex))203 return -EBUSY;204205 count = sprintf(buf, "0x%p\n", md->bus_master);206-207 up(&md->mutex);208 return count;209}···219{220 struct w1_master *md = container_of(dev, struct w1_master, dev);221 ssize_t count;222-223 if (down_interruptible(&md->mutex))224 return -EBUSY;225226 count = sprintf(buf, "%d\n", md->max_slave_count);227-228 up(&md->mutex);229 return count;230}···233{234 struct w1_master *md = container_of(dev, struct w1_master, dev);235 ssize_t count;236-237 if (down_interruptible(&md->mutex))238 return -EBUSY;239240 count = sprintf(buf, "%lu\n", md->attempts);241-242 up(&md->mutex);243 return count;244}···247{248 struct w1_master *md = container_of(dev, struct w1_master, dev);249 ssize_t count;250-251 if (down_interruptible(&md->mutex))252 return -EBUSY;253254 count = sprintf(buf, "%d\n", md->slave_count);255-256 up(&md->mutex);257 return count;258}259260static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device_attribute *attr, char *buf)261-262{263 struct w1_master *md = container_of(dev, struct w1_master, dev);264 int c = PAGE_SIZE;···274 list_for_each_safe(ent, n, &md->slist) {275 sl = list_entry(ent, struct w1_slave, w1_slave_entry);276277- c -= snprintf(buf + PAGE_SIZE - c, c, "%s\n", sl->name);278 }279 }280···283 return PAGE_SIZE - c;284}285286-static struct device_attribute w1_master_attribute_slaves = {287- .attr = {288- .name = "w1_master_slaves",289- .mode = S_IRUGO,290- .owner = THIS_MODULE,291- },292- .show = &w1_master_attribute_show_slaves,293-};294-static struct device_attribute w1_master_attribute_slave_count = {295- .attr = {296- .name = "w1_master_slave_count",297- .mode = S_IRUGO,298- .owner = THIS_MODULE299- },300- .show = &w1_master_attribute_show_slave_count,301-};302-static struct device_attribute w1_master_attribute_attempts = {303- .attr = {304- .name = "w1_master_attempts",305- .mode = S_IRUGO,306- .owner = THIS_MODULE307- },308- .show = &w1_master_attribute_show_attempts,309-};310-static struct device_attribute w1_master_attribute_max_slave_count = {311- .attr = {312- .name = "w1_master_max_slave_count",313- .mode = S_IRUGO,314- .owner = THIS_MODULE315- },316- .show = &w1_master_attribute_show_max_slave_count,317-};318-static struct device_attribute w1_master_attribute_timeout = {319- .attr = {320- .name = "w1_master_timeout",321- .mode = S_IRUGO,322- .owner = THIS_MODULE323- },324- .show = &w1_master_attribute_show_timeout,325-};326-static struct device_attribute w1_master_attribute_pointer = {327- .attr = {328- .name = "w1_master_pointer",329- .mode = S_IRUGO,330- .owner = THIS_MODULE331- },332- .show = &w1_master_attribute_show_pointer,333-};334-static struct device_attribute w1_master_attribute_name = {335- .attr = {336- .name = "w1_master_name",337- .mode = S_IRUGO,338- .owner = THIS_MODULE339- },340- .show = &w1_master_attribute_show_name,341};342343-static struct bin_attribute w1_slave_bin_attribute = {344- .attr = {345- .name = "w1_slave",346- .mode = S_IRUGO,347- .owner = THIS_MODULE,348- },349- .size = W1_SLAVE_DATA_SIZE,350- .read = &w1_default_read_bin,351};0000000000352353static int __w1_attach_slave_device(struct w1_slave *sl)354{···339 sl->dev.release = &w1_slave_release;340341 snprintf(&sl->dev.bus_id[0], sizeof(sl->dev.bus_id),342- "%02x-%012llx",343- (unsigned int) sl->reg_num.family,344- (unsigned long long) sl->reg_num.id);345- snprintf (&sl->name[0], sizeof(sl->name),346- "%02x-%012llx",347- (unsigned int) sl->reg_num.family,348- (unsigned long long) sl->reg_num.id);349350 dev_dbg(&sl->dev, "%s: registering %s.\n", __func__,351 &sl->dev.bus_id[0]);···353 err = device_register(&sl->dev);354 if (err < 0) {355 dev_err(&sl->dev,356- "Device registration [%s] failed. err=%d\n",357- sl->dev.bus_id, err);358 return err;359 }360361 memcpy(&sl->attr_bin, &w1_slave_bin_attribute, sizeof(sl->attr_bin));362 memcpy(&sl->attr_name, &w1_slave_attribute, sizeof(sl->attr_name));363- memcpy(&sl->attr_val, &w1_slave_attribute_val, sizeof(sl->attr_val));364-365 sl->attr_bin.read = sl->family->fops->rbin;366 sl->attr_name.show = sl->family->fops->rname;367- sl->attr_val.show = sl->family->fops->rval;368- sl->attr_val.attr.name = sl->family->fops->rvalname;369370 err = device_create_file(&sl->dev, &sl->attr_name);371 if (err < 0) {372 dev_err(&sl->dev,373- "sysfs file creation for [%s] failed. err=%d\n",374- sl->dev.bus_id, err);375 device_unregister(&sl->dev);376 return err;377 }378379- err = device_create_file(&sl->dev, &sl->attr_val);380- if (err < 0) {381- dev_err(&sl->dev,382- "sysfs file creation for [%s] failed. err=%d\n",383- sl->dev.bus_id, err);384- device_remove_file(&sl->dev, &sl->attr_name);385- device_unregister(&sl->dev);386- return err;387- }388-389- err = sysfs_create_bin_file(&sl->dev.kobj, &sl->attr_bin);390- if (err < 0) {391- dev_err(&sl->dev,392- "sysfs file creation for [%s] failed. err=%d\n",393- sl->dev.bus_id, err);394- device_remove_file(&sl->dev, &sl->attr_name);395- device_remove_file(&sl->dev, &sl->attr_val);396- device_unregister(&sl->dev);397- return err;398 }399400 list_add_tail(&sl->w1_slave_entry, &sl->master->slist);···418 spin_lock(&w1_flock);419 f = w1_family_registered(rn->family);420 if (!f) {421- spin_unlock(&w1_flock);422 dev_info(&dev->dev, "Family %x for %02x.%012llx.%02x is not registered.\n",423 rn->family, rn->family,424 (unsigned long long)rn->id, rn->crc);425- kfree(sl);426- return -ENODEV;427 }428 __w1_family_get(f);429 spin_unlock(&w1_flock);···451static void w1_slave_detach(struct w1_slave *sl)452{453 struct w1_netlink_msg msg;454-455 dev_info(&sl->dev, "%s: detaching %s.\n", __func__, sl->name);456457 while (atomic_read(&sl->refcnt)) {···462 flush_signals(current);463 }464465- sysfs_remove_bin_file (&sl->dev.kobj, &sl->attr_bin);00466 device_remove_file(&sl->dev, &sl->attr_name);467- device_remove_file(&sl->dev, &sl->attr_val);468 device_unregister(&sl->dev);469 w1_family_put(sl->family);00470471 memcpy(&msg.id.id, &sl->reg_num, sizeof(msg.id.id));472 msg.type = W1_SLAVE_REMOVE;···480{481 struct w1_master *dev;482 int found = 0;483-484- spin_lock_irq(&w1_mlock);485 list_for_each_entry(dev, &w1_masters, w1_master_entry) {486 if (dev->bus_master->data == data) {487 found = 1;···489 break;490 }491 }492- spin_unlock_irq(&w1_mlock);493494 return (found)?dev:NULL;495}496497-void w1_slave_found(unsigned long data, u64 rn)00000000000000498{499 int slave_count;500 struct w1_slave *sl;···523 data);524 return;525 }526-527 tmp = (struct w1_reg_num *) &rn;528529 slave_count = 0;···536 sl->reg_num.crc == tmp->crc) {537 set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);538 break;539- }540- else if (sl->reg_num.family == tmp->family) {541 family_found = 1;542 break;543 }···550 rn && ((le64_to_cpu(rn) >> 56) & 0xff) == w1_calc_crc8((u8 *)&rn, 7)) {551 w1_attach_slave_device(dev, tmp);552 }553-554 atomic_dec(&dev->refcnt);555}556557-void w1_search(struct w1_master *dev)00000000000000558{559- u64 last, rn, tmp;560- int i, count = 0;561- int last_family_desc, last_zero, last_device;562- int search_bit, id_bit, comp_bit, desc_bit;0563564- search_bit = id_bit = comp_bit = 0;565- rn = tmp = last = 0;566- last_device = last_zero = last_family_desc = 0;0567568 desc_bit = 64;569570- while (!(id_bit && comp_bit) && !last_device571- && count++ < dev->max_slave_count) {572- last = rn;573 rn = 0;574-575- last_family_desc = 0;576577 /*578 * Reset bus and all 1-wire device state machines···598 break;599 }600601-#if 1602 w1_write_8(dev, W1_SEARCH);603 for (i = 0; i < 64; ++i) {604- /*605- * Read 2 bits from bus.606- * All who don't sleep must send ID bit and COMPLEMENT ID bit.607- * They actually are ANDed between all senders.608- */609- id_bit = w1_touch_bit(dev, 1);610- comp_bit = w1_touch_bit(dev, 1);611612- if (id_bit && comp_bit)0000613 break;614615- if (id_bit == 0 && comp_bit == 0) {616- if (i == desc_bit)617- search_bit = 1;618- else if (i > desc_bit)619- search_bit = 0;620- else621- search_bit = ((last >> i) & 0x1);622623- if (search_bit == 0) {624- last_zero = i;625- if (last_zero < 9)626- last_family_desc = last_zero;627- }628-629- }630- else631- search_bit = id_bit;632-633- tmp = search_bit;634- rn |= (tmp << i);635-636- /*637- * Write 1 bit to bus638- * and make all who don't have "search_bit" in "i"'th position639- * in it's registration number sleep.640- */641- if (dev->bus_master->touch_bit)642- w1_touch_bit(dev, search_bit);643- else644- w1_write_bit(dev, search_bit);645-646 }647-#endif648649- if (desc_bit == last_zero)650- last_device = 1;651-652- desc_bit = last_zero;653-654- w1_slave_found(dev->bus_master->data, rn);655 }656}657658-int w1_create_master_attributes(struct w1_master *dev)659{660- if ( device_create_file(&dev->dev, &w1_master_attribute_slaves) < 0 ||661- device_create_file(&dev->dev, &w1_master_attribute_slave_count) < 0 ||662- device_create_file(&dev->dev, &w1_master_attribute_attempts) < 0 ||663- device_create_file(&dev->dev, &w1_master_attribute_max_slave_count) < 0 ||664- device_create_file(&dev->dev, &w1_master_attribute_timeout) < 0||665- device_create_file(&dev->dev, &w1_master_attribute_pointer) < 0||666- device_create_file(&dev->dev, &w1_master_attribute_name) < 0)667- return -EINVAL;668-669- return 0;670-}671-672-void w1_destroy_master_attributes(struct w1_master *dev)673-{674- device_remove_file(&dev->dev, &w1_master_attribute_slaves);675- device_remove_file(&dev->dev, &w1_master_attribute_slave_count);676- device_remove_file(&dev->dev, &w1_master_attribute_attempts);677- device_remove_file(&dev->dev, &w1_master_attribute_max_slave_count);678- device_remove_file(&dev->dev, &w1_master_attribute_timeout);679- device_remove_file(&dev->dev, &w1_master_attribute_pointer);680- device_remove_file(&dev->dev, &w1_master_attribute_name);681-}682-683-684-int w1_control(void *data)685-{686- struct w1_slave *sl;687- struct w1_master *dev;688- struct list_head *ent, *ment, *n, *mn;689 int err, have_to_wait = 0;690691 daemonize("w1_control");···652 if (signal_pending(current))653 flush_signals(current);654655- list_for_each_safe(ment, mn, &w1_masters) {656- dev = list_entry(ment, struct w1_master, w1_master_entry);657-658- if (!control_needs_exit && !dev->need_exit)659 continue;660 /*661 * Little race: we can create thread but not set the flag.···664 continue;665 }666667- spin_lock(&w1_mlock);668- list_del(&dev->w1_master_entry);669- spin_unlock(&w1_mlock);670-671 if (control_needs_exit) {672- dev->need_exit = 1;673674 err = kill_proc(dev->kpid, SIGTERM, 1);675 if (err)···674 dev->kpid);675 }676677- wait_for_completion(&dev->dev_exited);0000678679- list_for_each_safe(ent, n, &dev->slist) {680- sl = list_entry(ent, struct w1_slave, w1_slave_entry);681-682- if (!sl)683- dev_warn(&dev->dev,684- "%s: slave entry is NULL.\n",685- __func__);686- else {687 list_del(&sl->w1_slave_entry);688689 w1_slave_detach(sl);690 kfree(sl);691 }000692 }693- w1_destroy_master_attributes(dev);694- atomic_dec(&dev->refcnt);000000000000000000695 }696 }697···719int w1_process(void *data)720{721 struct w1_master *dev = (struct w1_master *) data;722- struct list_head *ent, *n;723- struct w1_slave *sl;724725 daemonize("%s", dev->name);726 allow_signal(SIGTERM);727728- while (!dev->need_exit) {729 try_to_freeze(PF_FREEZE);730 msleep_interruptible(w1_timeout * 1000);731732 if (signal_pending(current))733 flush_signals(current);734735- if (dev->need_exit)736 break;737738 if (!dev->initialized)739 continue;740000741 if (down_interruptible(&dev->mutex))742 continue;743744- list_for_each_safe(ent, n, &dev->slist) {745- sl = list_entry(ent, struct w1_slave, w1_slave_entry);746747- if (sl)748- clear_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);749- }750-751 w1_search_devices(dev, w1_slave_found);752753- list_for_each_safe(ent, n, &dev->slist) {754- sl = list_entry(ent, struct w1_slave, w1_slave_entry);755-756- if (sl && !test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) {757 list_del (&sl->w1_slave_entry);758759 w1_slave_detach (sl);760 kfree (sl);761762 dev->slave_count--;763- }764- else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags))765 sl->ttl = dev->slave_ttl;766 }0000767 up(&dev->mutex);768 }769···772 return 0;773}774775-int w1_init(void)776{777 int retval;778···812 return retval;813}814815-void w1_fini(void)816{817 struct w1_master *dev;818- struct list_head *ent, *n;819820- list_for_each_safe(ent, n, &w1_masters) {821- dev = list_entry(ent, struct w1_master, w1_master_entry);822 __w1_remove_master_device(dev);823- }824825 control_needs_exit = 1;826-827 wait_for_completion(&w1_control_complete);828829 driver_unregister(&w1_driver);
···1/*2+ * w1.c3 *4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>5+ *6 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License as published by···59static int control_needs_exit;60static DECLARE_COMPLETION(w1_control_complete);6162+/* stuff for the default family */63+static ssize_t w1_famdefault_read_name(struct device *dev, struct device_attribute *attr, char *buf)64+{65+ struct w1_slave *sl = container_of(dev, struct w1_slave, dev);66+ return(sprintf(buf, "%s\n", sl->name));67+}68+static struct w1_family_ops w1_default_fops = {69+ .rname = &w1_famdefault_read_name,70+};71+static struct w1_family w1_default_family = {72+ .fops = &w1_default_fops,73+};74+75static int w1_master_match(struct device *dev, struct device_driver *drv)76{77 return 1;···99 return sprintf(buf, "No family registered.\n");100}101102+static struct device_attribute w1_slave_attribute =103+ __ATTR(name, S_IRUGO, w1_default_read_name, NULL);104+105+static struct bin_attribute w1_slave_bin_attribute = {106+ .attr = {107+ .name = "w1_slave",108+ .mode = S_IRUGO,109+ .owner = THIS_MODULE,110+ },111+ .size = W1_SLAVE_DATA_SIZE,112+ .read = &w1_default_read_bin,113+};114+115+116static struct bus_type w1_bus_type = {117 .name = "w1",118 .match = w1_master_match,···119 .release = &w1_master_release120};121000000000000000000122static ssize_t w1_master_attribute_show_name(struct device *dev, struct device_attribute *attr, char *buf)123{124+ struct w1_master *md = container_of(dev, struct w1_master, dev);125 ssize_t count;126+127 if (down_interruptible (&md->mutex))128 return -EBUSY;129130 count = sprintf(buf, "%s\n", md->name);131+132+ up(&md->mutex);133+134+ return count;135+}136+137+static ssize_t w1_master_attribute_store_search(struct device * dev,138+ struct device_attribute *attr,139+ const char * buf, size_t count)140+{141+ struct w1_master *md = container_of(dev, struct w1_master, dev);142+143+ if (down_interruptible (&md->mutex))144+ return -EBUSY;145+146+ md->search_count = simple_strtol(buf, NULL, 0);147+148+ up(&md->mutex);149+150+ return count;151+}152+153+static ssize_t w1_master_attribute_show_search(struct device *dev,154+ struct device_attribute *attr,155+ char *buf)156+{157+ struct w1_master *md = container_of(dev, struct w1_master, dev);158+ ssize_t count;159+160+ if (down_interruptible (&md->mutex))161+ return -EBUSY;162+163+ count = sprintf(buf, "%d\n", md->search_count);164+165 up(&md->mutex);166167 return count;···156{157 struct w1_master *md = container_of(dev, struct w1_master, dev);158 ssize_t count;159+160 if (down_interruptible(&md->mutex))161 return -EBUSY;162163 count = sprintf(buf, "0x%p\n", md->bus_master);164+165 up(&md->mutex);166 return count;167}···177{178 struct w1_master *md = container_of(dev, struct w1_master, dev);179 ssize_t count;180+181 if (down_interruptible(&md->mutex))182 return -EBUSY;183184 count = sprintf(buf, "%d\n", md->max_slave_count);185+186 up(&md->mutex);187 return count;188}···191{192 struct w1_master *md = container_of(dev, struct w1_master, dev);193 ssize_t count;194+195 if (down_interruptible(&md->mutex))196 return -EBUSY;197198 count = sprintf(buf, "%lu\n", md->attempts);199+200 up(&md->mutex);201 return count;202}···205{206 struct w1_master *md = container_of(dev, struct w1_master, dev);207 ssize_t count;208+209 if (down_interruptible(&md->mutex))210 return -EBUSY;211212 count = sprintf(buf, "%d\n", md->slave_count);213+214 up(&md->mutex);215 return count;216}217218static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device_attribute *attr, char *buf)0219{220 struct w1_master *md = container_of(dev, struct w1_master, dev);221 int c = PAGE_SIZE;···233 list_for_each_safe(ent, n, &md->slist) {234 sl = list_entry(ent, struct w1_slave, w1_slave_entry);235236+ c -= snprintf(buf + PAGE_SIZE - c, c, "%s\n", sl->name);237 }238 }239···242 return PAGE_SIZE - c;243}244245+#define W1_MASTER_ATTR_RO(_name, _mode) \246+ struct device_attribute w1_master_attribute_##_name = \247+ __ATTR(w1_master_##_name, _mode, \248+ w1_master_attribute_show_##_name, NULL)249+250+#define W1_MASTER_ATTR_RW(_name, _mode) \251+ struct device_attribute w1_master_attribute_##_name = \252+ __ATTR(w1_master_##_name, _mode, \253+ w1_master_attribute_show_##_name, \254+ w1_master_attribute_store_##_name)255+256+static W1_MASTER_ATTR_RO(name, S_IRUGO);257+static W1_MASTER_ATTR_RO(slaves, S_IRUGO);258+static W1_MASTER_ATTR_RO(slave_count, S_IRUGO);259+static W1_MASTER_ATTR_RO(max_slave_count, S_IRUGO);260+static W1_MASTER_ATTR_RO(attempts, S_IRUGO);261+static W1_MASTER_ATTR_RO(timeout, S_IRUGO);262+static W1_MASTER_ATTR_RO(pointer, S_IRUGO);263+static W1_MASTER_ATTR_RW(search, S_IRUGO | S_IWUGO);264+265+static struct attribute *w1_master_default_attrs[] = {266+ &w1_master_attribute_name.attr,267+ &w1_master_attribute_slaves.attr,268+ &w1_master_attribute_slave_count.attr,269+ &w1_master_attribute_max_slave_count.attr,270+ &w1_master_attribute_attempts.attr,271+ &w1_master_attribute_timeout.attr,272+ &w1_master_attribute_pointer.attr,273+ &w1_master_attribute_search.attr,274+ NULL0000000000000000000000000275};276277+static struct attribute_group w1_master_defattr_group = {278+ .attrs = w1_master_default_attrs,000000279};280+281+int w1_create_master_attributes(struct w1_master *master)282+{283+ return sysfs_create_group(&master->dev.kobj, &w1_master_defattr_group);284+}285+286+void w1_destroy_master_attributes(struct w1_master *master)287+{288+ sysfs_remove_group(&master->dev.kobj, &w1_master_defattr_group);289+}290291static int __w1_attach_slave_device(struct w1_slave *sl)292{···319 sl->dev.release = &w1_slave_release;320321 snprintf(&sl->dev.bus_id[0], sizeof(sl->dev.bus_id),322+ "%02x-%012llx",323+ (unsigned int) sl->reg_num.family,324+ (unsigned long long) sl->reg_num.id);325+ snprintf(&sl->name[0], sizeof(sl->name),326+ "%02x-%012llx",327+ (unsigned int) sl->reg_num.family,328+ (unsigned long long) sl->reg_num.id);329330 dev_dbg(&sl->dev, "%s: registering %s.\n", __func__,331 &sl->dev.bus_id[0]);···333 err = device_register(&sl->dev);334 if (err < 0) {335 dev_err(&sl->dev,336+ "Device registration [%s] failed. err=%d\n",337+ sl->dev.bus_id, err);338 return err;339 }340341 memcpy(&sl->attr_bin, &w1_slave_bin_attribute, sizeof(sl->attr_bin));342 memcpy(&sl->attr_name, &w1_slave_attribute, sizeof(sl->attr_name));343+0344 sl->attr_bin.read = sl->family->fops->rbin;345 sl->attr_name.show = sl->family->fops->rname;00346347 err = device_create_file(&sl->dev, &sl->attr_name);348 if (err < 0) {349 dev_err(&sl->dev,350+ "sysfs file creation for [%s] failed. err=%d\n",351+ sl->dev.bus_id, err);352 device_unregister(&sl->dev);353 return err;354 }355356+ if ( sl->attr_bin.read ) {357+ err = sysfs_create_bin_file(&sl->dev.kobj, &sl->attr_bin);358+ if (err < 0) {359+ dev_err(&sl->dev,360+ "sysfs file creation for [%s] failed. err=%d\n",361+ sl->dev.bus_id, err);362+ device_remove_file(&sl->dev, &sl->attr_name);363+ device_unregister(&sl->dev);364+ return err;365+ }000000000366 }367368 list_add_tail(&sl->w1_slave_entry, &sl->master->slist);···410 spin_lock(&w1_flock);411 f = w1_family_registered(rn->family);412 if (!f) {413+ f= &w1_default_family;414 dev_info(&dev->dev, "Family %x for %02x.%012llx.%02x is not registered.\n",415 rn->family, rn->family,416 (unsigned long long)rn->id, rn->crc);00417 }418 __w1_family_get(f);419 spin_unlock(&w1_flock);···445static void w1_slave_detach(struct w1_slave *sl)446{447 struct w1_netlink_msg msg;448+449 dev_info(&sl->dev, "%s: detaching %s.\n", __func__, sl->name);450451 while (atomic_read(&sl->refcnt)) {···456 flush_signals(current);457 }458459+ if ( sl->attr_bin.read ) {460+ sysfs_remove_bin_file (&sl->dev.kobj, &sl->attr_bin);461+ }462 device_remove_file(&sl->dev, &sl->attr_name);0463 device_unregister(&sl->dev);464 w1_family_put(sl->family);465+466+ sl->master->slave_count--;467468 memcpy(&msg.id.id, &sl->reg_num, sizeof(msg.id.id));469 msg.type = W1_SLAVE_REMOVE;···471{472 struct w1_master *dev;473 int found = 0;474+475+ spin_lock_bh(&w1_mlock);476 list_for_each_entry(dev, &w1_masters, w1_master_entry) {477 if (dev->bus_master->data == data) {478 found = 1;···480 break;481 }482 }483+ spin_unlock_bh(&w1_mlock);484485 return (found)?dev:NULL;486}487488+void w1_reconnect_slaves(struct w1_family *f)489+{490+ struct w1_master *dev;491+492+ spin_lock_bh(&w1_mlock);493+ list_for_each_entry(dev, &w1_masters, w1_master_entry) {494+ dev_info(&dev->dev, "Reconnecting slaves in %s into new family %02x.\n",495+ dev->name, f->fid);496+ set_bit(W1_MASTER_NEED_RECONNECT, &dev->flags);497+ }498+ spin_unlock_bh(&w1_mlock);499+}500+501+502+static void w1_slave_found(unsigned long data, u64 rn)503{504 int slave_count;505 struct w1_slave *sl;···500 data);501 return;502 }503+504 tmp = (struct w1_reg_num *) &rn;505506 slave_count = 0;···513 sl->reg_num.crc == tmp->crc) {514 set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);515 break;516+ } else if (sl->reg_num.family == tmp->family) {0517 family_found = 1;518 break;519 }···528 rn && ((le64_to_cpu(rn) >> 56) & 0xff) == w1_calc_crc8((u8 *)&rn, 7)) {529 w1_attach_slave_device(dev, tmp);530 }531+532 atomic_dec(&dev->refcnt);533}534535+/**536+ * Performs a ROM Search & registers any devices found.537+ * The 1-wire search is a simple binary tree search.538+ * For each bit of the address, we read two bits and write one bit.539+ * The bit written will put to sleep all devies that don't match that bit.540+ * When the two reads differ, the direction choice is obvious.541+ * When both bits are 0, we must choose a path to take.542+ * When we can scan all 64 bits without having to choose a path, we are done.543+ *544+ * See "Application note 187 1-wire search algorithm" at www.maxim-ic.com545+ *546+ * @dev The master device to search547+ * @cb Function to call when a device is found548+ */549+void w1_search(struct w1_master *dev, w1_slave_found_callback cb)550{551+ u64 last_rn, rn, tmp64;552+ int i, slave_count = 0;553+ int last_zero, last_device;554+ int search_bit, desc_bit;555+ u8 triplet_ret = 0;556557+ search_bit = 0;558+ rn = last_rn = 0;559+ last_device = 0;560+ last_zero = -1;561562 desc_bit = 64;563564+ while ( !last_device && (slave_count++ < dev->max_slave_count) ) {565+ last_rn = rn;0566 rn = 0;00567568 /*569 * Reset bus and all 1-wire device state machines···563 break;564 }565566+ /* Start the search */567 w1_write_8(dev, W1_SEARCH);568 for (i = 0; i < 64; ++i) {569+ /* Determine the direction/search bit */570+ if (i == desc_bit)571+ search_bit = 1; /* took the 0 path last time, so take the 1 path */572+ else if (i > desc_bit)573+ search_bit = 0; /* take the 0 path on the next branch */574+ else575+ search_bit = ((last_rn >> i) & 0x1);576577+ /** Read two bits and write one bit */578+ triplet_ret = w1_triplet(dev, search_bit);579+580+ /* quit if no device responded */581+ if ( (triplet_ret & 0x03) == 0x03 )582 break;583584+ /* If both directions were valid, and we took the 0 path... */585+ if (triplet_ret == 0)586+ last_zero = i;0000587588+ /* extract the direction taken & update the device number */589+ tmp64 = (triplet_ret >> 2);590+ rn |= (tmp64 << i);00000000000000000000591 }0592593+ if ( (triplet_ret & 0x03) != 0x03 ) {594+ if ( (desc_bit == last_zero) || (last_zero < 0))595+ last_device = 1;596+ desc_bit = last_zero;597+ cb(dev->bus_master->data, rn);598+ }599 }600}601602+static int w1_control(void *data)603{604+ struct w1_slave *sl, *sln;605+ struct w1_master *dev, *n;000000000000000000000000000606 int err, have_to_wait = 0;607608 daemonize("w1_control");···665 if (signal_pending(current))666 flush_signals(current);667668+ list_for_each_entry_safe(dev, n, &w1_masters, w1_master_entry) {669+ if (!control_needs_exit && !dev->flags)00670 continue;671 /*672 * Little race: we can create thread but not set the flag.···679 continue;680 }6810000682 if (control_needs_exit) {683+ set_bit(W1_MASTER_NEED_EXIT, &dev->flags);684685 err = kill_proc(dev->kpid, SIGTERM, 1);686 if (err)···693 dev->kpid);694 }695696+ if (test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) {697+ wait_for_completion(&dev->dev_exited);698+ spin_lock_bh(&w1_mlock);699+ list_del(&dev->w1_master_entry);700+ spin_unlock_bh(&w1_mlock);701702+ list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {0000000703 list_del(&sl->w1_slave_entry);704705 w1_slave_detach(sl);706 kfree(sl);707 }708+ w1_destroy_master_attributes(dev);709+ atomic_dec(&dev->refcnt);710+ continue;711 }712+713+ if (test_bit(W1_MASTER_NEED_RECONNECT, &dev->flags)) {714+ dev_info(&dev->dev, "Reconnecting slaves in device %s.\n", dev->name);715+ down(&dev->mutex);716+ list_for_each_entry(sl, &dev->slist, w1_slave_entry) {717+ if (sl->family->fid == W1_FAMILY_DEFAULT) {718+ struct w1_reg_num rn;719+ list_del(&sl->w1_slave_entry);720+ w1_slave_detach(sl);721+722+ memcpy(&rn, &sl->reg_num, sizeof(rn));723+724+ kfree(sl);725+726+ w1_attach_slave_device(dev, &rn);727+ }728+ }729+ clear_bit(W1_MASTER_NEED_RECONNECT, &dev->flags);730+ up(&dev->mutex);731+ }732 }733 }734···720int w1_process(void *data)721{722 struct w1_master *dev = (struct w1_master *) data;723+ struct w1_slave *sl, *sln;0724725 daemonize("%s", dev->name);726 allow_signal(SIGTERM);727728+ while (!test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) {729 try_to_freeze(PF_FREEZE);730 msleep_interruptible(w1_timeout * 1000);731732 if (signal_pending(current))733 flush_signals(current);734735+ if (test_bit(W1_MASTER_NEED_EXIT, &dev->flags))736 break;737738 if (!dev->initialized)739 continue;740741+ if (dev->search_count == 0)742+ continue;743+744 if (down_interruptible(&dev->mutex))745 continue;746747+ list_for_each_entry(sl, &dev->slist, w1_slave_entry)748+ clear_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);7490000750 w1_search_devices(dev, w1_slave_found);751752+ list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {753+ if (!test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) {00754 list_del (&sl->w1_slave_entry);755756 w1_slave_detach (sl);757 kfree (sl);758759 dev->slave_count--;760+ } else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags))0761 sl->ttl = dev->slave_ttl;762 }763+764+ if (dev->search_count > 0)765+ dev->search_count--;766+767 up(&dev->mutex);768 }769···774 return 0;775}776777+static int w1_init(void)778{779 int retval;780···814 return retval;815}816817+static void w1_fini(void)818{819 struct w1_master *dev;0820821+ list_for_each_entry(dev, &w1_masters, w1_master_entry)0822 __w1_remove_master_device(dev);0823824 control_needs_exit = 1;0825 wait_for_completion(&w1_control_complete);826827 driver_unregister(&w1_driver);
+80-29
drivers/w1/w1.h
···1/*2- * w1.h3 *4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>5- * 6 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License as published by···74 int ttl;7576 struct w1_master *master;77- struct w1_family *family;78- struct device dev;79- struct completion dev_released;8081- struct bin_attribute attr_bin;82- struct device_attribute attr_name, attr_val;83};8485typedef void (* w1_slave_found_callback)(unsigned long, u64);860000000087struct w1_bus_master88{89- unsigned long data;09091- u8 (*read_bit)(unsigned long);92- void (*write_bit)(unsigned long, u8);93-94- u8 (*read_byte)(unsigned long);95- void (*write_byte)(unsigned long, u8);96-97- u8 (*read_block)(unsigned long, u8 *, int);98- void (*write_block)(unsigned long, u8 *, int);99-100- u8 (*touch_bit)(unsigned long, u8);101-102- u8 (*reset_bus)(unsigned long);103104- void (*search)(unsigned long, w1_slave_found_callback);000000000000000000000000000000000000000000000105};000106107struct w1_master108{···165 int slave_ttl;166 int initialized;167 u32 id;0168169 atomic_t refcnt;170171 void *priv;172 int priv_size;173174- int need_exit;0175 pid_t kpid;176- struct semaphore mutex;177178 struct device_driver *driver;179- struct device dev;180- struct completion dev_released;181- struct completion dev_exited;182183 struct w1_bus_master *bus_master;184185 u32 seq, groups;186- struct sock *nls;187};188189int w1_create_master_attributes(struct w1_master *);190-void w1_destroy_master_attributes(struct w1_master *);191-void w1_search(struct w1_master *dev);192193#endif /* __KERNEL__ */194
···1/*2+ * w1.h3 *4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>5+ *6 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License as published by···74 int ttl;7576 struct w1_master *master;77+ struct w1_family *family;78+ struct device dev;79+ struct completion dev_released;8081+ struct bin_attribute attr_bin;82+ struct device_attribute attr_name;83};8485typedef void (* w1_slave_found_callback)(unsigned long, u64);8687+88+/**89+ * Note: read_bit and write_bit are very low level functions and should only90+ * be used with hardware that doesn't really support 1-wire operations,91+ * like a parallel/serial port.92+ * Either define read_bit and write_bit OR define, at minimum, touch_bit and93+ * reset_bus.94+ */95struct w1_bus_master96{97+ /** the first parameter in all the functions below */98+ unsigned long data;99100+ /**101+ * Sample the line level102+ * @return the level read (0 or 1)103+ */104+ u8 (*read_bit)(unsigned long);0000000105106+ /** Sets the line level */107+ void (*write_bit)(unsigned long, u8);108+109+ /**110+ * touch_bit is the lowest-level function for devices that really111+ * support the 1-wire protocol.112+ * touch_bit(0) = write-0 cycle113+ * touch_bit(1) = write-1 / read cycle114+ * @return the bit read (0 or 1)115+ */116+ u8 (*touch_bit)(unsigned long, u8);117+118+ /**119+ * Reads a bytes. Same as 8 touch_bit(1) calls.120+ * @return the byte read121+ */122+ u8 (*read_byte)(unsigned long);123+124+ /**125+ * Writes a byte. Same as 8 touch_bit(x) calls.126+ */127+ void (*write_byte)(unsigned long, u8);128+129+ /**130+ * Same as a series of read_byte() calls131+ * @return the number of bytes read132+ */133+ u8 (*read_block)(unsigned long, u8 *, int);134+135+ /** Same as a series of write_byte() calls */136+ void (*write_block)(unsigned long, const u8 *, int);137+138+ /**139+ * Combines two reads and a smart write for ROM searches140+ * @return bit0=Id bit1=comp_id bit2=dir_taken141+ */142+ u8 (*triplet)(unsigned long, u8);143+144+ /**145+ * long write-0 with a read for the presence pulse detection146+ * @return -1=Error, 0=Device present, 1=No device present147+ */148+ u8 (*reset_bus)(unsigned long);149+150+ /** Really nice hardware can handles the ROM searches */151+ void (*search)(unsigned long, w1_slave_found_callback);152};153+154+#define W1_MASTER_NEED_EXIT 0155+#define W1_MASTER_NEED_RECONNECT 1156157struct w1_master158{···115 int slave_ttl;116 int initialized;117 u32 id;118+ int search_count;119120 atomic_t refcnt;121122 void *priv;123 int priv_size;124125+ long flags;126+127 pid_t kpid;128+ struct semaphore mutex;129130 struct device_driver *driver;131+ struct device dev;132+ struct completion dev_released;133+ struct completion dev_exited;134135 struct w1_bus_master *bus_master;136137 u32 seq, groups;138+ struct sock *nls;139};140141int w1_create_master_attributes(struct w1_master *);142+void w1_search(struct w1_master *dev, w1_slave_found_callback cb);0143144#endif /* __KERNEL__ */145
+6-4
drivers/w1/w1_family.c
···1/*2- * w1_family.c3 *4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>5- * 6 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License as published by···2728DEFINE_SPINLOCK(w1_flock);29static LIST_HEAD(w1_families);03031static int w1_check_family(struct w1_family *f)32{33- if (!f->fops->rname || !f->fops->rbin || !f->fops->rval || !f->fops->rvalname)34 return -EINVAL;3536 return 0;···61 newf->need_exit = 0;62 list_add_tail(&newf->family_entry, &w1_families);63 }64-65 spin_unlock(&w1_flock);006667 return ret;68}
···1/*2+ * w1_family.c3 *4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>5+ *6 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License as published by···2728DEFINE_SPINLOCK(w1_flock);29static LIST_HEAD(w1_families);30+extern void w1_reconnect_slaves(struct w1_family *f);3132static int w1_check_family(struct w1_family *f)33{34+ if (!f->fops->rname || !f->fops->rbin)35 return -EINVAL;3637 return 0;···60 newf->need_exit = 0;61 list_add_tail(&newf->family_entry, &w1_families);62 }063 spin_unlock(&w1_flock);64+65+ w1_reconnect_slaves(newf);6667 return ret;68}
+9-9
drivers/w1/w1_family.h
···1/*2- * w1_family.h3 *4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>5- * 6 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License as published by···27#include <asm/atomic.h>2829#define W1_FAMILY_DEFAULT 030-#define W1_FAMILY_THERM 0x1031-#define W1_FAMILY_SMEM 0x010003233#define MAXNAMELEN 3234···39{40 ssize_t (* rname)(struct device *, struct device_attribute *, char *);41 ssize_t (* rbin)(struct kobject *, char *, loff_t, size_t);42-43- ssize_t (* rval)(struct device *, struct device_attribute *, char *);44- unsigned char rvalname[MAXNAMELEN];45};4647struct w1_family48{49 struct list_head family_entry;50 u8 fid;51-52 struct w1_family_ops *fops;53-54 atomic_t refcnt;55 u8 need_exit;56};
···1/*2+ * w1_family.h3 *4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>5+ *6 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License as published by···27#include <asm/atomic.h>2829#define W1_FAMILY_DEFAULT 030+#define W1_FAMILY_SMEM_01 0x0131+#define W1_FAMILY_SMEM_81 0x8132+#define W1_THERM_DS18S20 0x1033+#define W1_THERM_DS1822 0x2234+#define W1_THERM_DS18B20 0x283536#define MAXNAMELEN 3237···36{37 ssize_t (* rname)(struct device *, struct device_attribute *, char *);38 ssize_t (* rbin)(struct kobject *, char *, loff_t, size_t);00039};4041struct w1_family42{43 struct list_head family_entry;44 u8 fid;45+46 struct w1_family_ops *fops;47+48 atomic_t refcnt;49 u8 need_exit;50};
+24-17
drivers/w1/w1_int.c
···1/*2- * w1_int.c3 *4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>5- * 6 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License as published by···3940extern int w1_process(void *);4142-struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,43- struct device_driver *driver, struct device *device)044{45 struct w1_master *dev;46 int err;···6162 dev->bus_master = (struct w1_bus_master *)(dev + 1);6364- dev->owner = THIS_MODULE;65- dev->max_slave_count = slave_count;66- dev->slave_count = 0;67- dev->attempts = 0;68- dev->kpid = -1;69- dev->initialized = 0;70- dev->id = id;71 dev->slave_ttl = slave_ttl;07273 atomic_set(&dev->refcnt, 2);74···107 return dev;108}109110-void w1_free_dev(struct w1_master *dev)111{112 device_unregister(&dev->dev);113 if (dev->nls && dev->nls->sk_socket)···121 struct w1_master *dev;122 int retval = 0;123 struct w1_netlink_msg msg;0000000124125 dev = w1_alloc_dev(w1_ids++, w1_max_slave_count, w1_max_slave_ttl, &w1_driver, &w1_device);126 if (!dev)···162 return 0;163164err_out_kill_thread:165- dev->need_exit = 1;166 if (kill_proc(dev->kpid, SIGTERM, 1))167 dev_err(&dev->dev,168 "Failed to send signal to w1 kernel thread %d.\n",···180 int err;181 struct w1_netlink_msg msg;182183- dev->need_exit = 1;184 err = kill_proc(dev->kpid, SIGTERM, 1);185 if (err)186 dev_err(&dev->dev,···206void w1_remove_master_device(struct w1_bus_master *bm)207{208 struct w1_master *dev = NULL;209- struct list_head *ent, *n;210211- list_for_each_safe(ent, n, &w1_masters) {212- dev = list_entry(ent, struct w1_master, w1_master_entry);213 if (!dev->initialized)214 continue;215
···1/*2+ * w1_int.c3 *4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>5+ *6 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License as published by···3940extern int w1_process(void *);4142+static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,43+ struct device_driver *driver,44+ struct device *device)45{46 struct w1_master *dev;47 int err;···6061 dev->bus_master = (struct w1_bus_master *)(dev + 1);6263+ dev->owner = THIS_MODULE;64+ dev->max_slave_count = slave_count;65+ dev->slave_count = 0;66+ dev->attempts = 0;67+ dev->kpid = -1;68+ dev->initialized = 0;69+ dev->id = id;70 dev->slave_ttl = slave_ttl;71+ dev->search_count = -1; /* continual scan */7273 atomic_set(&dev->refcnt, 2);74···105 return dev;106}107108+static void w1_free_dev(struct w1_master *dev)109{110 device_unregister(&dev->dev);111 if (dev->nls && dev->nls->sk_socket)···119 struct w1_master *dev;120 int retval = 0;121 struct w1_netlink_msg msg;122+123+ /* validate minimum functionality */124+ if (!(master->touch_bit && master->reset_bus) &&125+ !(master->write_bit && master->read_bit)) {126+ printk(KERN_ERR "w1_add_master_device: invalid function set\n");127+ return(-EINVAL);128+ }129130 dev = w1_alloc_dev(w1_ids++, w1_max_slave_count, w1_max_slave_ttl, &w1_driver, &w1_device);131 if (!dev)···153 return 0;154155err_out_kill_thread:156+ set_bit(W1_MASTER_NEED_EXIT, &dev->flags);157 if (kill_proc(dev->kpid, SIGTERM, 1))158 dev_err(&dev->dev,159 "Failed to send signal to w1 kernel thread %d.\n",···171 int err;172 struct w1_netlink_msg msg;173174+ set_bit(W1_MASTER_NEED_EXIT, &dev->flags);175 err = kill_proc(dev->kpid, SIGTERM, 1);176 if (err)177 dev_err(&dev->dev,···197void w1_remove_master_device(struct w1_bus_master *bm)198{199 struct w1_master *dev = NULL;0200201+ list_for_each_entry(dev, &w1_masters, w1_master_entry) {0202 if (!dev->initialized)203 continue;204
+2-4
drivers/w1/w1_int.h
···1/*2- * w1_int.h3 *4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>5- * 6 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License as published by···2728#include "w1.h"2930-struct w1_master * w1_alloc_dev(u32, int, int, struct device_driver *, struct device *);31-void w1_free_dev(struct w1_master *dev);32int w1_add_master_device(struct w1_bus_master *);33void w1_remove_master_device(struct w1_bus_master *);34void __w1_remove_master_device(struct w1_master *);
···1/*2+ * w1_int.h3 *4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>5+ *6 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License as published by···2728#include "w1.h"290030int w1_add_master_device(struct w1_bus_master *);31void w1_remove_master_device(struct w1_bus_master *);32void __w1_remove_master_device(struct w1_master *);
+105-12
drivers/w1/w1_io.c
···1/*2- * w1_io.c3 *4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>5- * 6 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License as published by···55 udelay(tm * w1_delay_parm);56}5700000058u8 w1_touch_bit(struct w1_master *dev, int bit)59{60 if (dev->bus_master->touch_bit)61 return dev->bus_master->touch_bit(dev->bus_master->data, bit);62- else63 return w1_read_bit(dev);000064}6566-void w1_write_bit(struct w1_master *dev, int bit)000067{68 if (bit) {69 dev->bus_master->write_bit(dev->bus_master->data, 0);···92 }93}9400000095void w1_write_8(struct w1_master *dev, u8 byte)96{97 int i;···106 dev->bus_master->write_byte(dev->bus_master->data, byte);107 else108 for (i = 0; i < 8; ++i)109- w1_write_bit(dev, (byte >> i) & 0x1);110}111112-u8 w1_read_bit(struct w1_master *dev)00000113{114 int result;115···129 return result & 0x1;130}13100000000000000000000000000000000000000000000000132u8 w1_read_8(struct w1_master * dev)133{134 int i;···185 res = dev->bus_master->read_byte(dev->bus_master->data);186 else187 for (i = 0; i < 8; ++i)188- res |= (w1_read_bit(dev) << i);189190 return res;191}192193-void w1_write_block(struct w1_master *dev, u8 *buf, int len)00000000194{195 int i;196···209 w1_write_8(dev, buf[i]);210}21100000000212u8 w1_read_block(struct w1_master *dev, u8 *buf, int len)213{214 int i;···233 return ret;234}235000000236int w1_reset_bus(struct w1_master *dev)237{238- int result = 0;239240 if (dev->bus_master->reset_bus)241 result = dev->bus_master->reset_bus(dev->bus_master->data) & 0x1;···274 if (dev->bus_master->search)275 dev->bus_master->search(dev->bus_master->data, cb);276 else277- w1_search(dev);278}279280-EXPORT_SYMBOL(w1_write_bit);281EXPORT_SYMBOL(w1_write_8);282-EXPORT_SYMBOL(w1_read_bit);283EXPORT_SYMBOL(w1_read_8);284EXPORT_SYMBOL(w1_reset_bus);285EXPORT_SYMBOL(w1_calc_crc8);
···1/*2+ * w1_io.c3 *4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>5+ *6 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License as published by···55 udelay(tm * w1_delay_parm);56}5758+static void w1_write_bit(struct w1_master *dev, int bit);59+static u8 w1_read_bit(struct w1_master *dev);60+61+/**62+ * Generates a write-0 or write-1 cycle and samples the level.63+ */64u8 w1_touch_bit(struct w1_master *dev, int bit)65{66 if (dev->bus_master->touch_bit)67 return dev->bus_master->touch_bit(dev->bus_master->data, bit);68+ else if (bit)69 return w1_read_bit(dev);70+ else {71+ w1_write_bit(dev, 0);72+ return(0);73+ }74}7576+/**77+ * Generates a write-0 or write-1 cycle.78+ * Only call if dev->bus_master->touch_bit is NULL79+ */80+static void w1_write_bit(struct w1_master *dev, int bit)81{82 if (bit) {83 dev->bus_master->write_bit(dev->bus_master->data, 0);···78 }79}8081+/**82+ * Writes 8 bits.83+ *84+ * @param dev the master device85+ * @param byte the byte to write86+ */87void w1_write_8(struct w1_master *dev, u8 byte)88{89 int i;···86 dev->bus_master->write_byte(dev->bus_master->data, byte);87 else88 for (i = 0; i < 8; ++i)89+ w1_touch_bit(dev, (byte >> i) & 0x1);90}9192+93+/**94+ * Generates a write-1 cycle and samples the level.95+ * Only call if dev->bus_master->touch_bit is NULL96+ */97+static u8 w1_read_bit(struct w1_master *dev)98{99 int result;100···104 return result & 0x1;105}106107+/**108+ * Does a triplet - used for searching ROM addresses.109+ * Return bits:110+ * bit 0 = id_bit111+ * bit 1 = comp_bit112+ * bit 2 = dir_taken113+ * If both bits 0 & 1 are set, the search should be restarted.114+ *115+ * @param dev the master device116+ * @param bdir the bit to write if both id_bit and comp_bit are 0117+ * @return bit fields - see above118+ */119+u8 w1_triplet(struct w1_master *dev, int bdir)120+{121+ if ( dev->bus_master->triplet )122+ return(dev->bus_master->triplet(dev->bus_master->data, bdir));123+ else {124+ u8 id_bit = w1_touch_bit(dev, 1);125+ u8 comp_bit = w1_touch_bit(dev, 1);126+ u8 retval;127+128+ if ( id_bit && comp_bit )129+ return(0x03); /* error */130+131+ if ( !id_bit && !comp_bit ) {132+ /* Both bits are valid, take the direction given */133+ retval = bdir ? 0x04 : 0;134+ } else {135+ /* Only one bit is valid, take that direction */136+ bdir = id_bit;137+ retval = id_bit ? 0x05 : 0x02;138+ }139+140+ if ( dev->bus_master->touch_bit )141+ w1_touch_bit(dev, bdir);142+ else143+ w1_write_bit(dev, bdir);144+ return(retval);145+ }146+}147+148+/**149+ * Reads 8 bits.150+ *151+ * @param dev the master device152+ * @return the byte read153+ */154u8 w1_read_8(struct w1_master * dev)155{156 int i;···113 res = dev->bus_master->read_byte(dev->bus_master->data);114 else115 for (i = 0; i < 8; ++i)116+ res |= (w1_touch_bit(dev,1) << i);117118 return res;119}120121+/**122+ * Writes a series of bytes.123+ *124+ * @param dev the master device125+ * @param buf pointer to the data to write126+ * @param len the number of bytes to write127+ * @return the byte read128+ */129+void w1_write_block(struct w1_master *dev, const u8 *buf, int len)130{131 int i;132···129 w1_write_8(dev, buf[i]);130}131132+/**133+ * Reads a series of bytes.134+ *135+ * @param dev the master device136+ * @param buf pointer to the buffer to fill137+ * @param len the number of bytes to read138+ * @return the number of bytes read139+ */140u8 w1_read_block(struct w1_master *dev, u8 *buf, int len)141{142 int i;···145 return ret;146}147148+/**149+ * Issues a reset bus sequence.150+ *151+ * @param dev The bus master pointer152+ * @return 0=Device present, 1=No device present or error153+ */154int w1_reset_bus(struct w1_master *dev)155{156+ int result;157158 if (dev->bus_master->reset_bus)159 result = dev->bus_master->reset_bus(dev->bus_master->data) & 0x1;···180 if (dev->bus_master->search)181 dev->bus_master->search(dev->bus_master->data, cb);182 else183+ w1_search(dev, cb);184}185186+EXPORT_SYMBOL(w1_touch_bit);187EXPORT_SYMBOL(w1_write_8);0188EXPORT_SYMBOL(w1_read_8);189EXPORT_SYMBOL(w1_reset_bus);190EXPORT_SYMBOL(w1_calc_crc8);
+4-5
drivers/w1/w1_io.h
···1/*2- * w1_io.h3 *4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>5- * 6 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License as published by···2627void w1_delay(unsigned long);28u8 w1_touch_bit(struct w1_master *, int);29-void w1_write_bit(struct w1_master *, int);30void w1_write_8(struct w1_master *, u8);31-u8 w1_read_bit(struct w1_master *);32u8 w1_read_8(struct w1_master *);33int w1_reset_bus(struct w1_master *);34u8 w1_calc_crc8(u8 *, int);35-void w1_write_block(struct w1_master *, u8 *, int);36u8 w1_read_block(struct w1_master *, u8 *, int);37void w1_search_devices(struct w1_master *dev, w1_slave_found_callback cb);38
···1/*2+ * w1_io.h3 *4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>5+ *6 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License as published by···2627void w1_delay(unsigned long);28u8 w1_touch_bit(struct w1_master *, int);29+u8 w1_triplet(struct w1_master *dev, int bdir);30void w1_write_8(struct w1_master *, u8);031u8 w1_read_8(struct w1_master *);32int w1_reset_bus(struct w1_master *);33u8 w1_calc_crc8(u8 *, int);34+void w1_write_block(struct w1_master *, const u8 *, int);35u8 w1_read_block(struct w1_master *, u8 *, int);36void w1_search_devices(struct w1_master *dev, w1_slave_found_callback cb);37
+2-2
drivers/w1/w1_log.h
···1/*2- * w1_log.h3 *4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>5- * 6 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License as published by
···1/*2+ * w1_log.h3 *4 * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>5+ *6 *7 * This program is free software; you can redistribute it and/or modify8 * it under the terms of the GNU General Public License as published by