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 "../w1.h"
  24#include "../w1_int.h"
  25
  26/**
  27 * The DS2482 registers - there are 3 registers that are addressed by a read
  28 * pointer. The read pointer is set by the last command executed.
  29 *
  30 * To read the data, issue a register read for any address
  31 */
  32#define DS2482_CMD_RESET                0xF0    /* No param */
  33#define DS2482_CMD_SET_READ_PTR         0xE1    /* Param: DS2482_PTR_CODE_xxx */
  34#define DS2482_CMD_CHANNEL_SELECT       0xC3    /* Param: Channel byte - DS2482-800 only */
  35#define DS2482_CMD_WRITE_CONFIG         0xD2    /* Param: Config byte */
  36#define DS2482_CMD_1WIRE_RESET          0xB4    /* Param: None */
  37#define DS2482_CMD_1WIRE_SINGLE_BIT     0x87    /* Param: Bit byte (bit7) */
  38#define DS2482_CMD_1WIRE_WRITE_BYTE     0xA5    /* Param: Data byte */
  39#define DS2482_CMD_1WIRE_READ_BYTE      0x96    /* Param: None */
  40/* Note to read the byte, Set the ReadPtr to Data then read (any addr) */
  41#define DS2482_CMD_1WIRE_TRIPLET        0x78    /* Param: Dir byte (bit7) */
  42
  43/* Values for DS2482_CMD_SET_READ_PTR */
  44#define DS2482_PTR_CODE_STATUS          0xF0
  45#define DS2482_PTR_CODE_DATA            0xE1
  46#define DS2482_PTR_CODE_CHANNEL         0xD2    /* DS2482-800 only */
  47#define DS2482_PTR_CODE_CONFIG          0xC3
  48
  49/**
  50 * Configure Register bit definitions
  51 * The top 4 bits always read 0.
  52 * To write, the top nibble must be the 1's compl. of the low nibble.
  53 */
  54#define DS2482_REG_CFG_1WS              0x08
  55#define DS2482_REG_CFG_SPU              0x04
  56#define DS2482_REG_CFG_PPM              0x02
  57#define DS2482_REG_CFG_APU              0x01
  58
  59
  60/**
  61 * Write and verify codes for the CHANNEL_SELECT command (DS2482-800 only).
  62 * To set the channel, write the value at the index of the channel.
  63 * Read and compare against the corresponding value to verify the change.
  64 */
  65static const u8 ds2482_chan_wr[8] =
  66        { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87 };
  67static const u8 ds2482_chan_rd[8] =
  68        { 0xB8, 0xB1, 0xAA, 0xA3, 0x9C, 0x95, 0x8E, 0x87 };
  69
  70
  71/**
  72 * Status Register bit definitions (read only)
  73 */
  74#define DS2482_REG_STS_DIR              0x80
  75#define DS2482_REG_STS_TSB              0x40
  76#define DS2482_REG_STS_SBR              0x20
  77#define DS2482_REG_STS_RST              0x10
  78#define DS2482_REG_STS_LL               0x08
  79#define DS2482_REG_STS_SD               0x04
  80#define DS2482_REG_STS_PPD              0x02
  81#define DS2482_REG_STS_1WB              0x01
  82
  83
  84static int ds2482_probe(struct i2c_client *client,
  85                        const struct i2c_device_id *id);
  86static int ds2482_remove(struct i2c_client *client);
  87
  88
  89/**
  90 * Driver data (common to all clients)
  91 */
  92static const struct i2c_device_id ds2482_id[] = {
  93        { "ds2482", 0 },
  94        { }
  95};
  96
  97static struct i2c_driver ds2482_driver = {
  98        .driver = {
  99                .owner  = THIS_MODULE,
 100                .name   = "ds2482",
 101        },
 102        .probe          = ds2482_probe,
 103        .remove         = ds2482_remove,
 104        .id_table       = ds2482_id,
 105};
 106
 107/*
 108 * Client data (each client gets its own)
 109 */
 110
 111struct ds2482_data;
 112
 113struct ds2482_w1_chan {
 114        struct ds2482_data      *pdev;
 115        u8                      channel;
 116        struct w1_bus_master    w1_bm;
 117};
 118
 119struct ds2482_data {
 120        struct i2c_client       *client;
 121        struct mutex            access_lock;
 122
 123        /* 1-wire interface(s) */
 124        int                     w1_count;       /* 1 or 8 */
 125        struct ds2482_w1_chan   w1_ch[8];
 126
 127        /* per-device values */
 128        u8                      channel;
 129        u8                      read_prt;       /* see DS2482_PTR_CODE_xxx */
 130        u8                      reg_config;
 131};
 132
 133
 134/**
 135 * Sets the read pointer.
 136 * @param pdev          The ds2482 client pointer
 137 * @param read_ptr      see DS2482_PTR_CODE_xxx above
 138 * @return -1 on failure, 0 on success
 139 */
 140static inline int ds2482_select_register(struct ds2482_data *pdev, u8 read_ptr)
 141{
 142        if (pdev->read_prt != read_ptr) {
 143                if (i2c_smbus_write_byte_data(pdev->client,
 144                                              DS2482_CMD_SET_READ_PTR,
 145                                              read_ptr) < 0)
 146                        return -1;
 147
 148                pdev->read_prt = read_ptr;
 149        }
 150        return 0;
 151}
 152
 153/**
 154 * Sends a command without a parameter
 155 * @param pdev  The ds2482 client pointer
 156 * @param cmd   DS2482_CMD_RESET,
 157 *              DS2482_CMD_1WIRE_RESET,
 158 *              DS2482_CMD_1WIRE_READ_BYTE
 159 * @return -1 on failure, 0 on success
 160 */
 161static inline int ds2482_send_cmd(struct ds2482_data *pdev, u8 cmd)
 162{
 163        if (i2c_smbus_write_byte(pdev->client, cmd) < 0)
 164                return -1;
 165
 166        pdev->read_prt = DS2482_PTR_CODE_STATUS;
 167        return 0;
 168}
 169
 170/**
 171 * Sends a command with a parameter
 172 * @param pdev  The ds2482 client pointer
 173 * @param cmd   DS2482_CMD_WRITE_CONFIG,
 174 *              DS2482_CMD_1WIRE_SINGLE_BIT,
 175 *              DS2482_CMD_1WIRE_WRITE_BYTE,
 176 *              DS2482_CMD_1WIRE_TRIPLET
 177 * @param byte  The data to send
 178 * @return -1 on failure, 0 on success
 179 */
 180static inline int ds2482_send_cmd_data(struct ds2482_data *pdev,
 181                                       u8 cmd, u8 byte)
 182{
 183        if (i2c_smbus_write_byte_data(pdev->client, cmd, byte) < 0)
 184                return -1;
 185
 186        /* all cmds leave in STATUS, except CONFIG */
 187        pdev->read_prt = (cmd != DS2482_CMD_WRITE_CONFIG) ?
 188                         DS2482_PTR_CODE_STATUS : DS2482_PTR_CODE_CONFIG;
 189        return 0;
 190}
 191
 192
 193/*
 194 * 1-Wire interface code
 195 */
 196
 197#define DS2482_WAIT_IDLE_TIMEOUT        100
 198
 199/**
 200 * Waits until the 1-wire interface is idle (not busy)
 201 *
 202 * @param pdev Pointer to the device structure
 203 * @return the last value read from status or -1 (failure)
 204 */
 205static int ds2482_wait_1wire_idle(struct ds2482_data *pdev)
 206{
 207        int temp = -1;
 208        int retries = 0;
 209
 210        if (!ds2482_select_register(pdev, DS2482_PTR_CODE_STATUS)) {
 211                do {
 212                        temp = i2c_smbus_read_byte(pdev->client);
 213                } while ((temp >= 0) && (temp & DS2482_REG_STS_1WB) &&
 214                         (++retries < DS2482_WAIT_IDLE_TIMEOUT));
 215        }
 216
 217        if (retries > DS2482_WAIT_IDLE_TIMEOUT)
 218                printk(KERN_ERR "%s: timeout on channel %d\n",
 219                       __func__, pdev->channel);
 220
 221        return temp;
 222}
 223
 224/**
 225 * Selects a w1 channel.
 226 * The 1-wire interface must be idle before calling this function.
 227 *
 228 * @param pdev          The ds2482 client pointer
 229 * @param channel       0-7
 230 * @return              -1 (failure) or 0 (success)
 231 */
 232static int ds2482_set_channel(struct ds2482_data *pdev, u8 channel)
 233{
 234        if (i2c_smbus_write_byte_data(pdev->client, DS2482_CMD_CHANNEL_SELECT,
 235                                      ds2482_chan_wr[channel]) < 0)
 236                return -1;
 237
 238        pdev->read_prt = DS2482_PTR_CODE_CHANNEL;
 239        pdev->channel = -1;
 240        if (i2c_smbus_read_byte(pdev->client) == ds2482_chan_rd[channel]) {
 241                pdev->channel = channel;
 242                return 0;
 243        }
 244        return -1;
 245}
 246
 247
 248/**
 249 * Performs the touch-bit function, which writes a 0 or 1 and reads the level.
 250 *
 251 * @param data  The ds2482 channel pointer
 252 * @param bit   The level to write: 0 or non-zero
 253 * @return      The level read: 0 or 1
 254 */
 255static u8 ds2482_w1_touch_bit(void *data, u8 bit)
 256{
 257        struct ds2482_w1_chan *pchan = data;
 258        struct ds2482_data    *pdev = pchan->pdev;
 259        int status = -1;
 260
 261        mutex_lock(&pdev->access_lock);
 262
 263        /* Select the channel */
 264        ds2482_wait_1wire_idle(pdev);
 265        if (pdev->w1_count > 1)
 266                ds2482_set_channel(pdev, pchan->channel);
 267
 268        /* Send the touch command, wait until 1WB == 0, return the status */
 269        if (!ds2482_send_cmd_data(pdev, DS2482_CMD_1WIRE_SINGLE_BIT,
 270                                  bit ? 0xFF : 0))
 271                status = ds2482_wait_1wire_idle(pdev);
 272
 273        mutex_unlock(&pdev->access_lock);
 274
 275        return (status & DS2482_REG_STS_SBR) ? 1 : 0;
 276}
 277
 278/**
 279 * Performs the triplet function, which reads two bits and writes a bit.
 280 * The bit written is determined by the two reads:
 281 *   00 => dbit, 01 => 0, 10 => 1
 282 *
 283 * @param data  The ds2482 channel pointer
 284 * @param dbit  The direction to choose if both branches are valid
 285 * @return      b0=read1 b1=read2 b3=bit written
 286 */
 287static u8 ds2482_w1_triplet(void *data, u8 dbit)
 288{
 289        struct ds2482_w1_chan *pchan = data;
 290        struct ds2482_data    *pdev = pchan->pdev;
 291        int status = (3 << 5);
 292
 293        mutex_lock(&pdev->access_lock);
 294
 295        /* Select the channel */
 296        ds2482_wait_1wire_idle(pdev);
 297        if (pdev->w1_count > 1)
 298                ds2482_set_channel(pdev, pchan->channel);
 299
 300        /* Send the triplet command, wait until 1WB == 0, return the status */
 301        if (!ds2482_send_cmd_data(pdev, DS2482_CMD_1WIRE_TRIPLET,
 302                                  dbit ? 0xFF : 0))
 303                status = ds2482_wait_1wire_idle(pdev);
 304
 305        mutex_unlock(&pdev->access_lock);
 306
 307        /* Decode the status */
 308        return (status >> 5);
 309}
 310
 311/**
 312 * Performs the write byte function.
 313 *
 314 * @param data  The ds2482 channel pointer
 315 * @param byte  The value to write
 316 */
 317static void ds2482_w1_write_byte(void *data, u8 byte)
 318{
 319        struct ds2482_w1_chan *pchan = data;
 320        struct ds2482_data    *pdev = pchan->pdev;
 321
 322        mutex_lock(&pdev->access_lock);
 323
 324        /* Select the channel */
 325        ds2482_wait_1wire_idle(pdev);
 326        if (pdev->w1_count > 1)
 327                ds2482_set_channel(pdev, pchan->channel);
 328
 329        /* Send the write byte command */
 330        ds2482_send_cmd_data(pdev, DS2482_CMD_1WIRE_WRITE_BYTE, byte);
 331
 332        mutex_unlock(&pdev->access_lock);
 333}
 334
 335/**
 336 * Performs the read byte function.
 337 *
 338 * @param data  The ds2482 channel pointer
 339 * @return      The value read
 340 */
 341static u8 ds2482_w1_read_byte(void *data)
 342{
 343        struct ds2482_w1_chan *pchan = data;
 344        struct ds2482_data    *pdev = pchan->pdev;
 345        int result;
 346
 347        mutex_lock(&pdev->access_lock);
 348
 349        /* Select the channel */
 350        ds2482_wait_1wire_idle(pdev);
 351        if (pdev->w1_count > 1)
 352                ds2482_set_channel(pdev, pchan->channel);
 353
 354        /* Send the read byte command */
 355        ds2482_send_cmd(pdev, DS2482_CMD_1WIRE_READ_BYTE);
 356
 357        /* Wait until 1WB == 0 */
 358        ds2482_wait_1wire_idle(pdev);
 359
 360        /* Select the data register */
 361        ds2482_select_register(pdev, DS2482_PTR_CODE_DATA);
 362
 363        /* Read the data byte */
 364        result = i2c_smbus_read_byte(pdev->client);
 365
 366        mutex_unlock(&pdev->access_lock);
 367
 368        return result;
 369}
 370
 371
 372/**
 373 * Sends a reset on the 1-wire interface
 374 *
 375 * @param data  The ds2482 channel pointer
 376 * @return      0=Device present, 1=No device present or error
 377 */
 378static u8 ds2482_w1_reset_bus(void *data)
 379{
 380        struct ds2482_w1_chan *pchan = data;
 381        struct ds2482_data    *pdev = pchan->pdev;
 382        int err;
 383        u8 retval = 1;
 384
 385        mutex_lock(&pdev->access_lock);
 386
 387        /* Select the channel */
 388        ds2482_wait_1wire_idle(pdev);
 389        if (pdev->w1_count > 1)
 390                ds2482_set_channel(pdev, pchan->channel);
 391
 392        /* Send the reset command */
 393        err = ds2482_send_cmd(pdev, DS2482_CMD_1WIRE_RESET);
 394        if (err >= 0) {
 395                /* Wait until the reset is complete */
 396                err = ds2482_wait_1wire_idle(pdev);
 397                retval = !(err & DS2482_REG_STS_PPD);
 398
 399                /* If the chip did reset since detect, re-config it */
 400                if (err & DS2482_REG_STS_RST)
 401                        ds2482_send_cmd_data(pdev, DS2482_CMD_WRITE_CONFIG,
 402                                             0xF0);
 403        }
 404
 405        mutex_unlock(&pdev->access_lock);
 406
 407        return retval;
 408}
 409
 410
 411static int ds2482_probe(struct i2c_client *client,
 412                        const struct i2c_device_id *id)
 413{
 414        struct ds2482_data *data;
 415        int err = -ENODEV;
 416        int temp1;
 417        int idx;
 418
 419        if (!i2c_check_functionality(client->adapter,
 420                                     I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
 421                                     I2C_FUNC_SMBUS_BYTE))
 422                return -ENODEV;
 423
 424        if (!(data = kzalloc(sizeof(struct ds2482_data), GFP_KERNEL))) {
 425                err = -ENOMEM;
 426                goto exit;
 427        }
 428
 429        data->client = client;
 430        i2c_set_clientdata(client, data);
 431
 432        /* Reset the device (sets the read_ptr to status) */
 433        if (ds2482_send_cmd(data, DS2482_CMD_RESET) < 0) {
 434                dev_warn(&client->dev, "DS2482 reset failed.\n");
 435                goto exit_free;
 436        }
 437
 438        /* Sleep at least 525ns to allow the reset to complete */
 439        ndelay(525);
 440
 441        /* Read the status byte - only reset bit and line should be set */
 442        temp1 = i2c_smbus_read_byte(client);
 443        if (temp1 != (DS2482_REG_STS_LL | DS2482_REG_STS_RST)) {
 444                dev_warn(&client->dev, "DS2482 reset status "
 445                         "0x%02X - not a DS2482\n", temp1);
 446                goto exit_free;
 447        }
 448
 449        /* Detect the 8-port version */
 450        data->w1_count = 1;
 451        if (ds2482_set_channel(data, 7) == 0)
 452                data->w1_count = 8;
 453
 454        /* Set all config items to 0 (off) */
 455        ds2482_send_cmd_data(data, DS2482_CMD_WRITE_CONFIG, 0xF0);
 456
 457        mutex_init(&data->access_lock);
 458
 459        /* Register 1-wire interface(s) */
 460        for (idx = 0; idx < data->w1_count; idx++) {
 461                data->w1_ch[idx].pdev = data;
 462                data->w1_ch[idx].channel = idx;
 463
 464                /* Populate all the w1 bus master stuff */
 465                data->w1_ch[idx].w1_bm.data       = &data->w1_ch[idx];
 466                data->w1_ch[idx].w1_bm.read_byte  = ds2482_w1_read_byte;
 467                data->w1_ch[idx].w1_bm.write_byte = ds2482_w1_write_byte;
 468                data->w1_ch[idx].w1_bm.touch_bit  = ds2482_w1_touch_bit;
 469                data->w1_ch[idx].w1_bm.triplet    = ds2482_w1_triplet;
 470                data->w1_ch[idx].w1_bm.reset_bus  = ds2482_w1_reset_bus;
 471
 472                err = w1_add_master_device(&data->w1_ch[idx].w1_bm);
 473                if (err) {
 474                        data->w1_ch[idx].pdev = NULL;
 475                        goto exit_w1_remove;
 476                }
 477        }
 478
 479        return 0;
 480
 481exit_w1_remove:
 482        for (idx = 0; idx < data->w1_count; idx++) {
 483                if (data->w1_ch[idx].pdev != NULL)
 484                        w1_remove_master_device(&data->w1_ch[idx].w1_bm);
 485        }
 486exit_free:
 487        kfree(data);
 488exit:
 489        return err;
 490}
 491
 492static int ds2482_remove(struct i2c_client *client)
 493{
 494        struct ds2482_data   *data = i2c_get_clientdata(client);
 495        int idx;
 496
 497        /* Unregister the 1-wire bridge(s) */
 498        for (idx = 0; idx < data->w1_count; idx++) {
 499                if (data->w1_ch[idx].pdev != NULL)
 500                        w1_remove_master_device(&data->w1_ch[idx].w1_bm);
 501        }
 502
 503        /* Free the memory */
 504        kfree(data);
 505        return 0;
 506}
 507
 508static int __init sensors_ds2482_init(void)
 509{
 510        return i2c_add_driver(&ds2482_driver);
 511}
 512
 513static void __exit sensors_ds2482_exit(void)
 514{
 515        i2c_del_driver(&ds2482_driver);
 516}
 517
 518MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>");
 519MODULE_DESCRIPTION("DS2482 driver");
 520MODULE_LICENSE("GPL");
 521
 522module_init(sensors_ds2482_init);
 523module_exit(sensors_ds2482_exit);
 524