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