All of lore.kernel.org
 help / color / mirror / Atom feed
* Fix ds2408 P0 output not working after power-on
@ 2013-05-07 12:40 Jean-Francois Dagenais
  2013-05-07 12:40 ` [PATCH] w1: ds2408: add magic sequence to disable P0 test mode Jean-Francois Dagenais
  0 siblings, 1 reply; 6+ messages in thread
From: Jean-Francois Dagenais @ 2013-05-07 12:40 UTC (permalink / raw)
  To: zbr; +Cc: linux-kernel

This issue is described in the v2 datasheet of ds2408 (see commit message). On
our board (9 ds2408 and 2 ds2433 on a ds1wm mastered bus), the problem affects
only 2 out of 9 chips 2408 and only after a long power off.

Adding the magic sequence described in the datasheet fixes the issue as
promised.

I had to do a little trick with the w1 master mutex since "add_slave" may be
called during w1 search of the master, at which time, the search op locks the
mutex the whole time. Checking if the mutex owner is the current thread to
determine whether locking is required or not sounds safe to me, any thoughts on
that? The bus search on my heavy setup works perfectly and is very stable.

Another point I'd like others to (perhaps) comment on is about doing this
"non-search" interaction with a particular slave between two search branches. I
did my homework and I can't find anything wrong with that.

/jfd


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH] w1: ds2408: add magic sequence to disable P0 test mode
  2013-05-07 12:40 Fix ds2408 P0 output not working after power-on Jean-Francois Dagenais
@ 2013-05-07 12:40 ` Jean-Francois Dagenais
  2013-05-07 14:00   ` [PATCH V2] " Jean-Francois Dagenais
  0 siblings, 1 reply; 6+ messages in thread
From: Jean-Francois Dagenais @ 2013-05-07 12:40 UTC (permalink / raw)
  To: zbr; +Cc: linux-kernel, Jean-Francois Dagenais

extract from http://datasheets.maximintegrated.com/en/ds/DS2408.pdf:

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

Signed-off-by: Jean-Francois Dagenais <jeff.dagenais@gmail.com>
---
 drivers/w1/slaves/w1_ds2408.c | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/drivers/w1/slaves/w1_ds2408.c b/drivers/w1/slaves/w1_ds2408.c
index e45eca1..49664b1 100644
--- a/drivers/w1/slaves/w1_ds2408.c
+++ b/drivers/w1/slaves/w1_ds2408.c
@@ -301,7 +301,35 @@ error:
 	return -EIO;
 }
 
-
+/**
+ * This is a special sequence we must do to ensure the P0 output is not stuck
+ * in test mode. This is described in rev 2 of the ds2408's datasheet
+ * (http://datasheets.maximintegrated.com/en/ds/DS2408.pdf) under
+ * "APPLICATION INFORMATION/Power-up timing".
+ */
+static int w1_f29_disable_test_mode(struct w1_slave *sl)
+{
+	int res;
+	u8 magic[10] = {0x96, };
+	u64 rn = le64_to_cpu(*((u64*)&sl->reg_num));
+	bool lock_needed = sl->master->mutex.owner != current;
+	memcpy(&magic[1], &rn, 8);
+	magic[9] = 0x3C;
+
+	if (lock_needed)
+		mutex_lock(&sl->master->mutex);
+
+	res = w1_reset_bus(sl->master);
+	if (res)
+		goto out;
+	w1_write_block(sl->master, magic, ARRAY_SIZE(magic));
+
+	res = w1_reset_bus(sl->master);
+out:
+	if (lock_needed)
+		mutex_unlock(&sl->master->mutex);
+	return res;
+}
 
 static struct bin_attribute w1_f29_sysfs_bin_files[] = {
 	{
@@ -362,6 +390,10 @@ static int w1_f29_add_slave(struct w1_slave *sl)
 	int err = 0;
 	int i;
 
+	err = w1_f29_disable_test_mode(sl);
+	if (err)
+		return err;
+
 	for (i = 0; i < ARRAY_SIZE(w1_f29_sysfs_bin_files) && !err; ++i)
 		err = sysfs_create_bin_file(
 			&sl->dev.kobj,
-- 
1.8.2.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH V2] w1: ds2408: add magic sequence to disable P0 test mode
  2013-05-07 12:40 ` [PATCH] w1: ds2408: add magic sequence to disable P0 test mode Jean-Francois Dagenais
@ 2013-05-07 14:00   ` Jean-Francois Dagenais
  2013-05-09 18:03     ` Andrew Morton
  0 siblings, 1 reply; 6+ messages in thread
From: Jean-Francois Dagenais @ 2013-05-07 14:00 UTC (permalink / raw)
  To: zbr; +Cc: linux-kernel, Jean-Francois Dagenais

V2: use the new bus_mutex

extract from http://datasheets.maximintegrated.com/en/ds/DS2408.pdf:

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

Signed-off-by: Jean-Francois Dagenais <jeff.dagenais@gmail.com>
---
 drivers/w1/slaves/w1_ds2408.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/drivers/w1/slaves/w1_ds2408.c b/drivers/w1/slaves/w1_ds2408.c
index e45eca1..3fc1b38 100644
--- a/drivers/w1/slaves/w1_ds2408.c
+++ b/drivers/w1/slaves/w1_ds2408.c
@@ -301,7 +301,32 @@ error:
 	return -EIO;
 }
 
+/**
+ * This is a special sequence we must do to ensure the P0 output is not stuck
+ * in test mode. This is described in rev 2 of the ds2408's datasheet
+ * (http://datasheets.maximintegrated.com/en/ds/DS2408.pdf) under
+ * "APPLICATION INFORMATION/Power-up timing".
+ */
+static int w1_f29_disable_test_mode(struct w1_slave *sl)
+{
+	int res;
+	u8 magic[10] = {0x96, };
+	u64 rn = le64_to_cpu(*((u64*)&sl->reg_num));
+	memcpy(&magic[1], &rn, 8);
+	magic[9] = 0x3C;
+
+	mutex_lock(&sl->master->bus_mutex);
 
+	res = w1_reset_bus(sl->master);
+	if (res)
+		goto out;
+	w1_write_block(sl->master, magic, ARRAY_SIZE(magic));
+
+	res = w1_reset_bus(sl->master);
+out:
+	mutex_unlock(&sl->master->bus_mutex);
+	return res;
+}
 
 static struct bin_attribute w1_f29_sysfs_bin_files[] = {
 	{
@@ -362,6 +387,10 @@ static int w1_f29_add_slave(struct w1_slave *sl)
 	int err = 0;
 	int i;
 
+	err = w1_f29_disable_test_mode(sl);
+	if (err)
+		return err;
+
 	for (i = 0; i < ARRAY_SIZE(w1_f29_sysfs_bin_files) && !err; ++i)
 		err = sysfs_create_bin_file(
 			&sl->dev.kobj,
-- 
1.8.2.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH V2] w1: ds2408: add magic sequence to disable P0 test mode
  2013-05-07 14:00   ` [PATCH V2] " Jean-Francois Dagenais
@ 2013-05-09 18:03     ` Andrew Morton
  2013-05-09 19:33       ` Jean-François Dagenais
  0 siblings, 1 reply; 6+ messages in thread
From: Andrew Morton @ 2013-05-09 18:03 UTC (permalink / raw)
  To: Jean-Francois Dagenais; +Cc: zbr, linux-kernel, Greg KH

On Tue,  7 May 2013 10:00:48 -0400 Jean-Francois Dagenais <jeff.dagenais@gmail.com> wrote:

> V2: use the new bus_mutex
> 
> extract from http://datasheets.maximintegrated.com/en/ds/DS2408.pdf:
> 
> 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
> 
> ...
>
> --- a/drivers/w1/slaves/w1_ds2408.c
> +++ b/drivers/w1/slaves/w1_ds2408.c
> @@ -301,7 +301,32 @@ error:
>  	return -EIO;
>  }
>  
> +/**

/** is used to introduce kerneldoc comments, but this isn't a kerneldoc
comment.  Just use /* here.

> + * This is a special sequence we must do to ensure the P0 output is not stuck
> + * in test mode. This is described in rev 2 of the ds2408's datasheet
> + * (http://datasheets.maximintegrated.com/en/ds/DS2408.pdf) under
> + * "APPLICATION INFORMATION/Power-up timing".
> + */
> +static int w1_f29_disable_test_mode(struct w1_slave *sl)
> +{
> +	int res;
> +	u8 magic[10] = {0x96, };
> +	u64 rn = le64_to_cpu(*((u64*)&sl->reg_num));
> +	memcpy(&magic[1], &rn, 8);
> +	magic[9] = 0x3C;

(please put a blank line between end-of-locals and start-of-code)

The casting looks decidedly dodgy.  I guess it won't cause an unalignned
exception due to reg_num's alignment, but it appears to defeat the
endianness handling in the definotion of `struct w1_reg_num'.

Are you sure this will work OK with all architectures and both
__LITTLE_ENDIAN_BITFIELD and __BIG_ENDIAN_BITFIELD?

> +	mutex_lock(&sl->master->bus_mutex);
>  
> +	res = w1_reset_bus(sl->master);
> +	if (res)
> +		goto out;
> +	w1_write_block(sl->master, magic, ARRAY_SIZE(magic));
> +
> +	res = w1_reset_bus(sl->master);
> +out:
> +	mutex_unlock(&sl->master->bus_mutex);
> +	return res;
> +}
>  
>  static struct bin_attribute w1_f29_sysfs_bin_files[] = {
>  	{
> @@ -362,6 +387,10 @@ static int w1_f29_add_slave(struct w1_slave *sl)
>  	int err = 0;
>  	int i;
>  
> +	err = w1_f29_disable_test_mode(sl);
> +	if (err)
> +		return err;
> +
>  	for (i = 0; i < ARRAY_SIZE(w1_f29_sysfs_bin_files) && !err; ++i)
>  		err = sysfs_create_bin_file(
>  			&sl->dev.kobj,


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH V2] w1: ds2408: add magic sequence to disable P0 test mode
  2013-05-09 18:03     ` Andrew Morton
@ 2013-05-09 19:33       ` Jean-François Dagenais
  2013-05-10 14:15         ` Evgeniy Polyakov
  0 siblings, 1 reply; 6+ messages in thread
From: Jean-François Dagenais @ 2013-05-09 19:33 UTC (permalink / raw)
  To: Andrew Morton; +Cc: zbr, linux-kernel, Greg KH


On 2013-05-09, at 2:03 PM, Andrew Morton wrote:
[...]
>> +static int w1_f29_disable_test_mode(struct w1_slave *sl)
>> +{
>> +	int res;
>> +	u8 magic[10] = {0x96, };
>> +	u64 rn = le64_to_cpu(*((u64*)&sl->reg_num));
>> +	memcpy(&magic[1], &rn, 8);
>> +	magic[9] = 0x3C;
> 
> (please put a blank line between end-of-locals and start-of-code)
> 
> The casting looks decidedly dodgy.  I guess it won't cause an unalignned
> exception due to reg_num's alignment, but it appears to defeat the
> endianness handling in the definotion of `struct w1_reg_num'.
> 
> Are you sure this will work OK with all architectures and both
> __LITTLE_ENDIAN_BITFIELD and __BIG_ENDIAN_BITFIELD?

To be honest, I didn't really thought about it that much, I just copy pasted that from Evgeniy Polyakov's hunk at drivers/w1/w1_io.c, function w1_reset_select_slave(struct w1_slave *sl) exept I changed the MATCH_ROM with magic 0x96 and appended magic 0x3C. I have tested it only on the available platform I have which is x86. I agree it looks dodgy. Do you have an alternative? You are certainly more familiar with the kernel's fancy bit and endian tools than I am. I'd be willing to test prior to sending V3.


struct w1_reg_num
{
#if defined(__LITTLE_ENDIAN_BITFIELD)
	__u64	family:8,
		id:48,
		crc:8;
#elif defined(__BIG_ENDIAN_BITFIELD)
	__u64	crc:8,
		id:48,
		family:8;
#else
#error "Please fix <asm/byteorder.h>"
#endif
};

On the wire, the family byte should be sent first, then the MSB of id, then the rest of id and finally the crc.

Perhaps Evgeniy can chime in here?

Cheers,
/jfd

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH V2] w1: ds2408: add magic sequence to disable P0 test mode
  2013-05-09 19:33       ` Jean-François Dagenais
@ 2013-05-10 14:15         ` Evgeniy Polyakov
  0 siblings, 0 replies; 6+ messages in thread
From: Evgeniy Polyakov @ 2013-05-10 14:15 UTC (permalink / raw)
  To: Jean-François Dagenais; +Cc: Andrew Morton, linux-kernel, Greg KH

On Thu, May 09, 2013 at 03:33:23PM -0400, Jean-François Dagenais (jeff.dagenais@gmail.com) wrote:
> To be honest, I didn't really thought about it that much, I just copy pasted that from Evgeniy Polyakov's hunk at drivers/w1/w1_io.c, function w1_reset_select_slave(struct w1_slave *sl) exept I changed the MATCH_ROM with magic 0x96 and appended magic 0x3C. I have tested it only on the available platform I have which is x86. I agree it looks dodgy. Do you have an alternative? You are certainly more familiar with the kernel's fancy bit and endian tools than I am. I'd be willing to test prior to sending V3.
> 
> 
> struct w1_reg_num
> {
> #if defined(__LITTLE_ENDIAN_BITFIELD)
> 	__u64	family:8,
> 		id:48,
> 		crc:8;
> #elif defined(__BIG_ENDIAN_BITFIELD)
> 	__u64	crc:8,
> 		id:48,
> 		family:8;
> #else
> #error "Please fix <asm/byteorder.h>"
> #endif
> };
> 
> On the wire, the family byte should be sent first, then the MSB of id, then the rest of id and finally the crc.
> 
> Perhaps Evgeniy can chime in here?

That's transform is only used to cast structure to uint64_t, nothing
fancy. In-memory structure should be ok because of above definition on
every endian.

-- 
	Evgeniy Polyakov

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2013-05-10 14:24 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-05-07 12:40 Fix ds2408 P0 output not working after power-on Jean-Francois Dagenais
2013-05-07 12:40 ` [PATCH] w1: ds2408: add magic sequence to disable P0 test mode Jean-Francois Dagenais
2013-05-07 14:00   ` [PATCH V2] " Jean-Francois Dagenais
2013-05-09 18:03     ` Andrew Morton
2013-05-09 19:33       ` Jean-François Dagenais
2013-05-10 14:15         ` Evgeniy Polyakov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.