linux/drivers/i2c/i2c-smbus.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * i2c-smbus.c - SMBus extensions to the I2C protocol
   4 *
   5 * Copyright (C) 2008 David Brownell
   6 * Copyright (C) 2010-2019 Jean Delvare <jdelvare@suse.de>
   7 */
   8
   9#include <linux/device.h>
  10#include <linux/dmi.h>
  11#include <linux/i2c.h>
  12#include <linux/i2c-smbus.h>
  13#include <linux/interrupt.h>
  14#include <linux/kernel.h>
  15#include <linux/module.h>
  16#include <linux/of_irq.h>
  17#include <linux/slab.h>
  18#include <linux/workqueue.h>
  19
  20struct i2c_smbus_alert {
  21        struct work_struct      alert;
  22        struct i2c_client       *ara;           /* Alert response address */
  23};
  24
  25struct alert_data {
  26        unsigned short          addr;
  27        enum i2c_alert_protocol type;
  28        unsigned int            data;
  29};
  30
  31/* If this is the alerting device, notify its driver */
  32static int smbus_do_alert(struct device *dev, void *addrp)
  33{
  34        struct i2c_client *client = i2c_verify_client(dev);
  35        struct alert_data *data = addrp;
  36        struct i2c_driver *driver;
  37
  38        if (!client || client->addr != data->addr)
  39                return 0;
  40        if (client->flags & I2C_CLIENT_TEN)
  41                return 0;
  42
  43        /*
  44         * Drivers should either disable alerts, or provide at least
  45         * a minimal handler.  Lock so the driver won't change.
  46         */
  47        device_lock(dev);
  48        if (client->dev.driver) {
  49                driver = to_i2c_driver(client->dev.driver);
  50                if (driver->alert)
  51                        driver->alert(client, data->type, data->data);
  52                else
  53                        dev_warn(&client->dev, "no driver alert()!\n");
  54        } else
  55                dev_dbg(&client->dev, "alert with no driver\n");
  56        device_unlock(dev);
  57
  58        /* Stop iterating after we find the device */
  59        return -EBUSY;
  60}
  61
  62/*
  63 * The alert IRQ handler needs to hand work off to a task which can issue
  64 * SMBus calls, because those sleeping calls can't be made in IRQ context.
  65 */
  66static irqreturn_t smbus_alert(int irq, void *d)
  67{
  68        struct i2c_smbus_alert *alert = d;
  69        struct i2c_client *ara;
  70
  71        ara = alert->ara;
  72
  73        for (;;) {
  74                s32 status;
  75                struct alert_data data;
  76
  77                /*
  78                 * Devices with pending alerts reply in address order, low
  79                 * to high, because of slave transmit arbitration.  After
  80                 * responding, an SMBus device stops asserting SMBALERT#.
  81                 *
  82                 * Note that SMBus 2.0 reserves 10-bit addresses for future
  83                 * use.  We neither handle them, nor try to use PEC here.
  84                 */
  85                status = i2c_smbus_read_byte(ara);
  86                if (status < 0)
  87                        break;
  88
  89                data.data = status & 1;
  90                data.addr = status >> 1;
  91                data.type = I2C_PROTOCOL_SMBUS_ALERT;
  92
  93                dev_dbg(&ara->dev, "SMBALERT# from dev 0x%02x, flag %d\n",
  94                        data.addr, data.data);
  95
  96                /* Notify driver for the device which issued the alert */
  97                device_for_each_child(&ara->adapter->dev, &data,
  98                                      smbus_do_alert);
  99        }
 100
 101        return IRQ_HANDLED;
 102}
 103
 104static void smbalert_work(struct work_struct *work)
 105{
 106        struct i2c_smbus_alert *alert;
 107
 108        alert = container_of(work, struct i2c_smbus_alert, alert);
 109
 110        smbus_alert(0, alert);
 111
 112}
 113
 114/* Setup SMBALERT# infrastructure */
 115static int smbalert_probe(struct i2c_client *ara,
 116                          const struct i2c_device_id *id)
 117{
 118        struct i2c_smbus_alert_setup *setup = dev_get_platdata(&ara->dev);
 119        struct i2c_smbus_alert *alert;
 120        struct i2c_adapter *adapter = ara->adapter;
 121        int res, irq;
 122
 123        alert = devm_kzalloc(&ara->dev, sizeof(struct i2c_smbus_alert),
 124                             GFP_KERNEL);
 125        if (!alert)
 126                return -ENOMEM;
 127
 128        if (setup) {
 129                irq = setup->irq;
 130        } else {
 131                irq = of_irq_get_byname(adapter->dev.of_node, "smbus_alert");
 132                if (irq <= 0)
 133                        return irq;
 134        }
 135
 136        INIT_WORK(&alert->alert, smbalert_work);
 137        alert->ara = ara;
 138
 139        if (irq > 0) {
 140                res = devm_request_threaded_irq(&ara->dev, irq,
 141                                                NULL, smbus_alert,
 142                                                IRQF_SHARED | IRQF_ONESHOT,
 143                                                "smbus_alert", alert);
 144                if (res)
 145                        return res;
 146        }
 147
 148        i2c_set_clientdata(ara, alert);
 149        dev_info(&adapter->dev, "supports SMBALERT#\n");
 150
 151        return 0;
 152}
 153
 154/* IRQ and memory resources are managed so they are freed automatically */
 155static int smbalert_remove(struct i2c_client *ara)
 156{
 157        struct i2c_smbus_alert *alert = i2c_get_clientdata(ara);
 158
 159        cancel_work_sync(&alert->alert);
 160        return 0;
 161}
 162
 163static const struct i2c_device_id smbalert_ids[] = {
 164        { "smbus_alert", 0 },
 165        { /* LIST END */ }
 166};
 167MODULE_DEVICE_TABLE(i2c, smbalert_ids);
 168
 169static struct i2c_driver smbalert_driver = {
 170        .driver = {
 171                .name   = "smbus_alert",
 172        },
 173        .probe          = smbalert_probe,
 174        .remove         = smbalert_remove,
 175        .id_table       = smbalert_ids,
 176};
 177
 178/**
 179 * i2c_handle_smbus_alert - Handle an SMBus alert
 180 * @ara: the ARA client on the relevant adapter
 181 * Context: can't sleep
 182 *
 183 * Helper function to be called from an I2C bus driver's interrupt
 184 * handler. It will schedule the alert work, in turn calling the
 185 * corresponding I2C device driver's alert function.
 186 *
 187 * It is assumed that ara is a valid i2c client previously returned by
 188 * i2c_new_smbus_alert_device().
 189 */
 190int i2c_handle_smbus_alert(struct i2c_client *ara)
 191{
 192        struct i2c_smbus_alert *alert = i2c_get_clientdata(ara);
 193
 194        return schedule_work(&alert->alert);
 195}
 196EXPORT_SYMBOL_GPL(i2c_handle_smbus_alert);
 197
 198module_i2c_driver(smbalert_driver);
 199
 200#if IS_ENABLED(CONFIG_I2C_SLAVE)
 201#define SMBUS_HOST_NOTIFY_LEN   3
 202struct i2c_slave_host_notify_status {
 203        u8 index;
 204        u8 addr;
 205};
 206
 207static int i2c_slave_host_notify_cb(struct i2c_client *client,
 208                                    enum i2c_slave_event event, u8 *val)
 209{
 210        struct i2c_slave_host_notify_status *status = client->dev.platform_data;
 211
 212        switch (event) {
 213        case I2C_SLAVE_WRITE_RECEIVED:
 214                /* We only retrieve the first byte received (addr)
 215                 * since there is currently no support to retrieve the data
 216                 * parameter from the client.
 217                 */
 218                if (status->index == 0)
 219                        status->addr = *val;
 220                if (status->index < U8_MAX)
 221                        status->index++;
 222                break;
 223        case I2C_SLAVE_STOP:
 224                if (status->index == SMBUS_HOST_NOTIFY_LEN)
 225                        i2c_handle_smbus_host_notify(client->adapter,
 226                                                     status->addr);
 227                fallthrough;
 228        case I2C_SLAVE_WRITE_REQUESTED:
 229                status->index = 0;
 230                break;
 231        case I2C_SLAVE_READ_REQUESTED:
 232        case I2C_SLAVE_READ_PROCESSED:
 233                *val = 0xff;
 234                break;
 235        }
 236
 237        return 0;
 238}
 239
 240/**
 241 * i2c_new_slave_host_notify_device - get a client for SMBus host-notify support
 242 * @adapter: the target adapter
 243 * Context: can sleep
 244 *
 245 * Setup handling of the SMBus host-notify protocol on a given I2C bus segment.
 246 *
 247 * Handling is done by creating a device and its callback and handling data
 248 * received via the SMBus host-notify address (0x8)
 249 *
 250 * This returns the client, which should be ultimately freed using
 251 * i2c_free_slave_host_notify_device(); or an ERRPTR to indicate an error.
 252 */
 253struct i2c_client *i2c_new_slave_host_notify_device(struct i2c_adapter *adapter)
 254{
 255        struct i2c_board_info host_notify_board_info = {
 256                I2C_BOARD_INFO("smbus_host_notify", 0x08),
 257                .flags  = I2C_CLIENT_SLAVE,
 258        };
 259        struct i2c_slave_host_notify_status *status;
 260        struct i2c_client *client;
 261        int ret;
 262
 263        status = kzalloc(sizeof(struct i2c_slave_host_notify_status),
 264                         GFP_KERNEL);
 265        if (!status)
 266                return ERR_PTR(-ENOMEM);
 267
 268        host_notify_board_info.platform_data = status;
 269
 270        client = i2c_new_client_device(adapter, &host_notify_board_info);
 271        if (IS_ERR(client)) {
 272                kfree(status);
 273                return client;
 274        }
 275
 276        ret = i2c_slave_register(client, i2c_slave_host_notify_cb);
 277        if (ret) {
 278                i2c_unregister_device(client);
 279                kfree(status);
 280                return ERR_PTR(ret);
 281        }
 282
 283        return client;
 284}
 285EXPORT_SYMBOL_GPL(i2c_new_slave_host_notify_device);
 286
 287/**
 288 * i2c_free_slave_host_notify_device - free the client for SMBus host-notify
 289 * support
 290 * @client: the client to free
 291 * Context: can sleep
 292 *
 293 * Free the i2c_client allocated via i2c_new_slave_host_notify_device
 294 */
 295void i2c_free_slave_host_notify_device(struct i2c_client *client)
 296{
 297        if (IS_ERR_OR_NULL(client))
 298                return;
 299
 300        i2c_slave_unregister(client);
 301        kfree(client->dev.platform_data);
 302        i2c_unregister_device(client);
 303}
 304EXPORT_SYMBOL_GPL(i2c_free_slave_host_notify_device);
 305#endif
 306
 307/*
 308 * SPD is not part of SMBus but we include it here for convenience as the
 309 * target systems are the same.
 310 * Restrictions to automatic SPD instantiation:
 311 *  - Only works if all filled slots have the same memory type
 312 *  - Only works for DDR2, DDR3 and DDR4 for now
 313 *  - Only works on systems with 1 to 4 memory slots
 314 */
 315#if IS_ENABLED(CONFIG_DMI)
 316void i2c_register_spd(struct i2c_adapter *adap)
 317{
 318        int n, slot_count = 0, dimm_count = 0;
 319        u16 handle;
 320        u8 common_mem_type = 0x0, mem_type;
 321        u64 mem_size;
 322        const char *name;
 323
 324        while ((handle = dmi_memdev_handle(slot_count)) != 0xffff) {
 325                slot_count++;
 326
 327                /* Skip empty slots */
 328                mem_size = dmi_memdev_size(handle);
 329                if (!mem_size)
 330                        continue;
 331
 332                /* Skip undefined memory type */
 333                mem_type = dmi_memdev_type(handle);
 334                if (mem_type <= 0x02)           /* Invalid, Other, Unknown */
 335                        continue;
 336
 337                if (!common_mem_type) {
 338                        /* First filled slot */
 339                        common_mem_type = mem_type;
 340                } else {
 341                        /* Check that all filled slots have the same type */
 342                        if (mem_type != common_mem_type) {
 343                                dev_warn(&adap->dev,
 344                                         "Different memory types mixed, not instantiating SPD\n");
 345                                return;
 346                        }
 347                }
 348                dimm_count++;
 349        }
 350
 351        /* No useful DMI data, bail out */
 352        if (!dimm_count)
 353                return;
 354
 355        dev_info(&adap->dev, "%d/%d memory slots populated (from DMI)\n",
 356                 dimm_count, slot_count);
 357
 358        if (slot_count > 4) {
 359                dev_warn(&adap->dev,
 360                         "Systems with more than 4 memory slots not supported yet, not instantiating SPD\n");
 361                return;
 362        }
 363
 364        switch (common_mem_type) {
 365        case 0x13:      /* DDR2 */
 366        case 0x18:      /* DDR3 */
 367        case 0x1C:      /* LPDDR2 */
 368        case 0x1D:      /* LPDDR3 */
 369                name = "spd";
 370                break;
 371        case 0x1A:      /* DDR4 */
 372        case 0x1E:      /* LPDDR4 */
 373                name = "ee1004";
 374                break;
 375        default:
 376                dev_info(&adap->dev,
 377                         "Memory type 0x%02x not supported yet, not instantiating SPD\n",
 378                         common_mem_type);
 379                return;
 380        }
 381
 382        /*
 383         * We don't know in which slots the memory modules are. We could
 384         * try to guess from the slot names, but that would be rather complex
 385         * and unreliable, so better probe all possible addresses until we
 386         * have found all memory modules.
 387         */
 388        for (n = 0; n < slot_count && dimm_count; n++) {
 389                struct i2c_board_info info;
 390                unsigned short addr_list[2];
 391
 392                memset(&info, 0, sizeof(struct i2c_board_info));
 393                strlcpy(info.type, name, I2C_NAME_SIZE);
 394                addr_list[0] = 0x50 + n;
 395                addr_list[1] = I2C_CLIENT_END;
 396
 397                if (!IS_ERR(i2c_new_scanned_device(adap, &info, addr_list, NULL))) {
 398                        dev_info(&adap->dev,
 399                                 "Successfully instantiated SPD at 0x%hx\n",
 400                                 addr_list[0]);
 401                        dimm_count--;
 402                }
 403        }
 404}
 405EXPORT_SYMBOL_GPL(i2c_register_spd);
 406#endif
 407
 408MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");
 409MODULE_DESCRIPTION("SMBus protocol extensions support");
 410MODULE_LICENSE("GPL");
 411