* [PATCH 5/7] [RFC] ds2760 W1 slave
@ 2007-04-11 23:25 Anton Vorontsov
2007-04-12 7:08 ` Evgeniy Polyakov
0 siblings, 1 reply; 5+ messages in thread
From: Anton Vorontsov @ 2007-04-11 23:25 UTC (permalink / raw)
To: linux-kernel; +Cc: kernel-discuss, johnpol
This is W1 slave for ds2760 chip, found inside almost every HP iPaq and
HTC PDAs/phones.
---
drivers/w1/slaves/Kconfig | 13 +++
drivers/w1/slaves/Makefile | 1 +
drivers/w1/slaves/w1_ds2760.c | 162 +++++++++++++++++++++++++++++++++++++++++
drivers/w1/slaves/w1_ds2760.h | 52 +++++++++++++
drivers/w1/w1_family.h | 1 +
5 files changed, 229 insertions(+), 0 deletions(-)
create mode 100644 drivers/w1/slaves/w1_ds2760.c
create mode 100644 drivers/w1/slaves/w1_ds2760.h
diff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig
index 904e5ae..df95d6c 100644
--- a/drivers/w1/slaves/Kconfig
+++ b/drivers/w1/slaves/Kconfig
@@ -35,4 +35,17 @@ config W1_SLAVE_DS2433_CRC
Each block has 30 bytes of data and a two byte CRC16.
Full block writes are only allowed if the CRC is valid.
+config W1_SLAVE_DS2760
+ tristate "Dallas 2760 battery monitor chip (HP iPAQ & others)"
+ depends on W1
+ help
+ If you enable this you will have the DS2760 battery monitor
+ chip support.
+
+ The battery monitor chip is used in many batteries/devices
+ as the one who is responsible for charging/discharging/monitoring
+ Li+ batteries.
+
+ If you are unsure, say N.
+
endmenu
diff --git a/drivers/w1/slaves/Makefile b/drivers/w1/slaves/Makefile
index 725dcfd..a8eb752 100644
--- a/drivers/w1/slaves/Makefile
+++ b/drivers/w1/slaves/Makefile
@@ -5,4 +5,5 @@
obj-$(CONFIG_W1_SLAVE_THERM) += w1_therm.o
obj-$(CONFIG_W1_SLAVE_SMEM) += w1_smem.o
obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o
+obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o
diff --git a/drivers/w1/slaves/w1_ds2760.c b/drivers/w1/slaves/w1_ds2760.c
new file mode 100644
index 0000000..21b0ef6
--- /dev/null
+++ b/drivers/w1/slaves/w1_ds2760.c
@@ -0,0 +1,162 @@
+/*
+ * 1-Wire implementation for the ds2760 chip
+ *
+ * Copyright (c) 2004-2005, Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
+ *
+ * Use consistent with the GNU GPL is permitted,
+ * provided that this copyright notice is
+ * preserved in its entirety in all copies and derived works.
+ *
+ */
+
+#include <asm/types.h>
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/jiffies.h>
+
+#include "../w1.h"
+#include "../w1_int.h"
+#include "../w1_family.h"
+#include "w1_ds2760.h"
+
+static int w1_ds2760_io(struct device *dev, char *buf, int addr, size_t count,
+ int io)
+{
+ struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
+
+ if (!dev)
+ return 0;
+
+ mutex_lock(&sl->master->mutex);
+
+ if (addr > DS2760_DATA_SIZE || addr < 0) {
+ count = 0;
+ goto out;
+ }
+ if (addr + count > DS2760_DATA_SIZE)
+ count = DS2760_DATA_SIZE - addr;
+
+ if (!w1_reset_select_slave(sl)) {
+ if (!io) {
+ w1_write_8(sl->master, W1_DS2760_READ_DATA);
+ w1_write_8(sl->master, addr);
+ count = w1_read_block(sl->master, buf, count);
+ } else {
+ w1_write_8(sl->master, W1_DS2760_WRITE_DATA);
+ w1_write_8(sl->master, addr);
+ w1_write_block(sl->master, buf, count);
+ /* XXX w1_write_block returns void, not n_written */
+ }
+ }
+
+out:
+ mutex_unlock(&sl->master->mutex);
+
+ return count;
+}
+
+int w1_ds2760_read(struct device *dev, char *buf, int addr, size_t count)
+{
+ return w1_ds2760_io(dev, buf, addr, count, 0);
+}
+
+int w1_ds2760_write(struct device *dev, char *buf, int addr, size_t count)
+{
+ return w1_ds2760_io(dev, buf, addr, count, 1);
+}
+
+/* io = 0 means copy from EEPROM to SRAM, 1 means from SRAM to EEPROM */
+static int w1_ds2760_eeprom(struct device *dev, int addr, int io)
+{
+ struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
+ int ret = 0;
+
+ mutex_lock(&sl->master->mutex);
+
+ if (!w1_reset_select_slave(sl)) {
+ if (!io)
+ w1_write_8(sl->master, W1_DS2760_RECALL_DATA);
+ else
+ w1_write_8(sl->master, W1_DS2760_COPY_DATA);
+ w1_write_8(sl->master, addr);
+ }
+
+ mutex_unlock(&sl->master->mutex);
+
+ return ret;
+}
+
+int w1_ds2760_recall(struct device *dev, int addr)
+{
+ return w1_ds2760_eeprom(dev, addr, 0);
+}
+
+int w1_ds2760_copy(struct device *dev, int addr)
+{
+ return w1_ds2760_eeprom(dev, addr, 1);
+}
+
+static ssize_t w1_ds2760_read_bin(struct kobject *kobj, char *buf, loff_t off,
+ size_t count)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ return w1_ds2760_read(dev, buf, off, count);
+}
+
+static struct bin_attribute w1_ds2760_bin_attr = {
+ .attr = {
+ .name = "w1_slave",
+ .mode = S_IRUGO,
+ .owner = THIS_MODULE,
+ },
+ .size = DS2760_DATA_SIZE,
+ .read = w1_ds2760_read_bin,
+};
+
+static int w1_ds2760_add_slave(struct w1_slave *sl)
+{
+ return sysfs_create_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr);
+}
+
+static void w1_ds2760_remove_slave(struct w1_slave *sl)
+{
+ sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr);
+}
+
+static struct w1_family_ops w1_ds2760_fops = {
+ .add_slave = w1_ds2760_add_slave,
+ .remove_slave = w1_ds2760_remove_slave,
+};
+
+static struct w1_family w1_ds2760_family = {
+ .fid = W1_FAMILY_DS2760,
+ .fops = &w1_ds2760_fops,
+};
+
+static int __init w1_ds2760_init(void)
+{
+ printk("1-Wire driver for the DS2760 battery monitor chip "
+ " - (c) 2004-2005, Szabolcs Gyurko\n");
+ return w1_register_family(&w1_ds2760_family);
+}
+
+static void __exit w1_ds2760_exit(void)
+{
+ w1_unregister_family(&w1_ds2760_family);
+}
+
+EXPORT_SYMBOL(w1_ds2760_read);
+EXPORT_SYMBOL(w1_ds2760_write);
+EXPORT_SYMBOL(w1_ds2760_recall);
+EXPORT_SYMBOL(w1_ds2760_copy);
+
+module_init(w1_ds2760_init);
+module_exit(w1_ds2760_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>");
+MODULE_DESCRIPTION("1-wire Driver Dallas 2760 battery monitor chip");
diff --git a/drivers/w1/slaves/w1_ds2760.h b/drivers/w1/slaves/w1_ds2760.h
new file mode 100644
index 0000000..301aae4
--- /dev/null
+++ b/drivers/w1/slaves/w1_ds2760.h
@@ -0,0 +1,52 @@
+/*
+ * 1-Wire implementation for the ds2760 chip
+ *
+ * Copyright (c) 2004-2005, Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
+ *
+ * Use consistent with the GNU GPL is permitted,
+ * provided that this copyright notice is
+ * preserved in its entirety in all copies and derived works.
+ *
+ */
+
+#ifndef __w1_ds2760_h__
+#define __w1_ds2760_h__
+
+/* Known commands to the DS2760 chip */
+#define W1_DS2760_SWAP 0xAA
+#define W1_DS2760_READ_DATA 0x69
+#define W1_DS2760_WRITE_DATA 0x6C
+#define W1_DS2760_COPY_DATA 0x48
+#define W1_DS2760_RECALL_DATA 0xB8
+#define W1_DS2760_LOCK 0x6A
+
+/* Number of valid register addresses */
+#define DS2760_DATA_SIZE 0x40
+
+#define DS2760_PROTECTION_REG 0x00
+#define DS2760_STATUS_REG 0x01
+#define DS2760_EEPROM_REG 0x07
+#define DS2760_SPECIAL_FEATURE_REG 0x08
+#define DS2760_VOLTAGE_MSB 0x0c
+#define DS2760_VOLTAGE_LSB 0x0d
+#define DS2760_CURRENT_MSB 0x0e
+#define DS2760_CURRENT_LSB 0x0f
+#define DS2760_CURRENT_ACCUM_MSB 0x10
+#define DS2760_CURRENT_ACCUM_LSB 0x11
+#define DS2760_TEMP_MSB 0x18
+#define DS2760_TEMP_LSB 0x19
+#define DS2760_EEPROM_BLOCK0 0x20
+#define DS2760_ACTIVE_FULL 0x20
+#define DS2760_EEPROM_BLOCK1 0x30
+#define DS2760_RATED_CAPACITY 0x32
+#define DS2760_CURRENT_OFFSET_BIAS 0x33
+#define DS2760_ACTIVE_EMPTY 0x3b
+
+extern int w1_ds2760_read(struct device *dev, char *buf, int addr,
+ size_t count);
+extern int w1_ds2760_write(struct device *dev, char *buf, int addr,
+ size_t count);
+extern int w1_ds2760_recall(struct device *dev, int addr);
+extern int w1_ds2760_copy(struct device *dev, int addr);
+
+#endif /* !__w1_ds2760_h__ */
diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h
index 1e2ac40..ef1e1da 100644
--- a/drivers/w1/w1_family.h
+++ b/drivers/w1/w1_family.h
@@ -33,6 +33,7 @@
#define W1_THERM_DS1822 0x22
#define W1_EEPROM_DS2433 0x23
#define W1_THERM_DS18B20 0x28
+#define W1_FAMILY_DS2760 0x30
#define MAXNAMELEN 32
--
1.5.0.5-dirty
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 5/7] [RFC] ds2760 W1 slave
2007-04-11 23:25 [PATCH 5/7] [RFC] ds2760 W1 slave Anton Vorontsov
@ 2007-04-12 7:08 ` Evgeniy Polyakov
2007-04-12 14:08 ` Anton Vorontsov
0 siblings, 1 reply; 5+ messages in thread
From: Evgeniy Polyakov @ 2007-04-12 7:08 UTC (permalink / raw)
To: Anton Vorontsov; +Cc: linux-kernel, kernel-discuss
On Thu, Apr 12, 2007 at 03:25:17AM +0400, Anton Vorontsov (cbou@mail.ru) wrote:
> This is W1 slave for ds2760 chip, found inside almost every HP iPaq and
> HTC PDAs/phones.
Hi Anton, I have some cleanup-related comments, patch itself looks good.
> diff --git a/drivers/w1/slaves/w1_ds2760.c b/drivers/w1/slaves/w1_ds2760.c
> new file mode 100644
> index 0000000..21b0ef6
> --- /dev/null
> +++ b/drivers/w1/slaves/w1_ds2760.c
> @@ -0,0 +1,162 @@
> +/*
> + * 1-Wire implementation for the ds2760 chip
> + *
> + * Copyright (c) 2004-2005, Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
> + *
> + * Use consistent with the GNU GPL is permitted,
> + * provided that this copyright notice is
> + * preserved in its entirety in all copies and derived works.
> + *
> + */
> +
> +#include <asm/types.h>
Is it really needed?
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/moduleparam.h>
> +#include <linux/device.h>
> +#include <linux/types.h>
> +#include <linux/jiffies.h>
> +
> +#include "../w1.h"
> +#include "../w1_int.h"
> +#include "../w1_family.h"
> +#include "w1_ds2760.h"
> +
> +static int w1_ds2760_io(struct device *dev, char *buf, int addr, size_t count,
> + int io)
> +{
> + struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
> +
> + if (!dev)
> + return 0;
> +
> + mutex_lock(&sl->master->mutex);
> +
> + if (addr > DS2760_DATA_SIZE || addr < 0) {
> + count = 0;
> + goto out;
> + }
> + if (addr + count > DS2760_DATA_SIZE)
> + count = DS2760_DATA_SIZE - addr;
> +
> + if (!w1_reset_select_slave(sl)) {
> + if (!io) {
> + w1_write_8(sl->master, W1_DS2760_READ_DATA);
> + w1_write_8(sl->master, addr);
> + count = w1_read_block(sl->master, buf, count);
> + } else {
> + w1_write_8(sl->master, W1_DS2760_WRITE_DATA);
> + w1_write_8(sl->master, addr);
> + w1_write_block(sl->master, buf, count);
> + /* XXX w1_write_block returns void, not n_written */
> + }
> + }
> +
> +out:
> + mutex_unlock(&sl->master->mutex);
> +
> + return count;
> +}
> +
> +int w1_ds2760_read(struct device *dev, char *buf, int addr, size_t count)
> +{
> + return w1_ds2760_io(dev, buf, addr, count, 0);
> +}
> +
> +int w1_ds2760_write(struct device *dev, char *buf, int addr, size_t count)
> +{
> + return w1_ds2760_io(dev, buf, addr, count, 1);
> +}
Both are exported, who use them?
> +/* io = 0 means copy from EEPROM to SRAM, 1 means from SRAM to EEPROM */
> +static int w1_ds2760_eeprom(struct device *dev, int addr, int io)
> +{
> + struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
> + int ret = 0;
> +
> + mutex_lock(&sl->master->mutex);
> +
> + if (!w1_reset_select_slave(sl)) {
> + if (!io)
> + w1_write_8(sl->master, W1_DS2760_RECALL_DATA);
> + else
> + w1_write_8(sl->master, W1_DS2760_COPY_DATA);
> + w1_write_8(sl->master, addr);
> + }
> +
> + mutex_unlock(&sl->master->mutex);
> +
> + return ret;
> +}
> +
> +int w1_ds2760_recall(struct device *dev, int addr)
> +{
> + return w1_ds2760_eeprom(dev, addr, 0);
> +}
> +
> +int w1_ds2760_copy(struct device *dev, int addr)
> +{
> + return w1_ds2760_eeprom(dev, addr, 1);
> +}
The same.
> +static ssize_t w1_ds2760_read_bin(struct kobject *kobj, char *buf, loff_t off,
> + size_t count)
> +{
> + struct device *dev = container_of(kobj, struct device, kobj);
> + return w1_ds2760_read(dev, buf, off, count);
> +}
> +
> +static struct bin_attribute w1_ds2760_bin_attr = {
> + .attr = {
> + .name = "w1_slave",
> + .mode = S_IRUGO,
> + .owner = THIS_MODULE,
> + },
> + .size = DS2760_DATA_SIZE,
> + .read = w1_ds2760_read_bin,
> +};
> +
> +static int w1_ds2760_add_slave(struct w1_slave *sl)
> +{
> + return sysfs_create_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr);
> +}
> +
> +static void w1_ds2760_remove_slave(struct w1_slave *sl)
> +{
> + sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr);
> +}
> +
> +static struct w1_family_ops w1_ds2760_fops = {
> + .add_slave = w1_ds2760_add_slave,
> + .remove_slave = w1_ds2760_remove_slave,
> +};
> +
> +static struct w1_family w1_ds2760_family = {
> + .fid = W1_FAMILY_DS2760,
> + .fops = &w1_ds2760_fops,
> +};
> +
> +static int __init w1_ds2760_init(void)
> +{
> + printk("1-Wire driver for the DS2760 battery monitor chip "
> + " - (c) 2004-2005, Szabolcs Gyurko\n");
> + return w1_register_family(&w1_ds2760_family);
> +}
Add something like KERN_INFO into printk.
--
Evgeniy Polyakov
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 5/7] [RFC] ds2760 W1 slave
2007-04-12 7:08 ` Evgeniy Polyakov
@ 2007-04-12 14:08 ` Anton Vorontsov
2007-04-12 14:20 ` Evgeniy Polyakov
0 siblings, 1 reply; 5+ messages in thread
From: Anton Vorontsov @ 2007-04-12 14:08 UTC (permalink / raw)
To: Evgeniy Polyakov; +Cc: linux-kernel, kernel-discuss
Hello Evgeniy,
On Thu, Apr 12, 2007 at 11:08:54AM +0400, Evgeniy Polyakov wrote:
> On Thu, Apr 12, 2007 at 03:25:17AM +0400, Anton Vorontsov (cbou@mail.ru) wrote:
> > This is W1 slave for ds2760 chip, found inside almost every HP iPaq and
> > HTC PDAs/phones.
>
> Hi Anton, I have some cleanup-related comments, patch itself looks good.
>
> > diff --git a/drivers/w1/slaves/w1_ds2760.c b/drivers/w1/slaves/w1_ds2760.c
> > new file mode 100644
> > index 0000000..21b0ef6
> > --- /dev/null
> > +++ b/drivers/w1/slaves/w1_ds2760.c
> > @@ -0,0 +1,162 @@
> > +/*
> > + * 1-Wire implementation for the ds2760 chip
> > + *
> > + * Copyright (c) 2004-2005, Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
> > + *
> > + * Use consistent with the GNU GPL is permitted,
> > + * provided that this copyright notice is
> > + * preserved in its entirety in all copies and derived works.
> > + *
> > + */
> > +
> > +#include <asm/types.h>
>
> Is it really needed?
No, sure.
> > +
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/moduleparam.h>
> > +#include <linux/device.h>
> > +#include <linux/types.h>
> > +#include <linux/jiffies.h>
> > +
> > +#include "../w1.h"
> > +#include "../w1_int.h"
> > +#include "../w1_family.h"
> > +#include "w1_ds2760.h"
> > +
> > +static int w1_ds2760_io(struct device *dev, char *buf, int addr, size_t count,
> > + int io)
> > +{
> > + struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
> > +
> > + if (!dev)
> > + return 0;
> > +
> > + mutex_lock(&sl->master->mutex);
> > +
> > + if (addr > DS2760_DATA_SIZE || addr < 0) {
> > + count = 0;
> > + goto out;
> > + }
> > + if (addr + count > DS2760_DATA_SIZE)
> > + count = DS2760_DATA_SIZE - addr;
> > +
> > + if (!w1_reset_select_slave(sl)) {
> > + if (!io) {
> > + w1_write_8(sl->master, W1_DS2760_READ_DATA);
> > + w1_write_8(sl->master, addr);
> > + count = w1_read_block(sl->master, buf, count);
> > + } else {
> > + w1_write_8(sl->master, W1_DS2760_WRITE_DATA);
> > + w1_write_8(sl->master, addr);
> > + w1_write_block(sl->master, buf, count);
> > + /* XXX w1_write_block returns void, not n_written */
> > + }
> > + }
> > +
> > +out:
> > + mutex_unlock(&sl->master->mutex);
> > +
> > + return count;
> > +}
> > +
> > +int w1_ds2760_read(struct device *dev, char *buf, int addr, size_t count)
> > +{
> > + return w1_ds2760_io(dev, buf, addr, count, 0);
> > +}
> > +
> > +int w1_ds2760_write(struct device *dev, char *buf, int addr, size_t count)
> > +{
> > + return w1_ds2760_io(dev, buf, addr, count, 1);
> > +}
>
> Both are exported, who use them?
ds2760_battery driver. W1 does not have any API to "talk" to w1 slaves
in generic manner (at least I didn't found any).
So, ds2760_battery using it.
static int ds2760_battery_read_status(struct ds2760_device_info *di)
{
[...]
ret = w1_ds2760_read(di->w1_dev, di->raw + start, start, count);
if (ret != count) {
printk("call to w1_ds2760_read failed (0x%08x)\n",
(unsigned int)di->w1_dev);
return 1;
}
static void ds2760_battery_update_status(struct ds2760_device_info *di)
{
[...]
acr[0] = (di->full_active_mAh * 4) >> 8;
acr[1] = (di->full_active_mAh * 4) & 0xff;
if (w1_ds2760_write(di->w1_dev, acr,
DS2760_CURRENT_ACCUM_MSB, 2) < 2)
printk(KERN_ERR "ACR reset failed\n");
di->charge_status = BATTERY_STATUS_FULL;
[...]
> > +/* io = 0 means copy from EEPROM to SRAM, 1 means from SRAM to EEPROM */
> > +static int w1_ds2760_eeprom(struct device *dev, int addr, int io)
> > +{
> > + struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
> > + int ret = 0;
> > +
> > + mutex_lock(&sl->master->mutex);
> > +
> > + if (!w1_reset_select_slave(sl)) {
> > + if (!io)
> > + w1_write_8(sl->master, W1_DS2760_RECALL_DATA);
> > + else
> > + w1_write_8(sl->master, W1_DS2760_COPY_DATA);
> > + w1_write_8(sl->master, addr);
> > + }
> > +
> > + mutex_unlock(&sl->master->mutex);
> > +
> > + return ret;
> > +}
> > +
> > +int w1_ds2760_recall(struct device *dev, int addr)
> > +{
> > + return w1_ds2760_eeprom(dev, addr, 0);
> > +}
> > +
> > +int w1_ds2760_copy(struct device *dev, int addr)
> > +{
> > + return w1_ds2760_eeprom(dev, addr, 1);
> > +}
>
> The same.
Yeah, these two should be static, right.
> > +static ssize_t w1_ds2760_read_bin(struct kobject *kobj, char *buf, loff_t off,
> > + size_t count)
> > +{
> > + struct device *dev = container_of(kobj, struct device, kobj);
> > + return w1_ds2760_read(dev, buf, off, count);
> > +}
> > +
> > +static struct bin_attribute w1_ds2760_bin_attr = {
> > + .attr = {
> > + .name = "w1_slave",
> > + .mode = S_IRUGO,
> > + .owner = THIS_MODULE,
> > + },
> > + .size = DS2760_DATA_SIZE,
> > + .read = w1_ds2760_read_bin,
> > +};
> > +
> > +static int w1_ds2760_add_slave(struct w1_slave *sl)
> > +{
> > + return sysfs_create_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr);
> > +}
> > +
> > +static void w1_ds2760_remove_slave(struct w1_slave *sl)
> > +{
> > + sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr);
> > +}
> > +
> > +static struct w1_family_ops w1_ds2760_fops = {
> > + .add_slave = w1_ds2760_add_slave,
> > + .remove_slave = w1_ds2760_remove_slave,
> > +};
> > +
> > +static struct w1_family w1_ds2760_family = {
> > + .fid = W1_FAMILY_DS2760,
> > + .fops = &w1_ds2760_fops,
> > +};
> > +
> > +static int __init w1_ds2760_init(void)
> > +{
> > + printk("1-Wire driver for the DS2760 battery monitor chip "
> > + " - (c) 2004-2005, Szabolcs Gyurko\n");
> > + return w1_register_family(&w1_ds2760_family);
> > +}
>
> Add something like KERN_INFO into printk.
Will do.
> --
> Evgeniy Polyakov
Thanks!
--
Anton Vorontsov
email: cbou@mail.ru
backup email: ya-cbou@yandex.ru
irc://irc.freenode.org/bd2
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 5/7] [RFC] ds2760 W1 slave
2007-04-12 14:08 ` Anton Vorontsov
@ 2007-04-12 14:20 ` Evgeniy Polyakov
2007-04-12 15:47 ` Anton Vorontsov
0 siblings, 1 reply; 5+ messages in thread
From: Evgeniy Polyakov @ 2007-04-12 14:20 UTC (permalink / raw)
To: Anton Vorontsov; +Cc: linux-kernel, kernel-discuss
On Thu, Apr 12, 2007 at 06:08:07PM +0400, Anton Vorontsov (cbou@mail.ru) wrote:
> > > +int w1_ds2760_read(struct device *dev, char *buf, int addr, size_t count)
> > > +{
> > > + return w1_ds2760_io(dev, buf, addr, count, 0);
> > > +}
> > > +
> > > +int w1_ds2760_write(struct device *dev, char *buf, int addr, size_t count)
> > > +{
> > > + return w1_ds2760_io(dev, buf, addr, count, 1);
> > > +}
> >
> > Both are exported, who use them?
>
> ds2760_battery driver. W1 does not have any API to "talk" to w1 slaves
> in generic manner (at least I didn't found any).
> So, ds2760_battery using it.
It was - bus masters were accessed through generic find_bus() via
device/driver model, bus master has links to all devices found on
controlled bus.
But find_bus() was removed, so there is no such mechanism right now.
I have no objections against this driver, feel free to add my ack (when
trivialities described are resolved) or I can push w1 part myself.
--
Evgeniy Polyakov
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 5/7] [RFC] ds2760 W1 slave
2007-04-12 14:20 ` Evgeniy Polyakov
@ 2007-04-12 15:47 ` Anton Vorontsov
0 siblings, 0 replies; 5+ messages in thread
From: Anton Vorontsov @ 2007-04-12 15:47 UTC (permalink / raw)
To: Evgeniy Polyakov; +Cc: linux-kernel, kernel-discuss
On Thu, Apr 12, 2007 at 06:20:23PM +0400, Evgeniy Polyakov wrote:
> On Thu, Apr 12, 2007 at 06:08:07PM +0400, Anton Vorontsov (cbou@mail.ru) wrote:
> > > > +int w1_ds2760_read(struct device *dev, char *buf, int addr, size_t count)
> > > > +{
> > > > + return w1_ds2760_io(dev, buf, addr, count, 0);
> > > > +}
> > > > +
> > > > +int w1_ds2760_write(struct device *dev, char *buf, int addr, size_t count)
> > > > +{
> > > > + return w1_ds2760_io(dev, buf, addr, count, 1);
> > > > +}
> > >
> > > Both are exported, who use them?
> >
> > ds2760_battery driver. W1 does not have any API to "talk" to w1 slaves
> > in generic manner (at least I didn't found any).
> > So, ds2760_battery using it.
>
> It was - bus masters were accessed through generic find_bus() via
> device/driver model, bus master has links to all devices found on
> controlled bus.
> But find_bus() was removed, so there is no such mechanism right now.
>
> I have no objections against this driver, feel free to add my ack (when
> trivialities described are resolved) or I can push w1 part myself.
Cleaned up patch follows. Before acking, please take a look at "#if 0",
I don't know if it's okay for you.
> --
> Evgeniy Polyakov
Thanks,
From: Anton Vorontsov <cbou@mail.ru>
Subject: [PATCH] [RFC] ds2760 W1 slave
This is W1 slave for ds2760 chip, found inside almost every HP iPaq and
HTC PDAs/phones.
Signed-off-by: Anton Vorontsov <cbou@mail.ru>
---
drivers/w1/slaves/Kconfig | 13 +++
drivers/w1/slaves/Makefile | 1 +
drivers/w1/slaves/w1_ds2760.c | 162 +++++++++++++++++++++++++++++++++++++++++
drivers/w1/slaves/w1_ds2760.h | 50 +++++++++++++
drivers/w1/w1_family.h | 1 +
5 files changed, 227 insertions(+), 0 deletions(-)
create mode 100644 drivers/w1/slaves/w1_ds2760.c
create mode 100644 drivers/w1/slaves/w1_ds2760.h
diff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig
index 904e5ae..df95d6c 100644
--- a/drivers/w1/slaves/Kconfig
+++ b/drivers/w1/slaves/Kconfig
@@ -35,4 +35,17 @@ config W1_SLAVE_DS2433_CRC
Each block has 30 bytes of data and a two byte CRC16.
Full block writes are only allowed if the CRC is valid.
+config W1_SLAVE_DS2760
+ tristate "Dallas 2760 battery monitor chip (HP iPAQ & others)"
+ depends on W1
+ help
+ If you enable this you will have the DS2760 battery monitor
+ chip support.
+
+ The battery monitor chip is used in many batteries/devices
+ as the one who is responsible for charging/discharging/monitoring
+ Li+ batteries.
+
+ If you are unsure, say N.
+
endmenu
diff --git a/drivers/w1/slaves/Makefile b/drivers/w1/slaves/Makefile
index 725dcfd..a8eb752 100644
--- a/drivers/w1/slaves/Makefile
+++ b/drivers/w1/slaves/Makefile
@@ -5,4 +5,5 @@
obj-$(CONFIG_W1_SLAVE_THERM) += w1_therm.o
obj-$(CONFIG_W1_SLAVE_SMEM) += w1_smem.o
obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o
+obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o
diff --git a/drivers/w1/slaves/w1_ds2760.c b/drivers/w1/slaves/w1_ds2760.c
new file mode 100644
index 0000000..1bd1c6d
--- /dev/null
+++ b/drivers/w1/slaves/w1_ds2760.c
@@ -0,0 +1,162 @@
+/*
+ * 1-Wire implementation for the ds2760 chip
+ *
+ * Copyright (c) 2004-2005, Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
+ *
+ * Use consistent with the GNU GPL is permitted,
+ * provided that this copyright notice is
+ * preserved in its entirety in all copies and derived works.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/types.h>
+
+#include "../w1.h"
+#include "../w1_int.h"
+#include "../w1_family.h"
+#include "w1_ds2760.h"
+
+static int w1_ds2760_io(struct device *dev, char *buf, int addr, size_t count,
+ int io)
+{
+ struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
+
+ if (!dev)
+ return 0;
+
+ mutex_lock(&sl->master->mutex);
+
+ if (addr > DS2760_DATA_SIZE || addr < 0) {
+ count = 0;
+ goto out;
+ }
+ if (addr + count > DS2760_DATA_SIZE)
+ count = DS2760_DATA_SIZE - addr;
+
+ if (!w1_reset_select_slave(sl)) {
+ if (!io) {
+ w1_write_8(sl->master, W1_DS2760_READ_DATA);
+ w1_write_8(sl->master, addr);
+ count = w1_read_block(sl->master, buf, count);
+ } else {
+ w1_write_8(sl->master, W1_DS2760_WRITE_DATA);
+ w1_write_8(sl->master, addr);
+ w1_write_block(sl->master, buf, count);
+ /* XXX w1_write_block returns void, not n_written */
+ }
+ }
+
+out:
+ mutex_unlock(&sl->master->mutex);
+
+ return count;
+}
+
+int w1_ds2760_read(struct device *dev, char *buf, int addr, size_t count)
+{
+ return w1_ds2760_io(dev, buf, addr, count, 0);
+}
+
+int w1_ds2760_write(struct device *dev, char *buf, int addr, size_t count)
+{
+ return w1_ds2760_io(dev, buf, addr, count, 1);
+}
+
+#if 0
+/* Code below works, but unused currently, thus produces "defined but not
+ * used" warning. It stays here for reference and future needs, feel free
+ * to drop "#if 0" when you're about to use it. */
+
+/* io = 0 means copy from EEPROM to SRAM, 1 means from SRAM to EEPROM */
+static int w1_ds2760_eeprom(struct device *dev, int addr, int io)
+{
+ struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
+ int ret = 0;
+
+ mutex_lock(&sl->master->mutex);
+
+ if (!w1_reset_select_slave(sl)) {
+ if (!io)
+ w1_write_8(sl->master, W1_DS2760_RECALL_DATA);
+ else
+ w1_write_8(sl->master, W1_DS2760_COPY_DATA);
+ w1_write_8(sl->master, addr);
+ }
+
+ mutex_unlock(&sl->master->mutex);
+
+ return ret;
+}
+
+static int w1_ds2760_recall(struct device *dev, int addr)
+{
+ return w1_ds2760_eeprom(dev, addr, 0);
+}
+
+static int w1_ds2760_copy(struct device *dev, int addr)
+{
+ return w1_ds2760_eeprom(dev, addr, 1);
+}
+#endif
+
+static ssize_t w1_ds2760_read_bin(struct kobject *kobj, char *buf, loff_t off,
+ size_t count)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ return w1_ds2760_read(dev, buf, off, count);
+}
+
+static struct bin_attribute w1_ds2760_bin_attr = {
+ .attr = {
+ .name = "w1_slave",
+ .mode = S_IRUGO,
+ .owner = THIS_MODULE,
+ },
+ .size = DS2760_DATA_SIZE,
+ .read = w1_ds2760_read_bin,
+};
+
+static int w1_ds2760_add_slave(struct w1_slave *sl)
+{
+ return sysfs_create_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr);
+}
+
+static void w1_ds2760_remove_slave(struct w1_slave *sl)
+{
+ sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr);
+}
+
+static struct w1_family_ops w1_ds2760_fops = {
+ .add_slave = w1_ds2760_add_slave,
+ .remove_slave = w1_ds2760_remove_slave,
+};
+
+static struct w1_family w1_ds2760_family = {
+ .fid = W1_FAMILY_DS2760,
+ .fops = &w1_ds2760_fops,
+};
+
+static int __init w1_ds2760_init(void)
+{
+ printk(KERN_INFO "1-Wire driver for the DS2760 battery monitor "
+ " chip - (c) 2004-2005, Szabolcs Gyurko\n");
+ return w1_register_family(&w1_ds2760_family);
+}
+
+static void __exit w1_ds2760_exit(void)
+{
+ w1_unregister_family(&w1_ds2760_family);
+}
+
+EXPORT_SYMBOL(w1_ds2760_read);
+EXPORT_SYMBOL(w1_ds2760_write);
+
+module_init(w1_ds2760_init);
+module_exit(w1_ds2760_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>");
+MODULE_DESCRIPTION("1-wire Driver Dallas 2760 battery monitor chip");
diff --git a/drivers/w1/slaves/w1_ds2760.h b/drivers/w1/slaves/w1_ds2760.h
new file mode 100644
index 0000000..0ee92b9
--- /dev/null
+++ b/drivers/w1/slaves/w1_ds2760.h
@@ -0,0 +1,50 @@
+/*
+ * 1-Wire implementation for the ds2760 chip
+ *
+ * Copyright (c) 2004-2005, Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
+ *
+ * Use consistent with the GNU GPL is permitted,
+ * provided that this copyright notice is
+ * preserved in its entirety in all copies and derived works.
+ *
+ */
+
+#ifndef __w1_ds2760_h__
+#define __w1_ds2760_h__
+
+/* Known commands to the DS2760 chip */
+#define W1_DS2760_SWAP 0xAA
+#define W1_DS2760_READ_DATA 0x69
+#define W1_DS2760_WRITE_DATA 0x6C
+#define W1_DS2760_COPY_DATA 0x48
+#define W1_DS2760_RECALL_DATA 0xB8
+#define W1_DS2760_LOCK 0x6A
+
+/* Number of valid register addresses */
+#define DS2760_DATA_SIZE 0x40
+
+#define DS2760_PROTECTION_REG 0x00
+#define DS2760_STATUS_REG 0x01
+#define DS2760_EEPROM_REG 0x07
+#define DS2760_SPECIAL_FEATURE_REG 0x08
+#define DS2760_VOLTAGE_MSB 0x0c
+#define DS2760_VOLTAGE_LSB 0x0d
+#define DS2760_CURRENT_MSB 0x0e
+#define DS2760_CURRENT_LSB 0x0f
+#define DS2760_CURRENT_ACCUM_MSB 0x10
+#define DS2760_CURRENT_ACCUM_LSB 0x11
+#define DS2760_TEMP_MSB 0x18
+#define DS2760_TEMP_LSB 0x19
+#define DS2760_EEPROM_BLOCK0 0x20
+#define DS2760_ACTIVE_FULL 0x20
+#define DS2760_EEPROM_BLOCK1 0x30
+#define DS2760_RATED_CAPACITY 0x32
+#define DS2760_CURRENT_OFFSET_BIAS 0x33
+#define DS2760_ACTIVE_EMPTY 0x3b
+
+extern int w1_ds2760_read(struct device *dev, char *buf, int addr,
+ size_t count);
+extern int w1_ds2760_write(struct device *dev, char *buf, int addr,
+ size_t count);
+
+#endif /* !__w1_ds2760_h__ */
diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h
index 1e2ac40..ef1e1da 100644
--- a/drivers/w1/w1_family.h
+++ b/drivers/w1/w1_family.h
@@ -33,6 +33,7 @@
#define W1_THERM_DS1822 0x22
#define W1_EEPROM_DS2433 0x23
#define W1_THERM_DS18B20 0x28
+#define W1_FAMILY_DS2760 0x30
#define MAXNAMELEN 32
--
1.5.0.5-dirty
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2007-04-12 15:50 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-04-11 23:25 [PATCH 5/7] [RFC] ds2760 W1 slave Anton Vorontsov
2007-04-12 7:08 ` Evgeniy Polyakov
2007-04-12 14:08 ` Anton Vorontsov
2007-04-12 14:20 ` Evgeniy Polyakov
2007-04-12 15:47 ` Anton Vorontsov
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.