This adds dt support to the at25 eeprom driver.
Signed-off-by: Alexandre Pereira da Silva <[email protected]>
Tested-by: Roland Stigge <[email protected]>
---
Documentation/devicetree/bindings/misc/at25.txt | 21 ++++++++
drivers/misc/eeprom/at25.c | 61 +++++++++++++++++------
2 files changed, 66 insertions(+), 16 deletions(-)
create mode 100644 Documentation/devicetree/bindings/misc/at25.txt
diff --git a/Documentation/devicetree/bindings/misc/at25.txt b/Documentation/devicetree/bindings/misc/at25.txt
new file mode 100644
index 0000000..ab3c327
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/at25.txt
@@ -0,0 +1,21 @@
+Atmel AT25 eeprom
+
+Required properties:
+- compatible : "atmel,at25".
+- reg : chip select number
+- spi-max-frequency : max spi frequency to use
+
+- at25,byte-len : total eeprom size in bytes
+- at25,addr-mode : addr-mode flags, as defined in include/linux/spi/eeprom.h
+- at25,page-size : size of the eeprom page
+
+Examples:
+at25@0 {
+ compatible = "atmel,at25";
+ reg = <0>
+ spi-max-frequency = <5000000>;
+
+ at25,byte-len = <0x8000>;
+ at25,addr-mode = <2>;
+ at25,page-size = <64>;
+};
diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c
index 0842c29..25003d6 100644
--- a/drivers/misc/eeprom/at25.c
+++ b/drivers/misc/eeprom/at25.c
@@ -19,7 +19,7 @@
#include <linux/spi/spi.h>
#include <linux/spi/eeprom.h>
-
+#include <linux/of.h>
/*
* NOTE: this is an *EEPROM* driver. The vagaries of product naming
@@ -305,25 +305,54 @@ static ssize_t at25_mem_write(struct memory_accessor *mem, const char *buf,
static int at25_probe(struct spi_device *spi)
{
struct at25_data *at25 = NULL;
- const struct spi_eeprom *chip;
+ struct spi_eeprom chip;
+ struct device_node *np = spi->dev.of_node;
int err;
int sr;
int addrlen;
/* Chip description */
- chip = spi->dev.platform_data;
- if (!chip) {
- dev_dbg(&spi->dev, "no chip description\n");
- err = -ENODEV;
- goto fail;
- }
+ if (!spi->dev.platform_data) {
+ if (np) {
+ u32 val;
+
+ memset(&chip, 0, sizeof(chip));
+ strncpy(chip.name, np->name, 10);
+
+ err = of_property_read_u32(np, "at25,byte-len", &val);
+ if (err) {
+ dev_dbg(&spi->dev, "invalid chip dt description\n");
+ goto fail;
+ }
+ chip.byte_len = val;
+
+ err = of_property_read_u32(np, "at25,addr-mode", &val);
+ if (err) {
+ dev_dbg(&spi->dev, "invalid chip dt description\n");
+ goto fail;
+ }
+ chip.flags = (u16)val;
+
+ err = of_property_read_u32(np, "at25,page-size", &val);
+ if (err) {
+ dev_dbg(&spi->dev, "invalid chip dt description\n");
+ goto fail;
+ }
+ chip.page_size = (u16)val;
+ } else {
+ dev_dbg(&spi->dev, "no chip description\n");
+ err = -ENODEV;
+ goto fail;
+ }
+ } else
+ chip = *(struct spi_eeprom *)spi->dev.platform_data;
/* For now we only support 8/16/24 bit addressing */
- if (chip->flags & EE_ADDR1)
+ if (chip.flags & EE_ADDR1)
addrlen = 1;
- else if (chip->flags & EE_ADDR2)
+ else if (chip.flags & EE_ADDR2)
addrlen = 2;
- else if (chip->flags & EE_ADDR3)
+ else if (chip.flags & EE_ADDR3)
addrlen = 3;
else {
dev_dbg(&spi->dev, "unsupported address type\n");
@@ -348,7 +377,7 @@ static int at25_probe(struct spi_device *spi)
}
mutex_init(&at25->lock);
- at25->chip = *chip;
+ at25->chip = chip;
at25->spi = spi_dev_get(spi);
dev_set_drvdata(&spi->dev, at25);
at25->addrlen = addrlen;
@@ -369,7 +398,7 @@ static int at25_probe(struct spi_device *spi)
at25->mem.read = at25_mem_read;
at25->bin.size = at25->chip.byte_len;
- if (!(chip->flags & EE_READONLY)) {
+ if (!(chip.flags & EE_READONLY)) {
at25->bin.write = at25_bin_write;
at25->bin.attr.mode |= S_IWUSR;
at25->mem.write = at25_mem_write;
@@ -379,8 +408,8 @@ static int at25_probe(struct spi_device *spi)
if (err)
goto fail;
- if (chip->setup)
- chip->setup(&at25->mem, chip->context);
+ if (chip.setup)
+ chip.setup(&at25->mem, chip.context);
dev_info(&spi->dev, "%Zd %s %s eeprom%s, pagesize %u\n",
(at25->bin.size < 1024)
@@ -388,7 +417,7 @@ static int at25_probe(struct spi_device *spi)
: (at25->bin.size / 1024),
(at25->bin.size < 1024) ? "Byte" : "KByte",
at25->chip.name,
- (chip->flags & EE_READONLY) ? " (readonly)" : "",
+ (chip.flags & EE_READONLY) ? " (readonly)" : "",
at25->chip.page_size);
return 0;
fail:
--
1.7.10
Hi,
2012/6/14 Alexandre Pereira da Silva <[email protected]>:
> @@ -305,25 +305,54 @@ static ssize_t at25_mem_write(struct memory_accessor *mem, const char *buf,
> + ? ? ? if (!spi->dev.platform_data) {
> + ? ? ? ? ? ? ? if (np) {
> + ? ? ? ? ? ? ? ? ? ? ? u32 val;
> +
> + ? ? ? ? ? ? ? ? ? ? ? memset(&chip, 0, sizeof(chip));
> + ? ? ? ? ? ? ? ? ? ? ? strncpy(chip.name, np->name, 10);
> +
> + ? ? ? ? ? ? ? ? ? ? ? err = of_property_read_u32(np, "at25,byte-len", &val);
> + ? ? ? ? ? ? ? ? ? ? ? if (err) {
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dev_dbg(&spi->dev, "invalid chip dt description\n");
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? goto fail;
> + ? ? ? ? ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? ? ? ? ? chip.byte_len = val;
> +
> + ? ? ? ? ? ? ? ? ? ? ? err = of_property_read_u32(np, "at25,addr-mode", &val);
> + ? ? ? ? ? ? ? ? ? ? ? if (err) {
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dev_dbg(&spi->dev, "invalid chip dt description\n");
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? goto fail;
> + ? ? ? ? ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? ? ? ? ? chip.flags = (u16)val;
> +
> + ? ? ? ? ? ? ? ? ? ? ? err = of_property_read_u32(np, "at25,page-size", &val);
> + ? ? ? ? ? ? ? ? ? ? ? if (err) {
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dev_dbg(&spi->dev, "invalid chip dt description\n");
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? goto fail;
> + ? ? ? ? ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? ? ? ? ? chip.page_size = (u16)val;
> + ? ? ? ? ? ? ? } else {
> + ? ? ? ? ? ? ? ? ? ? ? dev_dbg(&spi->dev, "no chip description\n");
> + ? ? ? ? ? ? ? ? ? ? ? err = -ENODEV;
> + ? ? ? ? ? ? ? ? ? ? ? goto fail;
> + ? ? ? ? ? ? ? }
> + ? ? ? } else
> + ? ? ? ? ? ? ? chip = *(struct spi_eeprom *)spi->dev.platform_data;
One small remark:
In case of platform_data, the "if (!chip)" check has been removed and
is now only handled in the device tree initialization.
Maybe add this check to the platform initialization as well:
} else {
if (!spi->dev.platform_data) {
dev_dbg(&spi->dev, "no chip description\n");
err = -ENODEV;
goto fail;
}
chip = *(struct spi_eeprom *)spi->dev.platform_data;
}
Furthermore looks good to me...
(Note: I am not familiar with device trees, so I cannot judge that
part of this patch)
Regards,
Ivo Sieben
On Thu, Jun 21, 2012 at 6:49 AM, Ivo Sieben <[email protected]> wrote:
> One small remark:
> In case of platform_data, the "if (!chip)" check has been removed and
> is now only handled in the device tree initialization.
> Maybe add this check to the platform initialization as well:
>
> } else {
> ? ? ? ?if (!spi->dev.platform_data) {
> ? ? ? ? ? ? ? ?dev_dbg(&spi->dev, "no chip description\n");
> ? ? ? ? ? ? ? ?err = -ENODEV;
> ? ? ? ? ? ? ? ?goto fail;
> ? ? ? ?}
> ? ? ? ?chip = ?*(struct spi_eeprom *)spi->dev.platform_data;
> }
Thanks for finding that out. I will fix that case.
This patch was already merged to gregh/char-misc:
http://git.kernel.org/?p=linux/kernel/git/gregkh/char-misc.git;a=shortlog;h=refs/heads/char-misc-next
I will implement a patch to fix this against the original one.
On Thu, Jun 21, 2012 at 8:10 AM, Alexandre Pereira da Silva
<[email protected]> wrote:
> On Thu, Jun 21, 2012 at 6:49 AM, Ivo Sieben <[email protected]> wrote:
>> One small remark:
>> In case of platform_data, the "if (!chip)" check has been removed and
>> is now only handled in the device tree initialization.
>> Maybe add this check to the platform initialization as well:
>>
>> } else {
>> ? ? ? ?if (!spi->dev.platform_data) {
>> ? ? ? ? ? ? ? ?dev_dbg(&spi->dev, "no chip description\n");
>> ? ? ? ? ? ? ? ?err = -ENODEV;
>> ? ? ? ? ? ? ? ?goto fail;
>> ? ? ? ?}
>> ? ? ? ?chip = ?*(struct spi_eeprom *)spi->dev.platform_data;
>> }
Please ignore my last email. Not enough coffee.
I'm sorry. The code looks right to me.
- chip = spi->dev.platform_data;
- if (!chip) {
- dev_dbg(&spi->dev, "no chip description\n");
- err = -ENODEV;
- goto fail;
- }
+ if (!spi->dev.platform_data) {
+ if (np) {
/* No platform data and DT node present,
DT handling */
+ } else {
/* No DT and No platform description,
handle error */
+ dev_dbg(&spi->dev, "no chip description\n");
+ err = -ENODEV;
+ goto fail;
+ }
+ } else
/* At this point chip is guaranteed to have valid data */
+ chip = *(struct spi_eeprom *)spi->dev.platform_data;
Hi,
2012/6/21 Alexandre Pereira da Silva <[email protected]>:
>
> Please ignore my last email. Not enough coffee.
>
> I'm sorry. The code looks right to me.
>
Yup, sorry... you're right
not enough coffee for me also.
Regards,
Ivo