linux/drivers/misc/ad525x_dpot.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * ad525x_dpot: Driver for the Analog Devices digital potentiometers
   4 * Copyright (c) 2009-2010 Analog Devices, Inc.
   5 * Author: Michael Hennerich <michael.hennerich@analog.com>
   6 *
   7 * DEVID                #Wipers         #Positions      Resistor Options (kOhm)
   8 * AD5258               1               64              1, 10, 50, 100
   9 * AD5259               1               256             5, 10, 50, 100
  10 * AD5251               2               64              1, 10, 50, 100
  11 * AD5252               2               256             1, 10, 50, 100
  12 * AD5255               3               512             25, 250
  13 * AD5253               4               64              1, 10, 50, 100
  14 * AD5254               4               256             1, 10, 50, 100
  15 * AD5160               1               256             5, 10, 50, 100
  16 * AD5161               1               256             5, 10, 50, 100
  17 * AD5162               2               256             2.5, 10, 50, 100
  18 * AD5165               1               256             100
  19 * AD5200               1               256             10, 50
  20 * AD5201               1               33              10, 50
  21 * AD5203               4               64              10, 100
  22 * AD5204               4               256             10, 50, 100
  23 * AD5206               6               256             10, 50, 100
  24 * AD5207               2               256             10, 50, 100
  25 * AD5231               1               1024            10, 50, 100
  26 * AD5232               2               256             10, 50, 100
  27 * AD5233               4               64              10, 50, 100
  28 * AD5235               2               1024            25, 250
  29 * AD5260               1               256             20, 50, 200
  30 * AD5262               2               256             20, 50, 200
  31 * AD5263               4               256             20, 50, 200
  32 * AD5290               1               256             10, 50, 100
  33 * AD5291               1               256             20, 50, 100  (20-TP)
  34 * AD5292               1               1024            20, 50, 100  (20-TP)
  35 * AD5293               1               1024            20, 50, 100
  36 * AD7376               1               128             10, 50, 100, 1M
  37 * AD8400               1               256             1, 10, 50, 100
  38 * AD8402               2               256             1, 10, 50, 100
  39 * AD8403               4               256             1, 10, 50, 100
  40 * ADN2850              3               512             25, 250
  41 * AD5241               1               256             10, 100, 1M
  42 * AD5246               1               128             5, 10, 50, 100
  43 * AD5247               1               128             5, 10, 50, 100
  44 * AD5245               1               256             5, 10, 50, 100
  45 * AD5243               2               256             2.5, 10, 50, 100
  46 * AD5248               2               256             2.5, 10, 50, 100
  47 * AD5242               2               256             20, 50, 200
  48 * AD5280               1               256             20, 50, 200
  49 * AD5282               2               256             20, 50, 200
  50 * ADN2860              3               512             25, 250
  51 * AD5273               1               64              1, 10, 50, 100 (OTP)
  52 * AD5171               1               64              5, 10, 50, 100 (OTP)
  53 * AD5170               1               256             2.5, 10, 50, 100 (OTP)
  54 * AD5172               2               256             2.5, 10, 50, 100 (OTP)
  55 * AD5173               2               256             2.5, 10, 50, 100 (OTP)
  56 * AD5270               1               1024            20, 50, 100 (50-TP)
  57 * AD5271               1               256             20, 50, 100 (50-TP)
  58 * AD5272               1               1024            20, 50, 100 (50-TP)
  59 * AD5274               1               256             20, 50, 100 (50-TP)
  60 *
  61 * See Documentation/misc-devices/ad525x_dpot.txt for more info.
  62 *
  63 * derived from ad5258.c
  64 * Copyright (c) 2009 Cyber Switching, Inc.
  65 * Author: Chris Verges <chrisv@cyberswitching.com>
  66 *
  67 * derived from ad5252.c
  68 * Copyright (c) 2006-2011 Michael Hennerich <michael.hennerich@analog.com>
  69 */
  70
  71#include <linux/module.h>
  72#include <linux/device.h>
  73#include <linux/kernel.h>
  74#include <linux/delay.h>
  75#include <linux/slab.h>
  76
  77#include "ad525x_dpot.h"
  78
  79/*
  80 * Client data (each client gets its own)
  81 */
  82
  83struct dpot_data {
  84        struct ad_dpot_bus_data bdata;
  85        struct mutex update_lock;
  86        unsigned int rdac_mask;
  87        unsigned int max_pos;
  88        unsigned long devid;
  89        unsigned int uid;
  90        unsigned int feat;
  91        unsigned int wipers;
  92        u16 rdac_cache[MAX_RDACS];
  93        DECLARE_BITMAP(otp_en_mask, MAX_RDACS);
  94};
  95
  96static inline int dpot_read_d8(struct dpot_data *dpot)
  97{
  98        return dpot->bdata.bops->read_d8(dpot->bdata.client);
  99}
 100
 101static inline int dpot_read_r8d8(struct dpot_data *dpot, u8 reg)
 102{
 103        return dpot->bdata.bops->read_r8d8(dpot->bdata.client, reg);
 104}
 105
 106static inline int dpot_read_r8d16(struct dpot_data *dpot, u8 reg)
 107{
 108        return dpot->bdata.bops->read_r8d16(dpot->bdata.client, reg);
 109}
 110
 111static inline int dpot_write_d8(struct dpot_data *dpot, u8 val)
 112{
 113        return dpot->bdata.bops->write_d8(dpot->bdata.client, val);
 114}
 115
 116static inline int dpot_write_r8d8(struct dpot_data *dpot, u8 reg, u16 val)
 117{
 118        return dpot->bdata.bops->write_r8d8(dpot->bdata.client, reg, val);
 119}
 120
 121static inline int dpot_write_r8d16(struct dpot_data *dpot, u8 reg, u16 val)
 122{
 123        return dpot->bdata.bops->write_r8d16(dpot->bdata.client, reg, val);
 124}
 125
 126static s32 dpot_read_spi(struct dpot_data *dpot, u8 reg)
 127{
 128        unsigned int ctrl = 0;
 129        int value;
 130
 131        if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD))) {
 132
 133                if (dpot->feat & F_RDACS_WONLY)
 134                        return dpot->rdac_cache[reg & DPOT_RDAC_MASK];
 135                if (dpot->uid == DPOT_UID(AD5291_ID) ||
 136                        dpot->uid == DPOT_UID(AD5292_ID) ||
 137                        dpot->uid == DPOT_UID(AD5293_ID)) {
 138
 139                        value = dpot_read_r8d8(dpot,
 140                                DPOT_AD5291_READ_RDAC << 2);
 141
 142                        if (dpot->uid == DPOT_UID(AD5291_ID))
 143                                value = value >> 2;
 144
 145                        return value;
 146                } else if (dpot->uid == DPOT_UID(AD5270_ID) ||
 147                        dpot->uid == DPOT_UID(AD5271_ID)) {
 148
 149                        value = dpot_read_r8d8(dpot,
 150                                DPOT_AD5270_1_2_4_READ_RDAC << 2);
 151
 152                        if (value < 0)
 153                                return value;
 154
 155                        if (dpot->uid == DPOT_UID(AD5271_ID))
 156                                value = value >> 2;
 157
 158                        return value;
 159                }
 160
 161                ctrl = DPOT_SPI_READ_RDAC;
 162        } else if (reg & DPOT_ADDR_EEPROM) {
 163                ctrl = DPOT_SPI_READ_EEPROM;
 164        }
 165
 166        if (dpot->feat & F_SPI_16BIT)
 167                return dpot_read_r8d8(dpot, ctrl);
 168        else if (dpot->feat & F_SPI_24BIT)
 169                return dpot_read_r8d16(dpot, ctrl);
 170
 171        return -EFAULT;
 172}
 173
 174static s32 dpot_read_i2c(struct dpot_data *dpot, u8 reg)
 175{
 176        int value;
 177        unsigned int ctrl = 0;
 178
 179        switch (dpot->uid) {
 180        case DPOT_UID(AD5246_ID):
 181        case DPOT_UID(AD5247_ID):
 182                return dpot_read_d8(dpot);
 183        case DPOT_UID(AD5245_ID):
 184        case DPOT_UID(AD5241_ID):
 185        case DPOT_UID(AD5242_ID):
 186        case DPOT_UID(AD5243_ID):
 187        case DPOT_UID(AD5248_ID):
 188        case DPOT_UID(AD5280_ID):
 189        case DPOT_UID(AD5282_ID):
 190                ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
 191                        0 : DPOT_AD5282_RDAC_AB;
 192                return dpot_read_r8d8(dpot, ctrl);
 193        case DPOT_UID(AD5170_ID):
 194        case DPOT_UID(AD5171_ID):
 195        case DPOT_UID(AD5273_ID):
 196                        return dpot_read_d8(dpot);
 197        case DPOT_UID(AD5172_ID):
 198        case DPOT_UID(AD5173_ID):
 199                ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
 200                        0 : DPOT_AD5172_3_A0;
 201                return dpot_read_r8d8(dpot, ctrl);
 202        case DPOT_UID(AD5272_ID):
 203        case DPOT_UID(AD5274_ID):
 204                dpot_write_r8d8(dpot,
 205                                (DPOT_AD5270_1_2_4_READ_RDAC << 2), 0);
 206
 207                value = dpot_read_r8d16(dpot, DPOT_AD5270_1_2_4_RDAC << 2);
 208                if (value < 0)
 209                        return value;
 210                /*
 211                 * AD5272/AD5274 returns high byte first, however
 212                 * underling smbus expects low byte first.
 213                 */
 214                value = swab16(value);
 215
 216                if (dpot->uid == DPOT_UID(AD5274_ID))
 217                        value = value >> 2;
 218                return value;
 219        default:
 220                if ((reg & DPOT_REG_TOL) || (dpot->max_pos > 256))
 221                        return dpot_read_r8d16(dpot, (reg & 0xF8) |
 222                                        ((reg & 0x7) << 1));
 223                else
 224                        return dpot_read_r8d8(dpot, reg);
 225        }
 226}
 227
 228static s32 dpot_read(struct dpot_data *dpot, u8 reg)
 229{
 230        if (dpot->feat & F_SPI)
 231                return dpot_read_spi(dpot, reg);
 232        else
 233                return dpot_read_i2c(dpot, reg);
 234}
 235
 236static s32 dpot_write_spi(struct dpot_data *dpot, u8 reg, u16 value)
 237{
 238        unsigned int val = 0;
 239
 240        if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD | DPOT_ADDR_OTP))) {
 241                if (dpot->feat & F_RDACS_WONLY)
 242                        dpot->rdac_cache[reg & DPOT_RDAC_MASK] = value;
 243
 244                if (dpot->feat & F_AD_APPDATA) {
 245                        if (dpot->feat & F_SPI_8BIT) {
 246                                val = ((reg & DPOT_RDAC_MASK) <<
 247                                        DPOT_MAX_POS(dpot->devid)) |
 248                                        value;
 249                                return dpot_write_d8(dpot, val);
 250                        } else if (dpot->feat & F_SPI_16BIT) {
 251                                val = ((reg & DPOT_RDAC_MASK) <<
 252                                        DPOT_MAX_POS(dpot->devid)) |
 253                                        value;
 254                                return dpot_write_r8d8(dpot, val >> 8,
 255                                        val & 0xFF);
 256                        } else
 257                                BUG();
 258                } else {
 259                        if (dpot->uid == DPOT_UID(AD5291_ID) ||
 260                                dpot->uid == DPOT_UID(AD5292_ID) ||
 261                                dpot->uid == DPOT_UID(AD5293_ID)) {
 262
 263                                dpot_write_r8d8(dpot, DPOT_AD5291_CTRLREG << 2,
 264                                                DPOT_AD5291_UNLOCK_CMD);
 265
 266                                if (dpot->uid == DPOT_UID(AD5291_ID))
 267                                        value = value << 2;
 268
 269                                return dpot_write_r8d8(dpot,
 270                                        (DPOT_AD5291_RDAC << 2) |
 271                                        (value >> 8), value & 0xFF);
 272                        } else if (dpot->uid == DPOT_UID(AD5270_ID) ||
 273                                dpot->uid == DPOT_UID(AD5271_ID)) {
 274                                dpot_write_r8d8(dpot,
 275                                                DPOT_AD5270_1_2_4_CTRLREG << 2,
 276                                                DPOT_AD5270_1_2_4_UNLOCK_CMD);
 277
 278                                if (dpot->uid == DPOT_UID(AD5271_ID))
 279                                        value = value << 2;
 280
 281                                return dpot_write_r8d8(dpot,
 282                                        (DPOT_AD5270_1_2_4_RDAC << 2) |
 283                                        (value >> 8), value & 0xFF);
 284                        }
 285                        val = DPOT_SPI_RDAC | (reg & DPOT_RDAC_MASK);
 286                }
 287        } else if (reg & DPOT_ADDR_EEPROM) {
 288                val = DPOT_SPI_EEPROM | (reg & DPOT_RDAC_MASK);
 289        } else if (reg & DPOT_ADDR_CMD) {
 290                switch (reg) {
 291                case DPOT_DEC_ALL_6DB:
 292                        val = DPOT_SPI_DEC_ALL_6DB;
 293                        break;
 294                case DPOT_INC_ALL_6DB:
 295                        val = DPOT_SPI_INC_ALL_6DB;
 296                        break;
 297                case DPOT_DEC_ALL:
 298                        val = DPOT_SPI_DEC_ALL;
 299                        break;
 300                case DPOT_INC_ALL:
 301                        val = DPOT_SPI_INC_ALL;
 302                        break;
 303                }
 304        } else if (reg & DPOT_ADDR_OTP) {
 305                if (dpot->uid == DPOT_UID(AD5291_ID) ||
 306                        dpot->uid == DPOT_UID(AD5292_ID)) {
 307                        return dpot_write_r8d8(dpot,
 308                                DPOT_AD5291_STORE_XTPM << 2, 0);
 309                } else if (dpot->uid == DPOT_UID(AD5270_ID) ||
 310                        dpot->uid == DPOT_UID(AD5271_ID)) {
 311                        return dpot_write_r8d8(dpot,
 312                                DPOT_AD5270_1_2_4_STORE_XTPM << 2, 0);
 313                }
 314        } else
 315                BUG();
 316
 317        if (dpot->feat & F_SPI_16BIT)
 318                return dpot_write_r8d8(dpot, val, value);
 319        else if (dpot->feat & F_SPI_24BIT)
 320                return dpot_write_r8d16(dpot, val, value);
 321
 322        return -EFAULT;
 323}
 324
 325static s32 dpot_write_i2c(struct dpot_data *dpot, u8 reg, u16 value)
 326{
 327        /* Only write the instruction byte for certain commands */
 328        unsigned int tmp = 0, ctrl = 0;
 329
 330        switch (dpot->uid) {
 331        case DPOT_UID(AD5246_ID):
 332        case DPOT_UID(AD5247_ID):
 333                return dpot_write_d8(dpot, value);
 334
 335        case DPOT_UID(AD5245_ID):
 336        case DPOT_UID(AD5241_ID):
 337        case DPOT_UID(AD5242_ID):
 338        case DPOT_UID(AD5243_ID):
 339        case DPOT_UID(AD5248_ID):
 340        case DPOT_UID(AD5280_ID):
 341        case DPOT_UID(AD5282_ID):
 342                ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
 343                        0 : DPOT_AD5282_RDAC_AB;
 344                return dpot_write_r8d8(dpot, ctrl, value);
 345        case DPOT_UID(AD5171_ID):
 346        case DPOT_UID(AD5273_ID):
 347                if (reg & DPOT_ADDR_OTP) {
 348                        tmp = dpot_read_d8(dpot);
 349                        if (tmp >> 6) /* Ready to Program? */
 350                                return -EFAULT;
 351                        ctrl = DPOT_AD5273_FUSE;
 352                }
 353                return dpot_write_r8d8(dpot, ctrl, value);
 354        case DPOT_UID(AD5172_ID):
 355        case DPOT_UID(AD5173_ID):
 356                ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
 357                        0 : DPOT_AD5172_3_A0;
 358                if (reg & DPOT_ADDR_OTP) {
 359                        tmp = dpot_read_r8d16(dpot, ctrl);
 360                        if (tmp >> 14) /* Ready to Program? */
 361                                return -EFAULT;
 362                        ctrl |= DPOT_AD5170_2_3_FUSE;
 363                }
 364                return dpot_write_r8d8(dpot, ctrl, value);
 365        case DPOT_UID(AD5170_ID):
 366                if (reg & DPOT_ADDR_OTP) {
 367                        tmp = dpot_read_r8d16(dpot, tmp);
 368                        if (tmp >> 14) /* Ready to Program? */
 369                                return -EFAULT;
 370                        ctrl = DPOT_AD5170_2_3_FUSE;
 371                }
 372                return dpot_write_r8d8(dpot, ctrl, value);
 373        case DPOT_UID(AD5272_ID):
 374        case DPOT_UID(AD5274_ID):
 375                dpot_write_r8d8(dpot, DPOT_AD5270_1_2_4_CTRLREG << 2,
 376                                DPOT_AD5270_1_2_4_UNLOCK_CMD);
 377
 378                if (reg & DPOT_ADDR_OTP)
 379                        return dpot_write_r8d8(dpot,
 380                                        DPOT_AD5270_1_2_4_STORE_XTPM << 2, 0);
 381
 382                if (dpot->uid == DPOT_UID(AD5274_ID))
 383                        value = value << 2;
 384
 385                return dpot_write_r8d8(dpot, (DPOT_AD5270_1_2_4_RDAC << 2) |
 386                                       (value >> 8), value & 0xFF);
 387        default:
 388                if (reg & DPOT_ADDR_CMD)
 389                        return dpot_write_d8(dpot, reg);
 390
 391                if (dpot->max_pos > 256)
 392                        return dpot_write_r8d16(dpot, (reg & 0xF8) |
 393                                                ((reg & 0x7) << 1), value);
 394                else
 395                        /* All other registers require instruction + data bytes */
 396                        return dpot_write_r8d8(dpot, reg, value);
 397        }
 398}
 399
 400static s32 dpot_write(struct dpot_data *dpot, u8 reg, u16 value)
 401{
 402        if (dpot->feat & F_SPI)
 403                return dpot_write_spi(dpot, reg, value);
 404        else
 405                return dpot_write_i2c(dpot, reg, value);
 406}
 407
 408/* sysfs functions */
 409
 410static ssize_t sysfs_show_reg(struct device *dev,
 411                              struct device_attribute *attr,
 412                              char *buf, u32 reg)
 413{
 414        struct dpot_data *data = dev_get_drvdata(dev);
 415        s32 value;
 416
 417        if (reg & DPOT_ADDR_OTP_EN)
 418                return sprintf(buf, "%s\n",
 419                        test_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask) ?
 420                        "enabled" : "disabled");
 421
 422
 423        mutex_lock(&data->update_lock);
 424        value = dpot_read(data, reg);
 425        mutex_unlock(&data->update_lock);
 426
 427        if (value < 0)
 428                return -EINVAL;
 429        /*
 430         * Let someone else deal with converting this ...
 431         * the tolerance is a two-byte value where the MSB
 432         * is a sign + integer value, and the LSB is a
 433         * decimal value.  See page 18 of the AD5258
 434         * datasheet (Rev. A) for more details.
 435         */
 436
 437        if (reg & DPOT_REG_TOL)
 438                return sprintf(buf, "0x%04x\n", value & 0xFFFF);
 439        else
 440                return sprintf(buf, "%u\n", value & data->rdac_mask);
 441}
 442
 443static ssize_t sysfs_set_reg(struct device *dev,
 444                             struct device_attribute *attr,
 445                             const char *buf, size_t count, u32 reg)
 446{
 447        struct dpot_data *data = dev_get_drvdata(dev);
 448        unsigned long value;
 449        int err;
 450
 451        if (reg & DPOT_ADDR_OTP_EN) {
 452                if (sysfs_streq(buf, "enabled"))
 453                        set_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask);
 454                else
 455                        clear_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask);
 456
 457                return count;
 458        }
 459
 460        if ((reg & DPOT_ADDR_OTP) &&
 461                !test_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask))
 462                return -EPERM;
 463
 464        err = kstrtoul(buf, 10, &value);
 465        if (err)
 466                return err;
 467
 468        if (value > data->rdac_mask)
 469                value = data->rdac_mask;
 470
 471        mutex_lock(&data->update_lock);
 472        dpot_write(data, reg, value);
 473        if (reg & DPOT_ADDR_EEPROM)
 474                msleep(26);     /* Sleep while the EEPROM updates */
 475        else if (reg & DPOT_ADDR_OTP)
 476                msleep(400);    /* Sleep while the OTP updates */
 477        mutex_unlock(&data->update_lock);
 478
 479        return count;
 480}
 481
 482static ssize_t sysfs_do_cmd(struct device *dev,
 483                            struct device_attribute *attr,
 484                            const char *buf, size_t count, u32 reg)
 485{
 486        struct dpot_data *data = dev_get_drvdata(dev);
 487
 488        mutex_lock(&data->update_lock);
 489        dpot_write(data, reg, 0);
 490        mutex_unlock(&data->update_lock);
 491
 492        return count;
 493}
 494
 495/* ------------------------------------------------------------------------- */
 496
 497#define DPOT_DEVICE_SHOW(_name, _reg) static ssize_t \
 498show_##_name(struct device *dev, \
 499                          struct device_attribute *attr, char *buf) \
 500{ \
 501        return sysfs_show_reg(dev, attr, buf, _reg); \
 502}
 503
 504#define DPOT_DEVICE_SET(_name, _reg) static ssize_t \
 505set_##_name(struct device *dev, \
 506                         struct device_attribute *attr, \
 507                         const char *buf, size_t count) \
 508{ \
 509        return sysfs_set_reg(dev, attr, buf, count, _reg); \
 510}
 511
 512#define DPOT_DEVICE_SHOW_SET(name, reg) \
 513DPOT_DEVICE_SHOW(name, reg) \
 514DPOT_DEVICE_SET(name, reg) \
 515static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, set_##name)
 516
 517#define DPOT_DEVICE_SHOW_ONLY(name, reg) \
 518DPOT_DEVICE_SHOW(name, reg) \
 519static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, NULL)
 520
 521DPOT_DEVICE_SHOW_SET(rdac0, DPOT_ADDR_RDAC | DPOT_RDAC0);
 522DPOT_DEVICE_SHOW_SET(eeprom0, DPOT_ADDR_EEPROM | DPOT_RDAC0);
 523DPOT_DEVICE_SHOW_ONLY(tolerance0, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC0);
 524DPOT_DEVICE_SHOW_SET(otp0, DPOT_ADDR_OTP | DPOT_RDAC0);
 525DPOT_DEVICE_SHOW_SET(otp0en, DPOT_ADDR_OTP_EN | DPOT_RDAC0);
 526
 527DPOT_DEVICE_SHOW_SET(rdac1, DPOT_ADDR_RDAC | DPOT_RDAC1);
 528DPOT_DEVICE_SHOW_SET(eeprom1, DPOT_ADDR_EEPROM | DPOT_RDAC1);
 529DPOT_DEVICE_SHOW_ONLY(tolerance1, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC1);
 530DPOT_DEVICE_SHOW_SET(otp1, DPOT_ADDR_OTP | DPOT_RDAC1);
 531DPOT_DEVICE_SHOW_SET(otp1en, DPOT_ADDR_OTP_EN | DPOT_RDAC1);
 532
 533DPOT_DEVICE_SHOW_SET(rdac2, DPOT_ADDR_RDAC | DPOT_RDAC2);
 534DPOT_DEVICE_SHOW_SET(eeprom2, DPOT_ADDR_EEPROM | DPOT_RDAC2);
 535DPOT_DEVICE_SHOW_ONLY(tolerance2, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC2);
 536DPOT_DEVICE_SHOW_SET(otp2, DPOT_ADDR_OTP | DPOT_RDAC2);
 537DPOT_DEVICE_SHOW_SET(otp2en, DPOT_ADDR_OTP_EN | DPOT_RDAC2);
 538
 539DPOT_DEVICE_SHOW_SET(rdac3, DPOT_ADDR_RDAC | DPOT_RDAC3);
 540DPOT_DEVICE_SHOW_SET(eeprom3, DPOT_ADDR_EEPROM | DPOT_RDAC3);
 541DPOT_DEVICE_SHOW_ONLY(tolerance3, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC3);
 542DPOT_DEVICE_SHOW_SET(otp3, DPOT_ADDR_OTP | DPOT_RDAC3);
 543DPOT_DEVICE_SHOW_SET(otp3en, DPOT_ADDR_OTP_EN | DPOT_RDAC3);
 544
 545DPOT_DEVICE_SHOW_SET(rdac4, DPOT_ADDR_RDAC | DPOT_RDAC4);
 546DPOT_DEVICE_SHOW_SET(eeprom4, DPOT_ADDR_EEPROM | DPOT_RDAC4);
 547DPOT_DEVICE_SHOW_ONLY(tolerance4, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC4);
 548DPOT_DEVICE_SHOW_SET(otp4, DPOT_ADDR_OTP | DPOT_RDAC4);
 549DPOT_DEVICE_SHOW_SET(otp4en, DPOT_ADDR_OTP_EN | DPOT_RDAC4);
 550
 551DPOT_DEVICE_SHOW_SET(rdac5, DPOT_ADDR_RDAC | DPOT_RDAC5);
 552DPOT_DEVICE_SHOW_SET(eeprom5, DPOT_ADDR_EEPROM | DPOT_RDAC5);
 553DPOT_DEVICE_SHOW_ONLY(tolerance5, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC5);
 554DPOT_DEVICE_SHOW_SET(otp5, DPOT_ADDR_OTP | DPOT_RDAC5);
 555DPOT_DEVICE_SHOW_SET(otp5en, DPOT_ADDR_OTP_EN | DPOT_RDAC5);
 556
 557static const struct attribute *dpot_attrib_wipers[] = {
 558        &dev_attr_rdac0.attr,
 559        &dev_attr_rdac1.attr,
 560        &dev_attr_rdac2.attr,
 561        &dev_attr_rdac3.attr,
 562        &dev_attr_rdac4.attr,
 563        &dev_attr_rdac5.attr,
 564        NULL
 565};
 566
 567static const struct attribute *dpot_attrib_eeprom[] = {
 568        &dev_attr_eeprom0.attr,
 569        &dev_attr_eeprom1.attr,
 570        &dev_attr_eeprom2.attr,
 571        &dev_attr_eeprom3.attr,
 572        &dev_attr_eeprom4.attr,
 573        &dev_attr_eeprom5.attr,
 574        NULL
 575};
 576
 577static const struct attribute *dpot_attrib_otp[] = {
 578        &dev_attr_otp0.attr,
 579        &dev_attr_otp1.attr,
 580        &dev_attr_otp2.attr,
 581        &dev_attr_otp3.attr,
 582        &dev_attr_otp4.attr,
 583        &dev_attr_otp5.attr,
 584        NULL
 585};
 586
 587static const struct attribute *dpot_attrib_otp_en[] = {
 588        &dev_attr_otp0en.attr,
 589        &dev_attr_otp1en.attr,
 590        &dev_attr_otp2en.attr,
 591        &dev_attr_otp3en.attr,
 592        &dev_attr_otp4en.attr,
 593        &dev_attr_otp5en.attr,
 594        NULL
 595};
 596
 597static const struct attribute *dpot_attrib_tolerance[] = {
 598        &dev_attr_tolerance0.attr,
 599        &dev_attr_tolerance1.attr,
 600        &dev_attr_tolerance2.attr,
 601        &dev_attr_tolerance3.attr,
 602        &dev_attr_tolerance4.attr,
 603        &dev_attr_tolerance5.attr,
 604        NULL
 605};
 606
 607/* ------------------------------------------------------------------------- */
 608
 609#define DPOT_DEVICE_DO_CMD(_name, _cmd) static ssize_t \
 610set_##_name(struct device *dev, \
 611                         struct device_attribute *attr, \
 612                         const char *buf, size_t count) \
 613{ \
 614        return sysfs_do_cmd(dev, attr, buf, count, _cmd); \
 615} \
 616static DEVICE_ATTR(_name, S_IWUSR | S_IRUGO, NULL, set_##_name)
 617
 618DPOT_DEVICE_DO_CMD(inc_all, DPOT_INC_ALL);
 619DPOT_DEVICE_DO_CMD(dec_all, DPOT_DEC_ALL);
 620DPOT_DEVICE_DO_CMD(inc_all_6db, DPOT_INC_ALL_6DB);
 621DPOT_DEVICE_DO_CMD(dec_all_6db, DPOT_DEC_ALL_6DB);
 622
 623static struct attribute *ad525x_attributes_commands[] = {
 624        &dev_attr_inc_all.attr,
 625        &dev_attr_dec_all.attr,
 626        &dev_attr_inc_all_6db.attr,
 627        &dev_attr_dec_all_6db.attr,
 628        NULL
 629};
 630
 631static const struct attribute_group ad525x_group_commands = {
 632        .attrs = ad525x_attributes_commands,
 633};
 634
 635static int ad_dpot_add_files(struct device *dev,
 636                unsigned int features, unsigned int rdac)
 637{
 638        int err = sysfs_create_file(&dev->kobj,
 639                dpot_attrib_wipers[rdac]);
 640        if (features & F_CMD_EEP)
 641                err |= sysfs_create_file(&dev->kobj,
 642                        dpot_attrib_eeprom[rdac]);
 643        if (features & F_CMD_TOL)
 644                err |= sysfs_create_file(&dev->kobj,
 645                        dpot_attrib_tolerance[rdac]);
 646        if (features & F_CMD_OTP) {
 647                err |= sysfs_create_file(&dev->kobj,
 648                        dpot_attrib_otp_en[rdac]);
 649                err |= sysfs_create_file(&dev->kobj,
 650                        dpot_attrib_otp[rdac]);
 651        }
 652
 653        if (err)
 654                dev_err(dev, "failed to register sysfs hooks for RDAC%d\n",
 655                        rdac);
 656
 657        return err;
 658}
 659
 660static inline void ad_dpot_remove_files(struct device *dev,
 661                unsigned int features, unsigned int rdac)
 662{
 663        sysfs_remove_file(&dev->kobj,
 664                dpot_attrib_wipers[rdac]);
 665        if (features & F_CMD_EEP)
 666                sysfs_remove_file(&dev->kobj,
 667                        dpot_attrib_eeprom[rdac]);
 668        if (features & F_CMD_TOL)
 669                sysfs_remove_file(&dev->kobj,
 670                        dpot_attrib_tolerance[rdac]);
 671        if (features & F_CMD_OTP) {
 672                sysfs_remove_file(&dev->kobj,
 673                        dpot_attrib_otp_en[rdac]);
 674                sysfs_remove_file(&dev->kobj,
 675                        dpot_attrib_otp[rdac]);
 676        }
 677}
 678
 679int ad_dpot_probe(struct device *dev,
 680                struct ad_dpot_bus_data *bdata, unsigned long devid,
 681                            const char *name)
 682{
 683
 684        struct dpot_data *data;
 685        int i, err = 0;
 686
 687        data = kzalloc(sizeof(struct dpot_data), GFP_KERNEL);
 688        if (!data) {
 689                err = -ENOMEM;
 690                goto exit;
 691        }
 692
 693        dev_set_drvdata(dev, data);
 694        mutex_init(&data->update_lock);
 695
 696        data->bdata = *bdata;
 697        data->devid = devid;
 698
 699        data->max_pos = 1 << DPOT_MAX_POS(devid);
 700        data->rdac_mask = data->max_pos - 1;
 701        data->feat = DPOT_FEAT(devid);
 702        data->uid = DPOT_UID(devid);
 703        data->wipers = DPOT_WIPERS(devid);
 704
 705        for (i = DPOT_RDAC0; i < MAX_RDACS; i++)
 706                if (data->wipers & (1 << i)) {
 707                        err = ad_dpot_add_files(dev, data->feat, i);
 708                        if (err)
 709                                goto exit_remove_files;
 710                        /* power-up midscale */
 711                        if (data->feat & F_RDACS_WONLY)
 712                                data->rdac_cache[i] = data->max_pos / 2;
 713                }
 714
 715        if (data->feat & F_CMD_INC)
 716                err = sysfs_create_group(&dev->kobj, &ad525x_group_commands);
 717
 718        if (err) {
 719                dev_err(dev, "failed to register sysfs hooks\n");
 720                goto exit_free;
 721        }
 722
 723        dev_info(dev, "%s %d-Position Digital Potentiometer registered\n",
 724                 name, data->max_pos);
 725
 726        return 0;
 727
 728exit_remove_files:
 729        for (i = DPOT_RDAC0; i < MAX_RDACS; i++)
 730                if (data->wipers & (1 << i))
 731                        ad_dpot_remove_files(dev, data->feat, i);
 732
 733exit_free:
 734        kfree(data);
 735        dev_set_drvdata(dev, NULL);
 736exit:
 737        dev_err(dev, "failed to create client for %s ID 0x%lX\n",
 738                name, devid);
 739        return err;
 740}
 741EXPORT_SYMBOL(ad_dpot_probe);
 742
 743int ad_dpot_remove(struct device *dev)
 744{
 745        struct dpot_data *data = dev_get_drvdata(dev);
 746        int i;
 747
 748        for (i = DPOT_RDAC0; i < MAX_RDACS; i++)
 749                if (data->wipers & (1 << i))
 750                        ad_dpot_remove_files(dev, data->feat, i);
 751
 752        kfree(data);
 753
 754        return 0;
 755}
 756EXPORT_SYMBOL(ad_dpot_remove);
 757
 758
 759MODULE_AUTHOR("Chris Verges <chrisv@cyberswitching.com>, "
 760              "Michael Hennerich <michael.hennerich@analog.com>");
 761MODULE_DESCRIPTION("Digital potentiometer driver");
 762MODULE_LICENSE("GPL");
 763