Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 114918
b: refs/heads/master
c: 6a158c0
h: refs/heads/master
v: v3
  • Loading branch information
David Fries authored and Linus Torvalds committed Oct 16, 2008
1 parent 4dd5b0f commit fc02fe8
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3c52e4e627896b42152cc6ff98216c302932227e
refs/heads/master: 6a158c0de791a81eb761ccf26ead1bd0834abac2
40 changes: 39 additions & 1 deletion trunk/drivers/w1/w1.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,10 +246,14 @@ static ssize_t w1_master_attribute_store_search(struct device * dev,
struct device_attribute *attr,
const char * buf, size_t count)
{
long tmp;
struct w1_master *md = dev_to_w1_master(dev);

if (strict_strtol(buf, 0, &tmp) == -EINVAL)
return -EINVAL;

mutex_lock(&md->mutex);
md->search_count = simple_strtol(buf, NULL, 0);
md->search_count = tmp;
mutex_unlock(&md->mutex);
wake_up_process(md->thread);

Expand All @@ -270,6 +274,38 @@ static ssize_t w1_master_attribute_show_search(struct device *dev,
return count;
}

static ssize_t w1_master_attribute_store_pullup(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
long tmp;
struct w1_master *md = dev_to_w1_master(dev);

if (strict_strtol(buf, 0, &tmp) == -EINVAL)
return -EINVAL;

mutex_lock(&md->mutex);
md->enable_pullup = tmp;
mutex_unlock(&md->mutex);
wake_up_process(md->thread);

return count;
}

static ssize_t w1_master_attribute_show_pullup(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct w1_master *md = dev_to_w1_master(dev);
ssize_t count;

mutex_lock(&md->mutex);
count = sprintf(buf, "%d\n", md->enable_pullup);
mutex_unlock(&md->mutex);

return count;
}

static ssize_t w1_master_attribute_show_pointer(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w1_master *md = dev_to_w1_master(dev);
Expand Down Expand Up @@ -365,6 +401,7 @@ static W1_MASTER_ATTR_RO(attempts, S_IRUGO);
static W1_MASTER_ATTR_RO(timeout, S_IRUGO);
static W1_MASTER_ATTR_RO(pointer, S_IRUGO);
static W1_MASTER_ATTR_RW(search, S_IRUGO | S_IWUGO);
static W1_MASTER_ATTR_RW(pullup, S_IRUGO | S_IWUGO);

static struct attribute *w1_master_default_attrs[] = {
&w1_master_attribute_name.attr,
Expand All @@ -375,6 +412,7 @@ static struct attribute *w1_master_default_attrs[] = {
&w1_master_attribute_timeout.attr,
&w1_master_attribute_pointer.attr,
&w1_master_attribute_search.attr,
&w1_master_attribute_pullup.attr,
NULL
};

Expand Down
12 changes: 12 additions & 0 deletions trunk/drivers/w1/w1.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,12 @@ struct w1_bus_master
*/
u8 (*reset_bus)(void *);

/**
* Put out a strong pull-up pulse of the specified duration.
* @return -1=Error, 0=completed
*/
u8 (*set_pullup)(void *, int);

/** Really nice hardware can handles the different types of ROM search
* w1_master* is passed to the slave found callback.
*/
Expand All @@ -167,6 +173,11 @@ struct w1_master
void *priv;
int priv_size;

/** 5V strong pullup enabled flag, 1 enabled, zero disabled. */
int enable_pullup;
/** 5V strong pullup duration in milliseconds, zero disabled. */
int pullup_duration;

struct task_struct *thread;
struct mutex mutex;

Expand Down Expand Up @@ -201,6 +212,7 @@ u8 w1_calc_crc8(u8 *, int);
void w1_write_block(struct w1_master *, const u8 *, int);
u8 w1_read_block(struct w1_master *, u8 *, int);
int w1_reset_select_slave(struct w1_slave *sl);
void w1_next_pullup(struct w1_master *, int);

static inline struct w1_slave* dev_to_w1_slave(struct device *dev)
{
Expand Down
16 changes: 16 additions & 0 deletions trunk/drivers/w1/w1_int.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@

static u32 w1_ids = 1;

static int w1_enable_pullup = 1;
module_param_named(enable_pullup, w1_enable_pullup, int, 0);

static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
struct device_driver *driver,
struct device *device)
Expand Down Expand Up @@ -59,6 +62,7 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
dev->initialized = 0;
dev->id = id;
dev->slave_ttl = slave_ttl;
dev->enable_pullup = w1_enable_pullup;
dev->search_count = -1; /* continual scan */

/* 1 for w1_process to decrement
Expand Down Expand Up @@ -107,6 +111,18 @@ int w1_add_master_device(struct w1_bus_master *master)
printk(KERN_ERR "w1_add_master_device: invalid function set\n");
return(-EINVAL);
}
/* While it would be electrically possible to make a device that
* generated a strong pullup in bit bang mode, only hardare that
* controls 1-wire time frames are even expected to support a strong
* pullup. w1_io.c would need to support calling set_pullup before
* the last write_bit operation of a w1_write_8 which it currently
* doesn't.
*/
if (!master->write_byte && !master->touch_bit && master->set_pullup) {
printk(KERN_ERR "w1_add_master_device: set_pullup requires "
"write_byte or touch_bit, disabling\n");
master->set_pullup = NULL;
}

dev = w1_alloc_dev(w1_ids++, w1_max_slave_count, w1_max_slave_ttl, &w1_master_driver, &w1_master_device);
if (!dev)
Expand Down
68 changes: 64 additions & 4 deletions trunk/drivers/w1/w1_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,40 @@ static void w1_write_bit(struct w1_master *dev, int bit)
}
}

/**
* Pre-write operation, currently only supporting strong pullups.
* Program the hardware for a strong pullup, if one has been requested and
* the hardware supports it.
*
* @param dev the master device
*/
static void w1_pre_write(struct w1_master *dev)
{
if (dev->pullup_duration &&
dev->enable_pullup && dev->bus_master->set_pullup) {
dev->bus_master->set_pullup(dev->bus_master->data,
dev->pullup_duration);
}
}

/**
* Post-write operation, currently only supporting strong pullups.
* If a strong pullup was requested, clear it if the hardware supports
* them, or execute the delay otherwise, in either case clear the request.
*
* @param dev the master device
*/
static void w1_post_write(struct w1_master *dev)
{
if (dev->pullup_duration) {
if (dev->enable_pullup && dev->bus_master->set_pullup)
dev->bus_master->set_pullup(dev->bus_master->data, 0);
else
msleep(dev->pullup_duration);
dev->pullup_duration = 0;
}
}

/**
* Writes 8 bits.
*
Expand All @@ -102,11 +136,17 @@ void w1_write_8(struct w1_master *dev, u8 byte)
{
int i;

if (dev->bus_master->write_byte)
if (dev->bus_master->write_byte) {
w1_pre_write(dev);
dev->bus_master->write_byte(dev->bus_master->data, byte);
}
else
for (i = 0; i < 8; ++i)
for (i = 0; i < 8; ++i) {
if (i == 7)
w1_pre_write(dev);
w1_touch_bit(dev, (byte >> i) & 0x1);
}
w1_post_write(dev);
}
EXPORT_SYMBOL_GPL(w1_write_8);

Expand Down Expand Up @@ -203,11 +243,14 @@ void w1_write_block(struct w1_master *dev, const u8 *buf, int len)
{
int i;

if (dev->bus_master->write_block)
if (dev->bus_master->write_block) {
w1_pre_write(dev);
dev->bus_master->write_block(dev->bus_master->data, buf, len);
}
else
for (i = 0; i < len; ++i)
w1_write_8(dev, buf[i]);
w1_write_8(dev, buf[i]); /* calls w1_pre_write */
w1_post_write(dev);
}
EXPORT_SYMBOL_GPL(w1_write_block);

Expand Down Expand Up @@ -306,3 +349,20 @@ int w1_reset_select_slave(struct w1_slave *sl)
return 0;
}
EXPORT_SYMBOL_GPL(w1_reset_select_slave);

/**
* Put out a strong pull-up of the specified duration after the next write
* operation. Not all hardware supports strong pullups. Hardware that
* doesn't support strong pullups will sleep for the given time after the
* write operation without a strong pullup. This is a one shot request for
* the next write, specifying zero will clear a previous request.
* The w1 master lock must be held.
*
* @param delay time in milliseconds
* @return 0=success, anything else=error
*/
void w1_next_pullup(struct w1_master *dev, int delay)
{
dev->pullup_duration = delay;
}
EXPORT_SYMBOL_GPL(w1_next_pullup);

0 comments on commit fc02fe8

Please sign in to comment.