Skip to contentSkip to conversation

rtc-ds1307 : add sysfs support for trickle charger

PATCH New frederic RODO 1 participant 1 message Jan 16, 2008 Real time clock (RTC)

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 rtc-ds1307 : add sysfs support for trickle charger

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 (fredo@srv-devhard) (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)
drivers/rtc/rtc-ds1307.c +82 -0
index 3a86898..4564238 100644
@@ -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
-------------------------------------------------------------------------