Signed-off-by: Asen Dimov <di...@ronetix.at>
---
 drivers/misc/Makefile |    1 +
 drivers/misc/ds2401.c |  265 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/ds2401.h      |   36 +++++++
 3 files changed, 302 insertions(+), 0 deletions(-)
 create mode 100644 drivers/misc/ds2401.c
 create mode 100644 include/ds2401.h

diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 96aa331..4355b6e 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -32,6 +32,7 @@ COBJS-$(CONFIG_NS87308) += ns87308.o
 COBJS-$(CONFIG_STATUS_LED) += status_led.o
 COBJS-$(CONFIG_TWL4030_LED) += twl4030_led.o
 COBJS-$(CONFIG_FSL_PMIC) += fsl_pmic.o
+COBJS-$(CONFIG_DS2401) += ds2401.o
 
 COBJS  := $(COBJS-y)
 SRCS   := $(COBJS:.o=.c)
diff --git a/drivers/misc/ds2401.c b/drivers/misc/ds2401.c
new file mode 100644
index 0000000..4298d8a
--- /dev/null
+++ b/drivers/misc/ds2401.c
@@ -0,0 +1,265 @@
+/*
+ * Copyright 2009, 2010
+ * Ilko Iliev <il...@ronetix.at>
+ * Ronetix Development Tools GmbH <www.ronetix.at>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * Version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Driver for 1-wire, DS2401, a Silicon Serial Number chip
+ *
+ * Driver usage:
+ *
+ *     To build the driver add in a board config file:
+ *             #define CONFIG_DS2401 1
+ *
+ *     In the board specific file define the get and set functions
+ *     to read and write one bit from/to PIO.
+ *     
+ *     If you want to set a specific first three bytes of the MAC address
+ *     define CONFIG_MAC_OUI.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <ds2401.h>
+
+#ifndef CONFIG_MAC_OUI
+#define CONFIG_MAC_OUI "02:00:00" /* Organizationally Unique Identifier*/
+#endif
+
+static DS2401_FUNCS *DS2401_Funcs = NULL;
+
+/*
+ * Generate a 1-wire reset, return 1 if no presence detect was found,
+ * return 0 otherwise.
+ */
+static int ds2401_reset(void)
+{
+       int result;
+
+       DS2401_Funcs->set(0);
+       udelay(480);
+       DS2401_Funcs->set(1);
+       udelay(70);
+
+       result = DS2401_Funcs->get();
+
+       udelay(410);
+       return result;
+}
+
+/*
+ * Send 1 a 1-wire write bit.
+ * Provide 10us recovery time.
+ */
+static void ds2401_write_bit(int bit)
+{
+       if (bit) {
+               /*
+                * write '1' bit
+                */
+               DS2401_Funcs->set(0);
+               udelay(6);
+               DS2401_Funcs->set(1);
+               udelay(64);
+       } else {
+               /*
+                * write '0' bit
+                */
+               DS2401_Funcs->set(0);
+               udelay(60);
+               DS2401_Funcs->set(1);
+               udelay(10);
+       }
+}
+
+/*
+ * Read a bit from the 1-wire bus and return it.
+ * Provide 10us recovery time.
+ */
+static int ds2401_read_bit(void)
+{
+       int result;
+
+       DS2401_Funcs->set(0);
+
+#ifdef __OPTIMIZE__
+       udelay(1);
+#endif
+
+       DS2401_Funcs->set(1);
+       udelay(9);
+
+       result = DS2401_Funcs->get();
+       udelay(55);
+
+       return result;
+}
+
+static void ds2401_write_byte(int data)
+{
+       int loop;
+
+       for (loop = 0; loop < 8; loop++) {
+               ds2401_write_bit(data & 0x01);
+               data >>= 1;
+       }
+}
+
+static int ds2401_read_byte(void)
+{
+       int loop, result = 0;
+
+       for (loop = 0; loop < 8; loop++) {
+               result >>= 1;
+               if (ds2401_read_bit())
+                       result |= 0x80;
+       }
+
+       return result;
+}
+
+static unsigned char ds2401_crc8_table[] = {
+       0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
+       157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
+       35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
+       190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
+       70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
+       219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
+       101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
+       248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
+       140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 
205,
+       17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 
80,
+       175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 
238,
+       50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 
115,
+       202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
+       87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
+       233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 
168,
+       116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53
+};
+
+static unsigned char ds2401_calc_crc8(unsigned char * data, int len)
+{
+       unsigned char crc = 0;
+
+       while (len--)
+               crc = ds2401_crc8_table[crc ^ *data++];
+
+       return crc;
+}
+
+void ds2401_init(DS2401_FUNCS *funcs)
+{
+       DS2401_Funcs = funcs;
+}
+
+/*
+ * Read the serial number from the 1-wire bus and return it.
+ * Returns 0 if successful.
+ * Returns non-zero if not successful.
+ */
+int ds2401_get_number( unsigned char id[6] )
+{
+       int ii, result;
+       unsigned char crc;
+       unsigned char buf[8];
+
+       result = ds2401_reset();
+       if (result != 0)
+               return 1;
+
+       ds2401_write_byte(DS2401_CMD_READ_ROM); /* send read rom command */
+
+       /*
+        * read 8 bytes:
+        * buf[0]       - family code (0x01)
+        * buf[1..6]    - serial number
+        * buf[7]       - CRC
+        */
+       for (ii = 0; ii < 8; ii++)
+               buf[ii] = ds2401_read_byte();
+
+       /*
+        * calculate the 8-bit Dallas CRC
+        */
+       crc = ds2401_calc_crc8( buf, 7 );
+
+       if ( crc != buf[7] )
+               return 1;
+
+       for (ii = 0; ii < 6; ii++)
+               id[ii] = buf[ii + 1];
+
+       return 0;
+}
+
+int do_ds2401(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+       int stat;
+       unsigned char ds2401_id[6];
+       char str[32];
+
+       if (DS2401_Funcs == NULL) {
+               puts("Board specific functions for 1-wire not specified!\n");
+               return 0;
+       }
+
+       stat = ds2401_get_number( ds2401_id );
+
+       if (stat){
+               puts("No 1-wire device detected!\n");
+               return 0;
+       }
+
+       if (strcmp(argv[1], "ethaddr") == 0){
+               sprintf(str, "%s:%X:%X:%X",
+                       CONFIG_MAC_OUI,
+                       (int)ds2401_id[2],
+                       (int)ds2401_id[1],
+                       (int)ds2401_id[0]);
+
+               printf("Setting environment variable 'ethaddr' to %s\n", str);
+               setenv("ethaddr", str);
+       } else {
+               sprintf(str, "0x%X%X%X%X%X%X",
+                       (int)ds2401_id[5],
+                       (int)ds2401_id[4],
+                       (int)ds2401_id[3],
+                       (int)ds2401_id[2],
+                       (int)ds2401_id[1],
+                       (int)ds2401_id[0]);
+
+               if (argc == 2 ) {
+                       printf("Setting environment variable '%s' to %s\n",
+                               argv[1], str);
+                       setenv(argv[1], str);
+               } else {
+                       printf("Serial number is %s\n", str);
+               }
+       }
+
+       return 0;
+}
+
+U_BOOT_CMD(
+       onewire, 2, 1, do_ds2401,
+       "Read 1-write ID and set an U-Boot variable or\n"
+       "the last three bytes of 'ethaddr'",
+       "[variable] - to set a specific variable with DS2401 serial number\n"
+       "onewire ethaddr    - to set the last three bytes of MAC address\n"
+       "onewire            - with no parameter to display serial number"
+);
diff --git a/include/ds2401.h b/include/ds2401.h
new file mode 100644
index 0000000..472e334
--- /dev/null
+++ b/include/ds2401.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2009
+ * Ilko Iliev <il...@ronetix.at>
+ * Ronetix Development Tools GmbH <www.ronetix.at>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * Version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __DS2401_H_
+#define __DS2401_H_
+
+#define DS2401_CMD_READ_ROM 0x33
+
+typedef struct
+{
+       void (*set)(int value );
+       int (*get)(void);
+} DS2401_FUNCS;
+
+extern void ds2401_init(DS2401_FUNCS *funcs);
+extern int ds2401_get_number( unsigned char id[6] );
+
+#endif /* __DS2401_H_ */
+
-- 
1.5.5.6

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to