linux/drivers/w1/masters/ds2482.c
<<
>>
Prefs
   1/**
   2 * ds2482.c - provides i2c to w1-master bridge(s)
   3 * Copyright (C) 2005  Ben Gardner <bgardner@wabtec.com>
   4 *
   5 * The DS2482 is a sensor chip made by Dallas Semiconductor (Maxim).
   6 * It is a I2C to 1-wire bridge.
   7 * There are two variations: -100 and -800, which have 1 or 8 1-wire ports.
   8 * The complete datasheet can be obtained from MAXIM's website at:
   9 *   http://www.maxim-ic.com/quick_view2.cfm/qv_pk/4382
  10 *
  11 * This program is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License as published by
  13 * the Free Software Foundation; version 2 of the License.
  14 */
  15
  16#include <linux/module.h>
  17#include <linux/init.h>
  18#include <linux/slab.h>
  19#include <linux/i2c.h>
  20#include <linux/delay.h>
  21#include <asm/delay.h>
  22
  23#include <linux/w1.h>
  24
  25/**
  26 * Allow the active pullup to be disabled, default is enabled.
  27 *
  28 * Note from the DS2482 datasheet:
  29 * The APU bit controls whether an active pullup (controlled slew-rate
  30 * transistor) or a passive pullup (Rwpu resistor) will be used to drive
  31 * a 1-Wire line from low to high. When APU = 0, active pullup is disabled
  32 * (resistor mode). Active Pullup should always be selected unless there is
  33 * only a single slave on the 1-Wire line.
  34 */
  35static int ds2482_active_pullup = 1;
  36module_param_named(active_pullup, ds2482_active_pullup, int, 0644);
  37MODULE_PARM_DESC(active_pullup, "Active pullup (apply to all buses): " \
  38                                "0-disable, 1-enable (default)");
  39
  40/**
  41 * The DS2482 registers - there are 3 registers that are addressed by a read
  42 * pointer. The read pointer is set by the last command executed.
  43 *
  44 * To read the data, issue a register read for any address
  45 */
  46#define DS2482_CMD_RESET                0xF0    /* No param */
  47#define DS2482_CMD_SET_READ_PTR         0xE1    /* Param: DS2482_PTR_CODE_xxx */
  48#define DS2482_CMD_CHANNEL_SELECT       0xC3    /* Param: Channel byte - DS2482-800 only */
  49#define DS2482_CMD_WRITE_CONFIG         0xD2    /* Param: Config byte */
  50#define DS2482_CMD_1WIRE_RESET          0xB4    /* Param: None */
  51#define DS2482_CMD_1WIRE_SINGLE_BIT     0x87    /* Param: Bit byte (bit7) */
  52#define DS2482_CMD_1WIRE_WRITE_BYTE     0xA5    /* Param: Data byte */
  53#define DS2482_CMD_1WIRE_READ_BYTE      0x96    /* Param: None */
  54/* Note to read the byte, Set the ReadPtr to Data then read (any addr) */
  55#define DS2482_CMD_1WIRE_TRIPLET        0x78    /* Param: Dir byte (bit7) */
  56
  57/* Values for DS2482_CMD_SET_READ_PTR */
  58#define DS2482_PTR_CODE_STATUS          0xF0
  59#define DS2482_PTR_CODE_DATA            0xE1
  60#define DS2482_PTR_CODE_CHANNEL         0xD2    /* DS2482-800 only */
  61#define DS2482_PTR_CODE_CONFIG          0xC3
  62
  63/**
  64 * Configure Register bit definitions
  65 * The top 4 bits always read 0.
  66 * To write, the top nibble must be the 1's compl. of the low nibble.
  67 */
  68#define DS2482_REG_CFG_1WS              0x08    /* 1-wire speed */
  69#define DS2482_REG_CFG_SPU              0x04    /* strong pull-up */
  70#define DS2482_REG_CFG_PPM              0x02    /* presence pulse masking */
  71#define DS2482_REG_CFG_APU              0x01    /* active pull-up */
  72
  73/* extra configurations - e.g. 1WS */
  74int extra_config;
  75
  76/**
  77 * Write and verify codes for the CHANNEL_SELECT command (DS2482-800 only).
  78 * To set the channel, write the value at the index of the channel.
  79 * Read and compare against the corresponding value to verify the change.
  80 */
  81static const u8 ds2482_chan_wr[8] =
  82        { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87 };
  83static const u8 ds2482_chan_rd[8] =
  84        { 0xB8, 0xB1, 0xAA, 0xA3, 0x9C, 0x95, 0x8E, 0x87 };
  85
  86
  87/**
  88 * Status Register bit definitions (read only)
  89 */
  90#define DS2482_REG_STS_DIR              0x80
  91#define DS2482_REG_STS_TSB              0x40
  92#define DS2482_REG_STS_SBR              0x20
  93#define DS2482_REG_STS_RST              0x10
  94#define DS2482_REG_STS_LL               0x08
  95#define DS2482_REG_STS_SD               0x04
  96#define DS2482_REG_STS_PPD              0x02
  97#define DS2482_REG_STS_1WB              0x01
  98
  99/*
 100 * Client data (each client gets its own)
 101 */
 102
 103struct ds2482_data;
 104
 105struct ds2482_w1_chan {
 106        struct ds2482_data      *pdev;
 107        u8                      channel;
 108        struct w1_bus_master    w1_bm;
 109};
 110
 111struct ds2482_data {
 112        struct i2c_client       *client;
 113        struct mutex            access_lock;
 114
 115        /* 1-wire interface(s) */
 116        int                     w1_count;       /* 1 or 8 */
 117        struct ds2482_w1_chan   w1_ch[8];
 118
 119        /* per-device values */
 120        u8                      channel;
 121        u8                      read_prt;       /* see DS2482_PTR_CODE_xxx */
 122        u8                      reg_config;
 123};
 124
 125
 126/**
 127 * Helper to calculate values for configuration register
 128 * @param conf the raw config value
 129 * @return the value w/ complements that can be written to register
 130 */
 131static inline u8 ds2482_calculate_config(u8 conf)
 132{
 133        if (ds2482_active_pullup)
 134                conf |= DS2482_REG_CFG_APU;
 135
 136        return conf | ((~conf & 0x0f) << 4);
 137}
 138
 139
 140/**
 141 * Sets the read pointer.
 142 * @param pdev          The ds2482 client pointer
 143 * @param read_ptr      see DS2482_PTR_CODE_xxx above
 144 * @return -1 on failure, 0 on success
 145 */
 146static inline int ds2482_select_register(struct ds2482_data *pdev, u8 read_ptr)
 147{
 148        if (pdev->read_prt != read_ptr) {
 149                if (i2c_smbus_write_byte_data(pdev->client,
 150                                              DS2482_CMD_SET_READ_PTR,
 151                                              read_ptr) < 0)
 152                        return -1;
 153
 154                pdev->read_prt = read_ptr;
 155        }
 156        return 0;
 157}
 158
 159/**
 160 * Sends a command without a parameter
 161 * @param pdev  The ds2482 client pointer
 162 * @param cmd   DS2482_CMD_RESET,
 163 *              DS2482_CMD_1WIRE_RESET,
 164 *              DS2482_CMD_1WIRE_READ_BYTE
 165 * @return -1 on failure, 0 on success
 166 */
 167static inline int ds2482_send_cmd(struct ds2482_data *pdev, u8 cmd)
 168{
 169        if (i2c_smbus_write_byte(pdev->client, cmd) < 0)
 170                return -1;
 171
 172        pdev->read_prt = DS2482_PTR_CODE_STATUS;
 173        return 0;
 174}
 175
 176/**
 177 * Sends a command with a parameter
 178 * @param pdev  The ds2482 client pointer
 179 * @param cmd   DS2482_CMD_WRITE_CONFIG,
 180 *              DS2482_CMD_1WIRE_SINGLE_BIT,
 181 *              DS2482_CMD_1WIRE_WRITE_BYTE,
 182 *              DS2482_CMD_1WIRE_TRIPLET
 183 * @param byte  The data to send
 184 * @return -1 on failure, 0 on success
 185 */
 186static inline int ds2482_send_cmd_data(struct ds2482_data *pdev,
 187                                       u8 cmd, u8 byte)
 188{
 189        if (i2c_smbus_write_byte_data(pdev->client, cmd, byte) < 0)
 190                return -1;
 191
 192        /* all cmds leave in STATUS, except CONFIG */
 193        pdev->read_prt = (cmd != DS2482_CMD_WRITE_CONFIG) ?
 194                         DS2482_PTR_CODE_STATUS : DS2482_PTR_CODE_CONFIG;
 195        return 0;
 196}
 197
 198
 199/*
 200 * 1-Wire interface code
 201 */
 202
 203#define DS2482_WAIT_IDLE_TIMEOUT        100
 204
 205/**
 206 * Waits until the 1-wire interface is idle (not busy)
 207 *
 208 * @param pdev Pointer to the device structure
 209 * @return the last value read from status or -1 (failure)
 210 */
 211static int ds2482_wait_1wire_idle(struct ds2482_data *pdev)
 212{
 213        int temp = -1;
 214        int retries = 0;
 215
 216        if (!ds2482_select_register(pdev, DS2482_PTR_CODE_STATUS)) {
 217                do {
 218                        temp = i2c_smbus_read_byte(pdev->client);
 219                } while ((temp >= 0) && (temp & DS2482_REG_STS_1WB) &&
 220                         (++retries < DS2482_WAIT_IDLE_TIMEOUT));
 221        }
 222
 223        if (retries >= DS2482_WAIT_IDLE_TIMEOUT)
 224                pr_err("%s: timeout on channel %d\n",
 225                       __func__, pdev->channel);
 226
 227        return temp;
 228}
 229
 230/**
 231 * Selects a w1 channel.
 232 * The 1-wire interface must be idle before calling this function.
 233 *
 234 * @param pdev          The ds2482 client pointer
 235 * @param channel       0-7
 236 * @return              -1 (failure) or 0 (success)
 237 */
 238static int ds2482_set_channel(struct ds2482_data *pdev, u8 channel)
 239{
 240        if (i2c_smbus_write_byte_data(pdev->client, DS2482_CMD_CHANNEL_SELECT,
 241                                      ds2482_chan_wr[channel]) < 0)
 242                return -1;
 243
 244        pdev->read_prt = DS2482_PTR_CODE_CHANNEL;
 245        pdev->channel = -1;
 246        if (i2c_smbus_read_byte(pdev->client) == ds2482_chan_rd[channel]) {
 247                pdev->channel = channel;
 248                return 0;
 249        }
 250        return -1;
 251}
 252
 253
 254/**
 255 * Performs the touch-bit function, which writes a 0 or 1 and reads the level.
 256 *
 257 * @param data  The ds2482 channel pointer
 258 * @param bit   The level to write: 0 or non-zero
 259 * @return      The level read: 0 or 1
 260 */
 261static u8 ds2482_w1_touch_bit(void *data, u8 bit)
 262{
 263        struct ds2482_w1_chan *pchan = data;
 264        struct ds2482_data    *pdev = pchan->pdev;
 265        int status = -1;
 266
 267        mutex_lock(&pdev->access_lock);
 268
 269        /* Select the channel */
 270        ds2482_wait_1wire_idle(pdev);
 271        if (pdev->w1_count > 1)
 272                ds2482_set_channel(pdev, pchan->channel);
 273
 274        /* Send the touch command, wait until 1WB == 0, return the status */
 275        if (!ds2482_send_cmd_data(pdev, DS2482_CMD_1WIRE_SINGLE_BIT,
 276                                  bit ? 0xFF : 0))
 277                status = ds2482_wait_1wire_idle(pdev);
 278
 279        mutex_unlock(&pdev->access_lock);
 280
 281        return (status & DS2482_REG_STS_SBR) ? 1 : 0;
 282}
 283
 284/**
 285 * Performs the triplet function, which reads two bits and writes a bit.
 286 * The bit written is determined by the two reads:
 287 *   00 => dbit, 01 => 0, 10 => 1
 288 *
 289 * @param data  The ds2482 channel pointer
 290 * @param dbit  The direction to choose if both branches are valid
 291 * @return      b0=read1 b1=read2 b3=bit written
 292 */
 293static u8 ds2482_w1_triplet(void *data, u8 dbit)
 294{
 295        struct ds2482_w1_chan *pchan = data;
 296        struct ds2482_data    *pdev = pchan->pdev;
 297        int status = (3 << 5);
 298
 299        mutex_lock(&pdev->access_lock);
 300
 301        /* Select the channel */
 302        ds2482_wait_1wire_idle(pdev);
 303        if (pdev->w1_count > 1)
 304                ds2482_set_channel(pdev, pchan->channel);
 305
 306        /* Send the triplet command, wait until 1WB == 0, return the status */
 307        if (!ds2482_send_cmd_data(pdev, DS2482_CMD_1WIRE_TRIPLET,
 308                                  dbit ? 0xFF : 0))
 309                status = ds2482_wait_1wire_idle(pdev);
 310
 311        mutex_unlock(&pdev->access_lock);
 312
 313        /* Decode the status */
 314        return (status >> 5);
 315}
 316
 317/**
 318 * Performs the write byte function.
 319 *
 320 * @param data  The ds2482 channel pointer
 321 * @param byte  The value to write
 322 */
 323static void ds2482_w1_write_byte(void *data, u8 byte)
 324{
 325        struct ds2482_w1_chan *pchan = data;
 326        struct ds2482_data    *pdev = pchan->pdev;
 327
 328        mutex_lock(&pdev->access_lock);
 329
 330        /* Select the channel */
 331        ds2482_wait_1wire_idle(pdev);
 332        if (pdev->w1_count > 1)
 333                ds2482_set_channel(pdev, pchan->channel);
 334
 335        /* Send the write byte command */
 336        ds2482_send_cmd_data(pdev, DS2482_CMD_1WIRE_WRITE_BYTE, byte);
 337
 338        mutex_unlock(&pdev->access_lock);
 339}
 340
 341/**
 342 * Performs the read byte function.
 343 *
 344 * @param data  The ds2482 channel pointer
 345 * @return      The value read
 346 */
 347static u8 ds2482_w1_read_byte(void *data)
 348{
 349        struct ds2482_w1_chan *pchan = data;
 350        struct ds2482_data    *pdev = pchan->pdev;
 351        int result;
 352
 353        mutex_lock(&pdev->access_lock);
 354
 355        /* Select the channel */
 356        ds2482_wait_1wire_idle(pdev);
 357        if (pdev->w1_count > 1)
 358                ds2482_set_channel(pdev, pchan->channel);
 359
 360        /* Send the read byte command */
 361        ds2482_send_cmd(pdev, DS2482_CMD_1WIRE_READ_BYTE);
 362
 363        /* Wait until 1WB == 0 */
 364        ds2482_wait_1wire_idle(pdev);
 365
 366        /* Select the data register */
 367        ds2482_select_register(pdev, DS2482_PTR_CODE_DATA);
 368
 369        /* Read the data byte */
 370        result = i2c_smbus_read_byte(pdev->client);
 371
 372        mutex_unlock(&pdev->access_lock);
 373
 374        return result;
 375}
 376
 377
 378/**
 379 * Sends a reset on the 1-wire interface
 380 *
 381 * @param data  The ds2482 channel pointer
 382 * @return      0=Device present, 1=No device present or error
 383 */
 384static u8 ds2482_w1_reset_bus(void *data)
 385{
 386        struct ds2482_w1_chan *pchan = data;
 387        struct ds2482_data    *pdev = pchan->pdev;
 388        int err;
 389        u8 retval = 1;
 390
 391        mutex_lock(&pdev->access_lock);
 392
 393        /* Select the channel */
 394        ds2482_wait_1wire_idle(pdev);
 395        if (pdev->w1_count > 1)
 396                ds2482_set_channel(pdev, pchan->channel);
 397
 398        /* Send the reset command */
 399        err = ds2482_send_cmd(pdev, DS2482_CMD_1WIRE_RESET);
 400        if (err >= 0) {
 401                /* Wait until the reset is complete */
 402                err = ds2482_wait_1wire_idle(pdev);
 403                retval = !(err & DS2482_REG_STS_PPD);
 404
 405                /* If the chip did reset since detect, re-config it */
 406                if (err & DS2482_REG_STS_RST)
 407                        ds2482_send_cmd_data(pdev, DS2482_CMD_WRITE_CONFIG,
 408                                        ds2482_calculate_config(extra_config));
 409        }
 410
 411        mutex_unlock(&pdev->access_lock);
 412
 413        return retval;
 414}
 415
 416static u8 ds2482_w1_set_pullup(void *data, int delay)
 417{
 418        struct ds2482_w1_chan *pchan = data;
 419        struct ds2482_data    *pdev = pchan->pdev;
 420        u8 retval = 1;
 421
 422        /* if delay is non-zero activate the pullup,
 423         * the strong pullup will be automatically deactivated
 424         * by the master, so do not explicitly deactive it
 425         */
 426        if (delay) {
 427                /* both waits are crucial, otherwise devices might not be
 428                 * powered long enough, causing e.g. a w1_therm sensor to
 429                 * provide wrong conversion results
 430                 */
 431                ds2482_wait_1wire_idle(pdev);
 432                /* note: it seems like both SPU and APU have to be set! */
 433                retval = ds2482_send_cmd_data(pdev, DS2482_CMD_WRITE_CONFIG,
 434                        ds2482_calculate_config(extra_config|DS2482_REG_CFG_SPU|DS2482_REG_CFG_APU));
 435                ds2482_wait_1wire_idle(pdev);
 436        }
 437
 438        return retval;
 439}
 440
 441
 442static int ds2482_probe(struct i2c_client *client,
 443                        const struct i2c_device_id *id)
 444{
 445        struct ds2482_data *data;
 446        int err = -ENODEV;
 447        int temp1;
 448        int idx;
 449
 450        if (!i2c_check_functionality(client->adapter,
 451                                     I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
 452                                     I2C_FUNC_SMBUS_BYTE))
 453                return -ENODEV;
 454
 455        if (!(data = kzalloc(sizeof(struct ds2482_data), GFP_KERNEL))) {
 456                err = -ENOMEM;
 457                goto exit;
 458        }
 459
 460        data->client = client;
 461        i2c_set_clientdata(client, data);
 462
 463        /* Reset the device (sets the read_ptr to status) */
 464        if (ds2482_send_cmd(data, DS2482_CMD_RESET) < 0) {
 465                dev_warn(&client->dev, "DS2482 reset failed.\n");
 466                goto exit_free;
 467        }
 468
 469        /* Sleep at least 525ns to allow the reset to complete */
 470        ndelay(525);
 471
 472        /* Read the status byte - only reset bit and line should be set */
 473        temp1 = i2c_smbus_read_byte(client);
 474        if (temp1 != (DS2482_REG_STS_LL | DS2482_REG_STS_RST)) {
 475                dev_warn(&client->dev, "DS2482 reset status "
 476                         "0x%02X - not a DS2482\n", temp1);
 477                goto exit_free;
 478        }
 479
 480        /* Detect the 8-port version */
 481        data->w1_count = 1;
 482        if (ds2482_set_channel(data, 7) == 0)
 483                data->w1_count = 8;
 484
 485        /* Set all config items to 0 (off) */
 486        ds2482_send_cmd_data(data, DS2482_CMD_WRITE_CONFIG,
 487                ds2482_calculate_config(extra_config));
 488
 489        mutex_init(&data->access_lock);
 490
 491        /* Register 1-wire interface(s) */
 492        for (idx = 0; idx < data->w1_count; idx++) {
 493                data->w1_ch[idx].pdev = data;
 494                data->w1_ch[idx].channel = idx;
 495
 496                /* Populate all the w1 bus master stuff */
 497                data->w1_ch[idx].w1_bm.data       = &data->w1_ch[idx];
 498                data->w1_ch[idx].w1_bm.read_byte  = ds2482_w1_read_byte;
 499                data->w1_ch[idx].w1_bm.write_byte = ds2482_w1_write_byte;
 500                data->w1_ch[idx].w1_bm.touch_bit  = ds2482_w1_touch_bit;
 501                data->w1_ch[idx].w1_bm.triplet    = ds2482_w1_triplet;
 502                data->w1_ch[idx].w1_bm.reset_bus  = ds2482_w1_reset_bus;
 503                data->w1_ch[idx].w1_bm.set_pullup = ds2482_w1_set_pullup;
 504
 505                err = w1_add_master_device(&data->w1_ch[idx].w1_bm);
 506                if (err) {
 507                        data->w1_ch[idx].pdev = NULL;
 508                        goto exit_w1_remove;
 509                }
 510        }
 511
 512        return 0;
 513
 514exit_w1_remove:
 515        for (idx = 0; idx < data->w1_count; idx++) {
 516                if (data->w1_ch[idx].pdev != NULL)
 517                        w1_remove_master_device(&data->w1_ch[idx].w1_bm);
 518        }
 519exit_free:
 520        kfree(data);
 521exit:
 522        return err;
 523}
 524
 525static int ds2482_remove(struct i2c_client *client)
 526{
 527        struct ds2482_data   *data = i2c_get_clientdata(client);
 528        int idx;
 529
 530        /* Unregister the 1-wire bridge(s) */
 531        for (idx = 0; idx < data->w1_count; idx++) {
 532                if (data->w1_ch[idx].pdev != NULL)
 533                        w1_remove_master_device(&data->w1_ch[idx].w1_bm);
 534        }
 535
 536        /* Free the memory */
 537        kfree(data);
 538        return 0;
 539}
 540
 541/**
 542 * Driver data (common to all clients)
 543 */
 544static const struct i2c_device_id ds2482_id[] = {
 545        { "ds2482", 0 },
 546        { }
 547};
 548MODULE_DEVICE_TABLE(i2c, ds2482_id);
 549
 550static struct i2c_driver ds2482_driver = {
 551        .driver = {
 552                .name   = "ds2482",
 553        },
 554        .probe          = ds2482_probe,
 555        .remove         = ds2482_remove,
 556        .id_table       = ds2482_id,
 557};
 558module_i2c_driver(ds2482_driver);
 559
 560MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>");
 561MODULE_DESCRIPTION("DS2482 driver");
 562module_param(extra_config, int, S_IRUGO | S_IWUSR);
 563MODULE_PARM_DESC(extra_config, "Extra Configuration settings 1=APU,2=PPM,3=SPU,8=1WS");
 564
 565MODULE_LICENSE("GPL");
 566