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