Merged in david_alessio/nuttx/feature/devc-at24cs-uuid (pull request #1013)

register a character driver for UUID of AT24CSxx chips

Allows the UUID to read as a file or displayed from an nsh prompt
with:  hexdump /dev/eeprom.uuid

Approved-by: Alan Carvalho de Assis <acassis@gmail.com>
Approved-by: Gregory Nutt <gnutt@nuttx.org>
This commit is contained in:
David Alessio
2019-08-21 13:41:16 +00:00
committed by Gregory Nutt
parent c6355f58d6
commit 885bf254e9
2 changed files with 130 additions and 1 deletions
+9
View File
@@ -41,6 +41,15 @@ config EE24XX_FREQUENCY
default 100000
depends on I2C_EE_24XX
config AT24CS_UUID
bool "Device driver support for Atmel AT24CSxx UUID"
default n
depends on I2C_EE_24XX
---help---
The Atmel AT24CSxx family have a 128-bit UUID which appears as
another I2C slave whose address is offset from the EEPROM by +8.
This option registers a char device driver with the ".uuid" suffix.
endif # I2C_EE_24XX
endif # EEPROM
+121 -1
View File
@@ -92,6 +92,7 @@
#include <sys/types.h>
#include <debug.h>
#include <errno.h>
#include <string.h>
#include <nuttx/fs/fs.h>
#include <nuttx/kmalloc.h>
@@ -161,6 +162,11 @@ static ssize_t ee24xx_write(FAR struct file *filep, FAR const char *buffer,
static int ee24xx_ioctl(FAR struct file *filep, int cmd,
unsigned long arg);
#ifdef CONFIG_AT24CS_UUID
static ssize_t at24cs_read_uuid(FAR struct file *filep, FAR char *buffer,
size_t buflen);
#endif
/****************************************************************************
* Private Data
****************************************************************************/
@@ -210,6 +216,19 @@ static const struct file_operations ee24xx_fops =
NULL /* poll */
};
#ifdef CONFIG_AT24CS_UUID
static const struct file_operations at24cs_uuid_fops =
{
ee24xx_open, /* piggyback on the ee24xx_open */
ee24xx_close, /* piggyback on the ee24xx_close */
at24cs_read_uuid, /* read */
NULL, /* write */
NULL, /* seek */
NULL, /* ioctl */
NULL /* poll */
};
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
@@ -540,6 +559,79 @@ done:
return ret;
}
#ifdef CONFIG_AT24CS_UUID
/****************************************************************************
* Name: at24cs_read_uuid
****************************************************************************/
#define UUID_SIZE 16
static ssize_t at24cs_read_uuid(FAR struct file *filep, FAR char *buffer,
size_t len)
{
FAR struct ee24xx_dev_s *eedev;
FAR struct inode *inode = filep->f_inode;
struct i2c_msg_s msgs[2];
uint8_t regindx;
int ret;
DEBUGASSERT(inode && inode->i_private);
eedev = (FAR struct ee24xx_dev_s *)inode->i_private;
ee24xx_semtake(eedev);
/* trim len if read would go beyond end of device */
if ((filep->f_pos + len) > UUID_SIZE)
{
len = UUID_SIZE - filep->f_pos;
}
if (len == 0)
{
/* We are at end of file */
ret = 0;
goto done;
}
/* Write data address */
finfo("READ %d bytes at pos %d\n", len, filep->f_pos);
regindx = 0x80; /* reg index of UUID[0] */
msgs[0].frequency = eedev->freq;
msgs[0].addr = eedev->addr + 8; /* slave addr of UUID */
msgs[0].flags = 0;
msgs[0].buffer = &regindx;
msgs[0].length = 1;
/* Read data */
msgs[1].frequency = msgs[0].frequency;
msgs[1].addr = msgs[0].addr;
msgs[1].flags = I2C_M_READ;
msgs[1].buffer = (uint8_t *)buffer;
msgs[1].length = len;
ret = I2C_TRANSFER(eedev->i2c, msgs, 2);
if (ret < 0)
{
goto done;
}
ret = len;
/* Update the file position */
filep->f_pos += len;
done:
ee24xx_semgive(eedev);
return ret;
}
#endif
/****************************************************************************
* Name: ee24xx_write
****************************************************************************/
@@ -705,6 +797,10 @@ int ee24xx_initialize(FAR struct i2c_master_s *bus, uint8_t devaddr,
FAR char *devname, int devtype, int readonly)
{
FAR struct ee24xx_dev_s *eedev;
#ifdef CONFIG_AT24CS_UUID
FAR char *uuidname;
int ret;
#endif
/* Check device type early */
@@ -759,7 +855,7 @@ int ee24xx_initialize(FAR struct i2c_master_s *bus, uint8_t devaddr,
ferr("Device 24xx1025 is not supported for the moment, TODO.\n");
eedev->haddrshift = 2;
free(eedev);
kmm_free(eedev);
return -ENODEV;
}
}
@@ -768,5 +864,29 @@ int ee24xx_initialize(FAR struct i2c_master_s *bus, uint8_t devaddr,
devname, eedev->size, eedev->pgsize, eedev->addrlen,
eedev->readonly ? "readonly" : "");
#ifdef CONFIG_AT24CS_UUID
uuidname = kmm_zalloc(strlen(devname) + 8);
if (!uuidname)
{
return -ENOMEM;
}
/* register the UUID I2C slave with the same name as the parent
* EEPROM chip, but with the ".uuid" suffix
*/
strcpy(uuidname, devname);
strcat(uuidname, ".uuid");
ret = register_driver(uuidname, &at24cs_uuid_fops, 0444, eedev);
kmm_free(uuidname);
if (OK != ret)
{
ferr("register uuid failed, ret = %d\n", ret);
return ret;
}
#endif
return register_driver(devname, &ee24xx_fops, 0666, eedev);
}