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

drivers/w1/slaves/w1_ds2408.c: add magic sequence to disable P0 test mode

Power-up timing

The DS2408 is sensitive to the power-on slew rate and can inadvertently
power up with a test mode feature enabled. When this occurs, the P0 port
does not respond to the Channel Access Write command. For most reliable
operation, it is recommended to disable the test mode after every power-on
reset using the Disable Test Mode sequence shown below. The 64-bit ROM
code must be transmitted in the same bit sequence as with the Match ROM
command, i.e., least significant bit first. This precaution is
recommended in parasite power mode (VCC pin connected to GND) as well as
with VCC power.

Disable Test Mode:
RST,PD,96h,<64-bit DS2408 ROM Code>,3Ch,RST,PD

[akpm@linux-foundation.org: don't use kerenldoc token to introduce a non-kerneldoc comment, tweak whitespace]
Signed-off-by: Jean-Francois Dagenais <jeff.dagenais@gmail.com>
Cc: Evgeniy Polyakov <zbr@ioremap.net>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Jean-Francois Dagenais and committed by
Linus Torvalds
d5528773 5af1a9ce

+30
+30
drivers/w1/slaves/w1_ds2408.c
··· 302 302 return -EIO; 303 303 } 304 304 305 + /* 306 + * This is a special sequence we must do to ensure the P0 output is not stuck 307 + * in test mode. This is described in rev 2 of the ds2408's datasheet 308 + * (http://datasheets.maximintegrated.com/en/ds/DS2408.pdf) under 309 + * "APPLICATION INFORMATION/Power-up timing". 310 + */ 311 + static int w1_f29_disable_test_mode(struct w1_slave *sl) 312 + { 313 + int res; 314 + u8 magic[10] = {0x96, }; 315 + u64 rn = le64_to_cpu(*((u64*)&sl->reg_num)); 305 316 317 + memcpy(&magic[1], &rn, 8); 318 + magic[9] = 0x3C; 319 + 320 + mutex_lock(&sl->master->bus_mutex); 321 + 322 + res = w1_reset_bus(sl->master); 323 + if (res) 324 + goto out; 325 + w1_write_block(sl->master, magic, ARRAY_SIZE(magic)); 326 + 327 + res = w1_reset_bus(sl->master); 328 + out: 329 + mutex_unlock(&sl->master->bus_mutex); 330 + return res; 331 + } 306 332 307 333 static struct bin_attribute w1_f29_sysfs_bin_files[] = { 308 334 { ··· 388 362 { 389 363 int err = 0; 390 364 int i; 365 + 366 + err = w1_f29_disable_test_mode(sl); 367 + if (err) 368 + return err; 391 369 392 370 for (i = 0; i < ARRAY_SIZE(w1_f29_sysfs_bin_files) && !err; ++i) 393 371 err = sysfs_create_bin_file(