this patch add two callbacks (show and store) to support the trickle charger for ds_1339 and ds_1340 (it can also be used for the ds1388).

I'm not sure if it'is the right way for adding this support. Can someone explain me a better way?

It was test on a custom board with a ds_1340. The ds_1339 support was not tested.

If you have any comments, please CC me


log from test

Linux version 2.6.24-rc7 ([EMAIL PROTECTED]) (gcc version 3.4.6) #14 Wed Jan 16 15:40:55 CET 2008
..........
i2c /dev entries driver
rtc-ds1307 0-0068: rtc core: registered ds1340 as rtc0
rtc-ds1307 0-0068: trickle charger
i2c-gpio i2c-gpio: using pins 55 (SDA) and 56 (SCL)
....
# cd /sys/class/rtc/rtc0/device/
# cat trickle
0xaa (trickle charger enabled)
# echo 0 > trickle
# cat trickle
0x00 (trickle charger disabled)


Signed-off-by: Frederic RODO <[EMAIL PROTECTED]>

diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 3a86898..4564238 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -77,6 +77,7 @@ enum ds_type {
 #      define DS1340_BIT_FT            0x40
 #      define DS1340_BIT_CALIB_SIGN    0x20
 #      define DS1340_M_CALIBRATION     0x1f
+#define DS1340_REG_TRICKLE     0x08
 #define DS1340_REG_FLAG                0x09
 #      define DS1340_BIT_OSF           0x80
 #define DS1337_REG_STATUS      0x0f
@@ -90,6 +91,7 @@ enum ds_type {
 struct ds1307 {
        u8                      reg_addr;
        bool                    has_nvram;
+       bool                    has_trickle;
        u8                      regs[8];
        enum ds_type            type;
        struct i2c_msg          msg[2];
@@ -102,6 +104,7 @@ struct chip_desc {
        char                    name[9];
        unsigned                nvram56:1;
        unsigned                alarm:1;
+       unsigned                trickle:1;
        enum ds_type            type;
 };

@@ -121,9 +124,11 @@ static const struct chip_desc chips[] = { {
        .name           = "ds1339",
        .type           = ds_1339,
        .alarm          = 1,
+       .trickle        = 1,
 }, {
        .name           = "ds1340",
        .type           = ds_1340,
+       .trickle        = 1,
 }, {
        .name           = "m41t00",
        .type           = m41t00,
@@ -322,6 +327,72 @@ static struct bin_attribute nvram = {
        .size   = NVRAM_SIZE,
 };

+static ssize_t ds1307_sysfs_show_trickle(struct device *dev,
+                                      struct device_attribute *attr,
+                                      char *buf)
+{
+       struct ds1307           *ds1307 = dev_get_drvdata(dev);
+       struct i2c_client       *client = to_i2c_client(dev);
+       int trickle;
+
+       switch (ds1307->type) {
+       case ds_1339:
+               trickle = i2c_smbus_read_byte_data(client, DS1339_REG_TRICKLE);
+               break;
+       case ds_1340:
+               trickle = i2c_smbus_read_byte_data(client, DS1340_REG_TRICKLE);
+               break;
+       default: return -EIO;
+       }
+
+       if (trickle < 0)
+               return trickle;
+
+       return sprintf(buf, "0x%02x (trickle charger %s)\n", (u8) trickle,
+                                            (((trickle & 0xf0) != 0xa0) ||
+                                             ((trickle & 0x0c) == 0x0c) ||
+                                             ((trickle & 0x0c) == 0) ||
+                                             ((trickle & 0x03) == 0))
+                                             ? "disabled" : "enabled");
+}
+
+static ssize_t ds1307_sysfs_store_trickle(struct device *dev,
+                                      struct device_attribute *attr,
+                                      const char *buf, size_t count)
+{
+       struct ds1307           *ds1307 = dev_get_drvdata(dev);
+       struct i2c_client       *client = to_i2c_client(dev);
+       int err;
+       int trickle = -1;
+
+       if (buf[0] == '0' && (buf[1] == 'x' || buf[1] == 'X')) {
+               if (sscanf(buf, "%x", &trickle) != 1)
+                       return -EINVAL;
+       } else {
+               if (sscanf(buf, "%d", &trickle) != 1)
+                       return -EINVAL;
+       }
+
+       if (trickle < 0 || trickle > 0xff)
+               return -EINVAL;
+
+       switch (ds1307->type) {
+       case ds_1339:
+               err = i2c_smbus_write_byte_data(client, DS1339_REG_TRICKLE,
+                                               trickle);
+               break;
+       case ds_1340:
+               err = i2c_smbus_write_byte_data(client, DS1340_REG_TRICKLE,
+                                               trickle);
+               break;
+       default: return -EIO;
+       }
+
+       return (err < 0) ? -EIO : 1;
+}
+static DEVICE_ATTR(trickle, S_IRUGO | S_IWUSR, ds1307_sysfs_show_trickle,
+                  ds1307_sysfs_store_trickle);
+
 /*----------------------------------------------------------------------*/

 static struct i2c_driver ds1307_driver;
@@ -526,6 +597,14 @@ read_rtc:
                }
        }

+       if (chip->trickle) {
+               err = device_create_file(&client->dev, &dev_attr_trickle);
+               if (err == 0) {
+                       ds1307->has_trickle = true;
+                       dev_info(&client->dev, "trickle charger\n");
+               }
+       }
+
        return 0;

 exit_bad:
@@ -548,6 +627,9 @@ static int __devexit ds1307_remove(struct i2c_client *client)
        if (ds1307->has_nvram)
                sysfs_remove_bin_file(&client->dev.kobj, &nvram);

+       if (ds1307->has_trickle)
+               device_remove_file(&client->dev, &dev_attr_trickle);
+
        rtc_device_unregister(ds1307->rtc);
        kfree(ds1307);
        return 0;


-------------------------------------------------------------------------
Les informations précédentes peuvent être confidentielles ou privilégiées.
Si vous n'êtes pas le destinataire prévu de ce mail, veuillez en notifier l'expéditeur en répondant à ce message puis supprimez-en toute trace de vos systèmes.

TIL Technologies
Parc du Golf, Bat 43
350 rue J.R Guilibert Gautier de la Lauzière 13856 AIX EN PROVENCE
Tel. : +33 4 42 37 11 77
-------------------------------------------------------------------------


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to