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