linux/drivers/misc/eeprom/ee1004.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * ee1004 - driver for DDR4 SPD EEPROMs
   4 *
   5 * Copyright (C) 2017-2019 Jean Delvare
   6 *
   7 * Based on the at24 driver:
   8 * Copyright (C) 2005-2007 David Brownell
   9 * Copyright (C) 2008 Wolfram Sang, Pengutronix
  10 */
  11
  12#include <linux/i2c.h>
  13#include <linux/init.h>
  14#include <linux/kernel.h>
  15#include <linux/mod_devicetable.h>
  16#include <linux/module.h>
  17#include <linux/mutex.h>
  18
  19/*
  20 * DDR4 memory modules use special EEPROMs following the Jedec EE1004
  21 * specification. These are 512-byte EEPROMs using a single I2C address
  22 * in the 0x50-0x57 range for data. One of two 256-byte page is selected
  23 * by writing a command to I2C address 0x36 or 0x37 on the same I2C bus.
  24 *
  25 * Therefore we need to request these 2 additional addresses, and serialize
  26 * access to all such EEPROMs with a single mutex.
  27 *
  28 * We assume it is safe to read up to 32 bytes at once from these EEPROMs.
  29 * We use SMBus access even if I2C is available, these EEPROMs are small
  30 * enough, and reading from them infrequent enough, that we favor simplicity
  31 * over performance.
  32 */
  33
  34#define EE1004_ADDR_SET_PAGE            0x36
  35#define EE1004_NUM_PAGES                2
  36#define EE1004_PAGE_SIZE                256
  37#define EE1004_PAGE_SHIFT               8
  38#define EE1004_EEPROM_SIZE              (EE1004_PAGE_SIZE * EE1004_NUM_PAGES)
  39
  40/*
  41 * Mutex protects ee1004_set_page and ee1004_dev_count, and must be held
  42 * from page selection to end of read.
  43 */
  44static DEFINE_MUTEX(ee1004_bus_lock);
  45static struct i2c_client *ee1004_set_page[EE1004_NUM_PAGES];
  46static unsigned int ee1004_dev_count;
  47static int ee1004_current_page;
  48
  49static const struct i2c_device_id ee1004_ids[] = {
  50        { "ee1004", 0 },
  51        { }
  52};
  53MODULE_DEVICE_TABLE(i2c, ee1004_ids);
  54
  55/*-------------------------------------------------------------------------*/
  56
  57static int ee1004_get_current_page(void)
  58{
  59        int err;
  60
  61        err = i2c_smbus_read_byte(ee1004_set_page[0]);
  62        if (err == -ENXIO) {
  63                /* Nack means page 1 is selected */
  64                return 1;
  65        }
  66        if (err < 0) {
  67                /* Anything else is a real error, bail out */
  68                return err;
  69        }
  70
  71        /* Ack means page 0 is selected, returned value meaningless */
  72        return 0;
  73}
  74
  75static int ee1004_set_current_page(struct device *dev, int page)
  76{
  77        int ret;
  78
  79        if (page == ee1004_current_page)
  80                return 0;
  81
  82        /* Data is ignored */
  83        ret = i2c_smbus_write_byte(ee1004_set_page[page], 0x00);
  84        /*
  85         * Don't give up just yet. Some memory modules will select the page
  86         * but not ack the command. Check which page is selected now.
  87         */
  88        if (ret == -ENXIO && ee1004_get_current_page() == page)
  89                ret = 0;
  90        if (ret < 0) {
  91                dev_err(dev, "Failed to select page %d (%d)\n", page, ret);
  92                return ret;
  93        }
  94
  95        dev_dbg(dev, "Selected page %d\n", page);
  96        ee1004_current_page = page;
  97
  98        return 0;
  99}
 100
 101static ssize_t ee1004_eeprom_read(struct i2c_client *client, char *buf,
 102                                  unsigned int offset, size_t count)
 103{
 104        int status, page;
 105
 106        page = offset >> EE1004_PAGE_SHIFT;
 107        offset &= (1 << EE1004_PAGE_SHIFT) - 1;
 108
 109        status = ee1004_set_current_page(&client->dev, page);
 110        if (status)
 111                return status;
 112
 113        /* Can't cross page boundaries */
 114        if (offset + count > EE1004_PAGE_SIZE)
 115                count = EE1004_PAGE_SIZE - offset;
 116
 117        return i2c_smbus_read_i2c_block_data_or_emulated(client, offset, count, buf);
 118}
 119
 120static ssize_t eeprom_read(struct file *filp, struct kobject *kobj,
 121                           struct bin_attribute *bin_attr,
 122                           char *buf, loff_t off, size_t count)
 123{
 124        struct i2c_client *client = kobj_to_i2c_client(kobj);
 125        size_t requested = count;
 126        int ret = 0;
 127
 128        /*
 129         * Read data from chip, protecting against concurrent access to
 130         * other EE1004 SPD EEPROMs on the same adapter.
 131         */
 132        mutex_lock(&ee1004_bus_lock);
 133
 134        while (count) {
 135                ret = ee1004_eeprom_read(client, buf, off, count);
 136                if (ret < 0)
 137                        goto out;
 138
 139                buf += ret;
 140                off += ret;
 141                count -= ret;
 142        }
 143out:
 144        mutex_unlock(&ee1004_bus_lock);
 145
 146        return ret < 0 ? ret : requested;
 147}
 148
 149static BIN_ATTR_RO(eeprom, EE1004_EEPROM_SIZE);
 150
 151static struct bin_attribute *ee1004_attrs[] = {
 152        &bin_attr_eeprom,
 153        NULL
 154};
 155
 156BIN_ATTRIBUTE_GROUPS(ee1004);
 157
 158static void ee1004_cleanup(int idx)
 159{
 160        if (--ee1004_dev_count == 0)
 161                while (--idx >= 0) {
 162                        i2c_unregister_device(ee1004_set_page[idx]);
 163                        ee1004_set_page[idx] = NULL;
 164                }
 165}
 166
 167static int ee1004_probe(struct i2c_client *client)
 168{
 169        int err, cnr = 0;
 170
 171        /* Make sure we can operate on this adapter */
 172        if (!i2c_check_functionality(client->adapter,
 173                                     I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_READ_I2C_BLOCK) &&
 174            !i2c_check_functionality(client->adapter,
 175                                     I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_READ_BYTE_DATA))
 176                return -EPFNOSUPPORT;
 177
 178        /* Use 2 dummy devices for page select command */
 179        mutex_lock(&ee1004_bus_lock);
 180        if (++ee1004_dev_count == 1) {
 181                for (cnr = 0; cnr < EE1004_NUM_PAGES; cnr++) {
 182                        struct i2c_client *cl;
 183
 184                        cl = i2c_new_dummy_device(client->adapter, EE1004_ADDR_SET_PAGE + cnr);
 185                        if (IS_ERR(cl)) {
 186                                err = PTR_ERR(cl);
 187                                goto err_clients;
 188                        }
 189                        ee1004_set_page[cnr] = cl;
 190                }
 191
 192                /* Remember current page to avoid unneeded page select */
 193                err = ee1004_get_current_page();
 194                if (err < 0)
 195                        goto err_clients;
 196                dev_dbg(&client->dev, "Currently selected page: %d\n", err);
 197                ee1004_current_page = err;
 198        } else if (client->adapter != ee1004_set_page[0]->adapter) {
 199                dev_err(&client->dev,
 200                        "Driver only supports devices on a single I2C bus\n");
 201                err = -EOPNOTSUPP;
 202                goto err_clients;
 203        }
 204        mutex_unlock(&ee1004_bus_lock);
 205
 206        dev_info(&client->dev,
 207                 "%u byte EE1004-compliant SPD EEPROM, read-only\n",
 208                 EE1004_EEPROM_SIZE);
 209
 210        return 0;
 211
 212 err_clients:
 213        ee1004_cleanup(cnr);
 214        mutex_unlock(&ee1004_bus_lock);
 215
 216        return err;
 217}
 218
 219static int ee1004_remove(struct i2c_client *client)
 220{
 221        /* Remove page select clients if this is the last device */
 222        mutex_lock(&ee1004_bus_lock);
 223        ee1004_cleanup(EE1004_NUM_PAGES);
 224        mutex_unlock(&ee1004_bus_lock);
 225
 226        return 0;
 227}
 228
 229/*-------------------------------------------------------------------------*/
 230
 231static struct i2c_driver ee1004_driver = {
 232        .driver = {
 233                .name = "ee1004",
 234                .dev_groups = ee1004_groups,
 235        },
 236        .probe_new = ee1004_probe,
 237        .remove = ee1004_remove,
 238        .id_table = ee1004_ids,
 239};
 240module_i2c_driver(ee1004_driver);
 241
 242MODULE_DESCRIPTION("Driver for EE1004-compliant DDR4 SPD EEPROMs");
 243MODULE_AUTHOR("Jean Delvare");
 244MODULE_LICENSE("GPL");
 245