Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: Break out ab5500 debugfs code

This breaks the debugfs portions of the AB5500 driver into its own
file. Split off a _raw function to access registers since we don't
want to expose a generically named function globally. Move all
required data structures to a shared ab5500-core.h file.

Cc: Mattias Wallin <mattias.wallin@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

authored by

Linus Walleij and committed by
Samuel Ortiz
94be70d4 b7ddac53

+941 -890
+8
drivers/mfd/Kconfig
··· 572 572 chip. This connects to the db5500 chip via the I2C bus via PRCMU. 573 573 This chip embeds various other multimedia funtionalities as well. 574 574 575 + config AB5500_DEBUG 576 + bool "Enable debug info via debugfs" 577 + depends on AB5500_CORE && DEBUG_FS 578 + default y if DEBUG_FS 579 + help 580 + Select this option if you want debug information from the AB5500 581 + using the debug filesystem, debugfs. 582 + 575 583 config AB8500_CORE 576 584 bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" 577 585 depends on GENERIC_HARDIRQS && ABX500_CORE
+1
drivers/mfd/Makefile
··· 81 81 obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o 82 82 obj-$(CONFIG_AB3550_CORE) += ab3550-core.o 83 83 obj-$(CONFIG_AB5500_CORE) += ab5500-core.o 84 + obj-$(CONFIG_AB5500_DEBUG) += ab5500-debugfs.o 84 85 obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o 85 86 obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o 86 87 obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o
+17 -890
drivers/mfd/ab5500-core.c
··· 21 21 #include <linux/irq.h> 22 22 #include <linux/interrupt.h> 23 23 #include <linux/random.h> 24 - #include <linux/debugfs.h> 25 - #include <linux/seq_file.h> 26 - #include <linux/uaccess.h> 27 24 #include <linux/mfd/ab5500/ab5500.h> 28 25 #include <linux/mfd/abx500.h> 29 26 #include <linux/list.h> ··· 30 33 #include <linux/version.h> 31 34 #include <linux/mfd/db5500-prcmu.h> 32 35 36 + #include "ab5500-core.h" 37 + #include "ab5500-debugfs.h" 38 + 33 39 #define AB5500_NUM_EVENT_REG 23 34 40 #define AB5500_IT_LATCH0_REG 0x40 35 41 #define AB5500_IT_MASK0_REG 0x60 36 - 37 - /* Read/write operation values. */ 38 - #define AB5500_PERM_RD (0x01) 39 - #define AB5500_PERM_WR (0x02) 40 - 41 - /* Read/write permissions. */ 42 - #define AB5500_PERM_RO (AB5500_PERM_RD) 43 - #define AB5500_PERM_RW (AB5500_PERM_RD | AB5500_PERM_WR) 44 - 45 - #define AB5500_MASK_BASE (0x60) 46 - #define AB5500_MASK_END (0x79) 47 - #define AB5500_CHIP_ID (0x20) 48 - 49 - /** 50 - * struct ab5500_bank 51 - * @slave_addr: I2C slave_addr found in AB5500 specification 52 - * @name: Documentation name of the bank. For reference 53 - */ 54 - struct ab5500_bank { 55 - u8 slave_addr; 56 - const char *name; 57 - }; 58 - 59 - static const struct ab5500_bank bankinfo[AB5500_NUM_BANKS] = { 60 - [AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP] = { 61 - AB5500_ADDR_VIT_IO_I2C_CLK_TST_OTP, "VIT_IO_I2C_CLK_TST_OTP"}, 62 - [AB5500_BANK_VDDDIG_IO_I2C_CLK_TST] = { 63 - AB5500_ADDR_VDDDIG_IO_I2C_CLK_TST, "VDDDIG_IO_I2C_CLK_TST"}, 64 - [AB5500_BANK_VDENC] = {AB5500_ADDR_VDENC, "VDENC"}, 65 - [AB5500_BANK_SIM_USBSIM] = {AB5500_ADDR_SIM_USBSIM, "SIM_USBSIM"}, 66 - [AB5500_BANK_LED] = {AB5500_ADDR_LED, "LED"}, 67 - [AB5500_BANK_ADC] = {AB5500_ADDR_ADC, "ADC"}, 68 - [AB5500_BANK_RTC] = {AB5500_ADDR_RTC, "RTC"}, 69 - [AB5500_BANK_STARTUP] = {AB5500_ADDR_STARTUP, "STARTUP"}, 70 - [AB5500_BANK_DBI_ECI] = {AB5500_ADDR_DBI_ECI, "DBI-ECI"}, 71 - [AB5500_BANK_CHG] = {AB5500_ADDR_CHG, "CHG"}, 72 - [AB5500_BANK_FG_BATTCOM_ACC] = { 73 - AB5500_ADDR_FG_BATTCOM_ACC, "FG_BATCOM_ACC"}, 74 - [AB5500_BANK_USB] = {AB5500_ADDR_USB, "USB"}, 75 - [AB5500_BANK_IT] = {AB5500_ADDR_IT, "IT"}, 76 - [AB5500_BANK_VIBRA] = {AB5500_ADDR_VIBRA, "VIBRA"}, 77 - [AB5500_BANK_AUDIO_HEADSETUSB] = { 78 - AB5500_ADDR_AUDIO_HEADSETUSB, "AUDIO_HEADSETUSB"}, 79 - }; 80 - 81 - /** 82 - * struct ab5500_reg_range 83 - * @first: the first address of the range 84 - * @last: the last address of the range 85 - * @perm: access permissions for the range 86 - */ 87 - struct ab5500_reg_range { 88 - u8 first; 89 - u8 last; 90 - u8 perm; 91 - }; 92 - 93 - /** 94 - * struct ab5500_i2c_ranges 95 - * @count: the number of ranges in the list 96 - * @range: the list of register ranges 97 - */ 98 - struct ab5500_i2c_ranges { 99 - u8 nranges; 100 - u8 bankid; 101 - const struct ab5500_reg_range *range; 102 - }; 103 - 104 - /** 105 - * struct ab5500_i2c_banks 106 - * @count: the number of ranges in the list 107 - * @range: the list of register ranges 108 - */ 109 - struct ab5500_i2c_banks { 110 - u8 nbanks; 111 - const struct ab5500_i2c_ranges *bank; 112 - }; 113 42 114 43 /* 115 44 * Permissible register ranges for reading and writing per device and bank. ··· 996 1073 /* 997 1074 * Functionality for getting/setting register values. 998 1075 */ 999 - static int get_register_interruptible(struct ab5500 *ab, u8 bank, u8 reg, 1000 - u8 *value) 1076 + int ab5500_get_register_interruptible_raw(struct ab5500 *ab, 1077 + u8 bank, u8 reg, 1078 + u8 *value) 1001 1079 { 1002 1080 int err; 1003 1081 ··· 1045 1121 return err; 1046 1122 } 1047 1123 1048 - static int mask_and_set_register_interruptible(struct ab5500 *ab, u8 bank, 1124 + int ab5500_mask_and_set_register_interruptible_raw(struct ab5500 *ab, u8 bank, 1049 1125 u8 reg, u8 bitmask, u8 bitvalues) 1050 1126 { 1051 1127 int err = 0; ··· 1082 1158 static int 1083 1159 set_register_interruptible(struct ab5500 *ab, u8 bank, u8 reg, u8 value) 1084 1160 { 1085 - return mask_and_set_register_interruptible(ab, bank, reg, 0xff, value); 1161 + return ab5500_mask_and_set_register_interruptible_raw(ab, bank, reg, 1162 + 0xff, value); 1086 1163 } 1087 1164 1088 1165 /* ··· 1186 1261 return -EINVAL; 1187 1262 1188 1263 ab = dev_get_drvdata(dev->parent); 1189 - return mask_and_set_register_interruptible(ab, bank, reg, 1264 + return ab5500_mask_and_set_register_interruptible_raw(ab, bank, reg, 1190 1265 bitmask, bitvalues); 1191 1266 } 1192 1267 ··· 1208 1283 return -EINVAL; 1209 1284 1210 1285 ab = dev_get_drvdata(dev->parent); 1211 - return get_register_interruptible(ab, bank, reg, value); 1286 + return ab5500_get_register_interruptible_raw(ab, bank, reg, value); 1212 1287 } 1213 1288 1214 1289 static int ab5500_get_register_page_interruptible(struct device *dev, u8 bank, ··· 1252 1327 .startup_irq_enabled = NULL, 1253 1328 }; 1254 1329 1255 - #ifdef CONFIG_DEBUG_FS 1256 - static struct ab5500_i2c_ranges ab5500_reg_ranges[AB5500_NUM_BANKS] = { 1257 - [AB5500_BANK_LED] = { 1258 - .bankid = AB5500_BANK_LED, 1259 - .nranges = 1, 1260 - .range = (struct ab5500_reg_range[]) { 1261 - { 1262 - .first = 0x00, 1263 - .last = 0x0C, 1264 - .perm = AB5500_PERM_RW, 1265 - }, 1266 - }, 1267 - }, 1268 - [AB5500_BANK_ADC] = { 1269 - .bankid = AB5500_BANK_ADC, 1270 - .nranges = 6, 1271 - .range = (struct ab5500_reg_range[]) { 1272 - { 1273 - .first = 0x1F, 1274 - .last = 0x22, 1275 - .perm = AB5500_PERM_RO, 1276 - }, 1277 - { 1278 - .first = 0x23, 1279 - .last = 0x24, 1280 - .perm = AB5500_PERM_RW, 1281 - }, 1282 - { 1283 - .first = 0x26, 1284 - .last = 0x2D, 1285 - .perm = AB5500_PERM_RO, 1286 - }, 1287 - { 1288 - .first = 0x2F, 1289 - .last = 0x34, 1290 - .perm = AB5500_PERM_RW, 1291 - }, 1292 - { 1293 - .first = 0x37, 1294 - .last = 0x57, 1295 - .perm = AB5500_PERM_RW, 1296 - }, 1297 - { 1298 - .first = 0x58, 1299 - .last = 0x58, 1300 - .perm = AB5500_PERM_RO, 1301 - }, 1302 - }, 1303 - }, 1304 - [AB5500_BANK_RTC] = { 1305 - .bankid = AB5500_BANK_RTC, 1306 - .nranges = 2, 1307 - .range = (struct ab5500_reg_range[]) { 1308 - { 1309 - .first = 0x00, 1310 - .last = 0x04, 1311 - .perm = AB5500_PERM_RW, 1312 - }, 1313 - { 1314 - .first = 0x06, 1315 - .last = 0x0C, 1316 - .perm = AB5500_PERM_RW, 1317 - }, 1318 - }, 1319 - }, 1320 - [AB5500_BANK_STARTUP] = { 1321 - .bankid = AB5500_BANK_STARTUP, 1322 - .nranges = 12, 1323 - .range = (struct ab5500_reg_range[]) { 1324 - { 1325 - .first = 0x00, 1326 - .last = 0x01, 1327 - .perm = AB5500_PERM_RW, 1328 - }, 1329 - { 1330 - .first = 0x1F, 1331 - .last = 0x1F, 1332 - .perm = AB5500_PERM_RW, 1333 - }, 1334 - { 1335 - .first = 0x2E, 1336 - .last = 0x2E, 1337 - .perm = AB5500_PERM_RO, 1338 - }, 1339 - { 1340 - .first = 0x2F, 1341 - .last = 0x30, 1342 - .perm = AB5500_PERM_RW, 1343 - }, 1344 - { 1345 - .first = 0x50, 1346 - .last = 0x51, 1347 - .perm = AB5500_PERM_RW, 1348 - }, 1349 - { 1350 - .first = 0x60, 1351 - .last = 0x61, 1352 - .perm = AB5500_PERM_RW, 1353 - }, 1354 - { 1355 - .first = 0x66, 1356 - .last = 0x8A, 1357 - .perm = AB5500_PERM_RW, 1358 - }, 1359 - { 1360 - .first = 0x8C, 1361 - .last = 0x96, 1362 - .perm = AB5500_PERM_RW, 1363 - }, 1364 - { 1365 - .first = 0xAA, 1366 - .last = 0xB4, 1367 - .perm = AB5500_PERM_RW, 1368 - }, 1369 - { 1370 - .first = 0xB7, 1371 - .last = 0xBF, 1372 - .perm = AB5500_PERM_RW, 1373 - }, 1374 - { 1375 - .first = 0xC1, 1376 - .last = 0xCA, 1377 - .perm = AB5500_PERM_RW, 1378 - }, 1379 - { 1380 - .first = 0xD3, 1381 - .last = 0xE0, 1382 - .perm = AB5500_PERM_RW, 1383 - }, 1384 - }, 1385 - }, 1386 - [AB5500_BANK_DBI_ECI] = { 1387 - .bankid = AB5500_BANK_DBI_ECI, 1388 - .nranges = 3, 1389 - .range = (struct ab5500_reg_range[]) { 1390 - { 1391 - .first = 0x00, 1392 - .last = 0x07, 1393 - .perm = AB5500_PERM_RW, 1394 - }, 1395 - { 1396 - .first = 0x10, 1397 - .last = 0x10, 1398 - .perm = AB5500_PERM_RW, 1399 - }, 1400 - { 1401 - .first = 0x13, 1402 - .last = 0x13, 1403 - .perm = AB5500_PERM_RW, 1404 - }, 1405 - }, 1406 - }, 1407 - [AB5500_BANK_CHG] = { 1408 - .bankid = AB5500_BANK_CHG, 1409 - .nranges = 2, 1410 - .range = (struct ab5500_reg_range[]) { 1411 - { 1412 - .first = 0x11, 1413 - .last = 0x11, 1414 - .perm = AB5500_PERM_RO, 1415 - }, 1416 - { 1417 - .first = 0x12, 1418 - .last = 0x1B, 1419 - .perm = AB5500_PERM_RW, 1420 - }, 1421 - }, 1422 - }, 1423 - [AB5500_BANK_FG_BATTCOM_ACC] = { 1424 - .bankid = AB5500_BANK_FG_BATTCOM_ACC, 1425 - .nranges = 2, 1426 - .range = (struct ab5500_reg_range[]) { 1427 - { 1428 - .first = 0x00, 1429 - .last = 0x0B, 1430 - .perm = AB5500_PERM_RO, 1431 - }, 1432 - { 1433 - .first = 0x0C, 1434 - .last = 0x10, 1435 - .perm = AB5500_PERM_RW, 1436 - }, 1437 - }, 1438 - }, 1439 - [AB5500_BANK_USB] = { 1440 - .bankid = AB5500_BANK_USB, 1441 - .nranges = 12, 1442 - .range = (struct ab5500_reg_range[]) { 1443 - { 1444 - .first = 0x01, 1445 - .last = 0x01, 1446 - .perm = AB5500_PERM_RW, 1447 - }, 1448 - { 1449 - .first = 0x80, 1450 - .last = 0x83, 1451 - .perm = AB5500_PERM_RW, 1452 - }, 1453 - { 1454 - .first = 0x87, 1455 - .last = 0x8A, 1456 - .perm = AB5500_PERM_RW, 1457 - }, 1458 - { 1459 - .first = 0x8B, 1460 - .last = 0x8B, 1461 - .perm = AB5500_PERM_RO, 1462 - }, 1463 - { 1464 - .first = 0x91, 1465 - .last = 0x92, 1466 - .perm = AB5500_PERM_RO, 1467 - }, 1468 - { 1469 - .first = 0x93, 1470 - .last = 0x93, 1471 - .perm = AB5500_PERM_RW, 1472 - }, 1473 - { 1474 - .first = 0x94, 1475 - .last = 0x94, 1476 - .perm = AB5500_PERM_RO, 1477 - }, 1478 - { 1479 - .first = 0xA8, 1480 - .last = 0xB0, 1481 - .perm = AB5500_PERM_RO, 1482 - }, 1483 - { 1484 - .first = 0xB2, 1485 - .last = 0xB2, 1486 - .perm = AB5500_PERM_RO, 1487 - }, 1488 - { 1489 - .first = 0xB4, 1490 - .last = 0xBC, 1491 - .perm = AB5500_PERM_RO, 1492 - }, 1493 - { 1494 - .first = 0xBF, 1495 - .last = 0xBF, 1496 - .perm = AB5500_PERM_RO, 1497 - }, 1498 - { 1499 - .first = 0xC1, 1500 - .last = 0xC5, 1501 - .perm = AB5500_PERM_RO, 1502 - }, 1503 - }, 1504 - }, 1505 - [AB5500_BANK_IT] = { 1506 - .bankid = AB5500_BANK_IT, 1507 - .nranges = 4, 1508 - .range = (struct ab5500_reg_range[]) { 1509 - { 1510 - .first = 0x00, 1511 - .last = 0x02, 1512 - .perm = AB5500_PERM_RO, 1513 - }, 1514 - { 1515 - .first = 0x20, 1516 - .last = 0x36, 1517 - .perm = AB5500_PERM_RO, 1518 - }, 1519 - { 1520 - .first = 0x40, 1521 - .last = 0x56, 1522 - .perm = AB5500_PERM_RO, 1523 - }, 1524 - { 1525 - .first = 0x60, 1526 - .last = 0x76, 1527 - .perm = AB5500_PERM_RO, 1528 - }, 1529 - }, 1530 - }, 1531 - [AB5500_BANK_VDDDIG_IO_I2C_CLK_TST] = { 1532 - .bankid = AB5500_BANK_VDDDIG_IO_I2C_CLK_TST, 1533 - .nranges = 7, 1534 - .range = (struct ab5500_reg_range[]) { 1535 - { 1536 - .first = 0x02, 1537 - .last = 0x02, 1538 - .perm = AB5500_PERM_RW, 1539 - }, 1540 - { 1541 - .first = 0x12, 1542 - .last = 0x12, 1543 - .perm = AB5500_PERM_RW, 1544 - }, 1545 - { 1546 - .first = 0x30, 1547 - .last = 0x34, 1548 - .perm = AB5500_PERM_RW, 1549 - }, 1550 - { 1551 - .first = 0x40, 1552 - .last = 0x44, 1553 - .perm = AB5500_PERM_RW, 1554 - }, 1555 - { 1556 - .first = 0x50, 1557 - .last = 0x54, 1558 - .perm = AB5500_PERM_RW, 1559 - }, 1560 - { 1561 - .first = 0x60, 1562 - .last = 0x64, 1563 - .perm = AB5500_PERM_RW, 1564 - }, 1565 - { 1566 - .first = 0x70, 1567 - .last = 0x74, 1568 - .perm = AB5500_PERM_RW, 1569 - }, 1570 - }, 1571 - }, 1572 - [AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP] = { 1573 - .bankid = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP, 1574 - .nranges = 13, 1575 - .range = (struct ab5500_reg_range[]) { 1576 - { 1577 - .first = 0x01, 1578 - .last = 0x01, 1579 - .perm = AB5500_PERM_RW, 1580 - }, 1581 - { 1582 - .first = 0x02, 1583 - .last = 0x02, 1584 - .perm = AB5500_PERM_RO, 1585 - }, 1586 - { 1587 - .first = 0x0D, 1588 - .last = 0x0F, 1589 - .perm = AB5500_PERM_RW, 1590 - }, 1591 - { 1592 - .first = 0x1C, 1593 - .last = 0x1C, 1594 - .perm = AB5500_PERM_RW, 1595 - }, 1596 - { 1597 - .first = 0x1E, 1598 - .last = 0x1E, 1599 - .perm = AB5500_PERM_RW, 1600 - }, 1601 - { 1602 - .first = 0x20, 1603 - .last = 0x21, 1604 - .perm = AB5500_PERM_RW, 1605 - }, 1606 - { 1607 - .first = 0x25, 1608 - .last = 0x25, 1609 - .perm = AB5500_PERM_RW, 1610 - }, 1611 - { 1612 - .first = 0x28, 1613 - .last = 0x2A, 1614 - .perm = AB5500_PERM_RW, 1615 - }, 1616 - { 1617 - .first = 0x30, 1618 - .last = 0x33, 1619 - .perm = AB5500_PERM_RW, 1620 - }, 1621 - { 1622 - .first = 0x40, 1623 - .last = 0x43, 1624 - .perm = AB5500_PERM_RW, 1625 - }, 1626 - { 1627 - .first = 0x50, 1628 - .last = 0x53, 1629 - .perm = AB5500_PERM_RW, 1630 - }, 1631 - { 1632 - .first = 0x60, 1633 - .last = 0x63, 1634 - .perm = AB5500_PERM_RW, 1635 - }, 1636 - { 1637 - .first = 0x70, 1638 - .last = 0x73, 1639 - .perm = AB5500_PERM_RW, 1640 - }, 1641 - }, 1642 - }, 1643 - [AB5500_BANK_VIBRA] = { 1644 - .bankid = AB5500_BANK_VIBRA, 1645 - .nranges = 2, 1646 - .range = (struct ab5500_reg_range[]) { 1647 - { 1648 - .first = 0x10, 1649 - .last = 0x13, 1650 - .perm = AB5500_PERM_RW, 1651 - }, 1652 - { 1653 - .first = 0xFE, 1654 - .last = 0xFE, 1655 - .perm = AB5500_PERM_RW, 1656 - }, 1657 - }, 1658 - }, 1659 - [AB5500_BANK_AUDIO_HEADSETUSB] = { 1660 - .bankid = AB5500_BANK_AUDIO_HEADSETUSB, 1661 - .nranges = 2, 1662 - .range = (struct ab5500_reg_range[]) { 1663 - { 1664 - .first = 0x00, 1665 - .last = 0x48, 1666 - .perm = AB5500_PERM_RW, 1667 - }, 1668 - { 1669 - .first = 0xEB, 1670 - .last = 0xFB, 1671 - .perm = AB5500_PERM_RW, 1672 - }, 1673 - }, 1674 - }, 1675 - [AB5500_BANK_SIM_USBSIM] = { 1676 - .bankid = AB5500_BANK_SIM_USBSIM, 1677 - .nranges = 1, 1678 - .range = (struct ab5500_reg_range[]) { 1679 - { 1680 - .first = 0x13, 1681 - .last = 0x19, 1682 - .perm = AB5500_PERM_RW, 1683 - }, 1684 - }, 1685 - }, 1686 - [AB5500_BANK_VDENC] = { 1687 - .bankid = AB5500_BANK_VDENC, 1688 - .nranges = 12, 1689 - .range = (struct ab5500_reg_range[]) { 1690 - { 1691 - .first = 0x00, 1692 - .last = 0x08, 1693 - .perm = AB5500_PERM_RW, 1694 - }, 1695 - { 1696 - .first = 0x09, 1697 - .last = 0x09, 1698 - .perm = AB5500_PERM_RO, 1699 - }, 1700 - { 1701 - .first = 0x0A, 1702 - .last = 0x12, 1703 - .perm = AB5500_PERM_RW, 1704 - }, 1705 - { 1706 - .first = 0x15, 1707 - .last = 0x19, 1708 - .perm = AB5500_PERM_RW, 1709 - }, 1710 - { 1711 - .first = 0x1B, 1712 - .last = 0x21, 1713 - .perm = AB5500_PERM_RW, 1714 - }, 1715 - { 1716 - .first = 0x27, 1717 - .last = 0x2C, 1718 - .perm = AB5500_PERM_RW, 1719 - }, 1720 - { 1721 - .first = 0x41, 1722 - .last = 0x41, 1723 - .perm = AB5500_PERM_RW, 1724 - }, 1725 - { 1726 - .first = 0x45, 1727 - .last = 0x5B, 1728 - .perm = AB5500_PERM_RW, 1729 - }, 1730 - { 1731 - .first = 0x5D, 1732 - .last = 0x5D, 1733 - .perm = AB5500_PERM_RW, 1734 - }, 1735 - { 1736 - .first = 0x69, 1737 - .last = 0x69, 1738 - .perm = AB5500_PERM_RW, 1739 - }, 1740 - { 1741 - .first = 0x6C, 1742 - .last = 0x6D, 1743 - .perm = AB5500_PERM_RW, 1744 - }, 1745 - { 1746 - .first = 0x80, 1747 - .last = 0x81, 1748 - .perm = AB5500_PERM_RW, 1749 - }, 1750 - }, 1751 - }, 1752 - }; 1753 - static int ab5500_registers_print(struct seq_file *s, void *p) 1754 - { 1755 - struct ab5500 *ab = s->private; 1756 - unsigned int i; 1757 - u8 bank = (u8)ab->debug_bank; 1758 - 1759 - seq_printf(s, "ab5500 register values:\n"); 1760 - for (bank = 0; bank < AB5500_NUM_BANKS; bank++) { 1761 - seq_printf(s, " bank %u, %s (0x%x):\n", bank, 1762 - bankinfo[bank].name, 1763 - bankinfo[bank].slave_addr); 1764 - for (i = 0; i < ab5500_reg_ranges[bank].nranges; i++) { 1765 - u8 reg; 1766 - int err; 1767 - 1768 - for (reg = ab5500_reg_ranges[bank].range[i].first; 1769 - reg <= ab5500_reg_ranges[bank].range[i].last; 1770 - reg++) { 1771 - u8 value; 1772 - 1773 - err = get_register_interruptible(ab, bank, reg, 1774 - &value); 1775 - if (err < 0) { 1776 - dev_err(ab->dev, "get_reg failed %d" 1777 - "bank 0x%x reg 0x%x\n", 1778 - err, bank, reg); 1779 - return err; 1780 - } 1781 - 1782 - err = seq_printf(s, "[%d/0x%02X]: 0x%02X\n", 1783 - bank, reg, value); 1784 - if (err < 0) { 1785 - dev_err(ab->dev, 1786 - "seq_printf overflow\n"); 1787 - /* 1788 - * Error is not returned here since 1789 - * the output is wanted in any case 1790 - */ 1791 - return 0; 1792 - } 1793 - } 1794 - } 1795 - } 1796 - return 0; 1797 - } 1798 - 1799 - static int ab5500_registers_open(struct inode *inode, struct file *file) 1800 - { 1801 - return single_open(file, ab5500_registers_print, inode->i_private); 1802 - } 1803 - 1804 - static const struct file_operations ab5500_registers_fops = { 1805 - .open = ab5500_registers_open, 1806 - .read = seq_read, 1807 - .llseek = seq_lseek, 1808 - .release = single_release, 1809 - .owner = THIS_MODULE, 1810 - }; 1811 - 1812 - static int ab5500_bank_print(struct seq_file *s, void *p) 1813 - { 1814 - struct ab5500 *ab = s->private; 1815 - 1816 - seq_printf(s, "%d\n", ab->debug_bank); 1817 - return 0; 1818 - } 1819 - 1820 - static int ab5500_bank_open(struct inode *inode, struct file *file) 1821 - { 1822 - return single_open(file, ab5500_bank_print, inode->i_private); 1823 - } 1824 - 1825 - static ssize_t ab5500_bank_write(struct file *file, 1826 - const char __user *user_buf, 1827 - size_t count, loff_t *ppos) 1828 - { 1829 - struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private; 1830 - char buf[32]; 1831 - int buf_size; 1832 - unsigned long user_bank; 1833 - int err; 1834 - 1835 - /* Get userspace string and assure termination */ 1836 - buf_size = min(count, (sizeof(buf) - 1)); 1837 - if (copy_from_user(buf, user_buf, buf_size)) 1838 - return -EFAULT; 1839 - buf[buf_size] = 0; 1840 - 1841 - err = strict_strtoul(buf, 0, &user_bank); 1842 - if (err) 1843 - return -EINVAL; 1844 - 1845 - if (user_bank >= AB5500_NUM_BANKS) { 1846 - dev_err(ab->dev, 1847 - "debugfs error input > number of banks\n"); 1848 - return -EINVAL; 1849 - } 1850 - 1851 - ab->debug_bank = user_bank; 1852 - 1853 - return buf_size; 1854 - } 1855 - 1856 - static int ab5500_address_print(struct seq_file *s, void *p) 1857 - { 1858 - struct ab5500 *ab = s->private; 1859 - 1860 - seq_printf(s, "0x%02X\n", ab->debug_address); 1861 - return 0; 1862 - } 1863 - 1864 - static int ab5500_address_open(struct inode *inode, struct file *file) 1865 - { 1866 - return single_open(file, ab5500_address_print, inode->i_private); 1867 - } 1868 - 1869 - static ssize_t ab5500_address_write(struct file *file, 1870 - const char __user *user_buf, 1871 - size_t count, loff_t *ppos) 1872 - { 1873 - struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private; 1874 - char buf[32]; 1875 - int buf_size; 1876 - unsigned long user_address; 1877 - int err; 1878 - 1879 - /* Get userspace string and assure termination */ 1880 - buf_size = min(count, (sizeof(buf) - 1)); 1881 - if (copy_from_user(buf, user_buf, buf_size)) 1882 - return -EFAULT; 1883 - buf[buf_size] = 0; 1884 - 1885 - err = strict_strtoul(buf, 0, &user_address); 1886 - if (err) 1887 - return -EINVAL; 1888 - if (user_address > 0xff) { 1889 - dev_err(ab->dev, 1890 - "debugfs error input > 0xff\n"); 1891 - return -EINVAL; 1892 - } 1893 - ab->debug_address = user_address; 1894 - return buf_size; 1895 - } 1896 - 1897 - static int ab5500_val_print(struct seq_file *s, void *p) 1898 - { 1899 - struct ab5500 *ab = s->private; 1900 - int err; 1901 - u8 regvalue; 1902 - 1903 - err = get_register_interruptible(ab, (u8)ab->debug_bank, 1904 - (u8)ab->debug_address, &regvalue); 1905 - if (err) { 1906 - dev_err(ab->dev, "get_reg failed %d, bank 0x%x" 1907 - ", reg 0x%x\n", err, ab->debug_bank, 1908 - ab->debug_address); 1909 - return -EINVAL; 1910 - } 1911 - seq_printf(s, "0x%02X\n", regvalue); 1912 - 1913 - return 0; 1914 - } 1915 - 1916 - static int ab5500_val_open(struct inode *inode, struct file *file) 1917 - { 1918 - return single_open(file, ab5500_val_print, inode->i_private); 1919 - } 1920 - 1921 - static ssize_t ab5500_val_write(struct file *file, 1922 - const char __user *user_buf, 1923 - size_t count, loff_t *ppos) 1924 - { 1925 - struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private; 1926 - char buf[32]; 1927 - int buf_size; 1928 - unsigned long user_val; 1929 - int err; 1930 - u8 regvalue; 1931 - 1932 - /* Get userspace string and assure termination */ 1933 - buf_size = min(count, (sizeof(buf)-1)); 1934 - if (copy_from_user(buf, user_buf, buf_size)) 1935 - return -EFAULT; 1936 - buf[buf_size] = 0; 1937 - 1938 - err = strict_strtoul(buf, 0, &user_val); 1939 - if (err) 1940 - return -EINVAL; 1941 - if (user_val > 0xff) { 1942 - dev_err(ab->dev, 1943 - "debugfs error input > 0xff\n"); 1944 - return -EINVAL; 1945 - } 1946 - err = mask_and_set_register_interruptible( 1947 - ab, (u8)ab->debug_bank, 1948 - (u8)ab->debug_address, 0xFF, (u8)user_val); 1949 - if (err) 1950 - return -EINVAL; 1951 - 1952 - get_register_interruptible(ab, (u8)ab->debug_bank, 1953 - (u8)ab->debug_address, &regvalue); 1954 - if (err) 1955 - return -EINVAL; 1956 - 1957 - return buf_size; 1958 - } 1959 - 1960 - static const struct file_operations ab5500_bank_fops = { 1961 - .open = ab5500_bank_open, 1962 - .write = ab5500_bank_write, 1963 - .read = seq_read, 1964 - .llseek = seq_lseek, 1965 - .release = single_release, 1966 - .owner = THIS_MODULE, 1967 - }; 1968 - 1969 - static const struct file_operations ab5500_address_fops = { 1970 - .open = ab5500_address_open, 1971 - .write = ab5500_address_write, 1972 - .read = seq_read, 1973 - .llseek = seq_lseek, 1974 - .release = single_release, 1975 - .owner = THIS_MODULE, 1976 - }; 1977 - 1978 - static const struct file_operations ab5500_val_fops = { 1979 - .open = ab5500_val_open, 1980 - .write = ab5500_val_write, 1981 - .read = seq_read, 1982 - .llseek = seq_lseek, 1983 - .release = single_release, 1984 - .owner = THIS_MODULE, 1985 - }; 1986 - 1987 - static struct dentry *ab5500_dir; 1988 - static struct dentry *ab5500_reg_file; 1989 - static struct dentry *ab5500_bank_file; 1990 - static struct dentry *ab5500_address_file; 1991 - static struct dentry *ab5500_val_file; 1992 - 1993 - static inline void ab5500_setup_debugfs(struct ab5500 *ab) 1994 - { 1995 - ab->debug_bank = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP; 1996 - ab->debug_address = AB5500_CHIP_ID; 1997 - 1998 - ab5500_dir = debugfs_create_dir("ab5500", NULL); 1999 - if (!ab5500_dir) 2000 - goto exit_no_debugfs; 2001 - 2002 - ab5500_reg_file = debugfs_create_file("all-bank-registers", 2003 - S_IRUGO, ab5500_dir, ab, &ab5500_registers_fops); 2004 - if (!ab5500_reg_file) 2005 - goto exit_destroy_dir; 2006 - 2007 - ab5500_bank_file = debugfs_create_file("register-bank", 2008 - (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_bank_fops); 2009 - if (!ab5500_bank_file) 2010 - goto exit_destroy_reg; 2011 - 2012 - ab5500_address_file = debugfs_create_file("register-address", 2013 - (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_address_fops); 2014 - if (!ab5500_address_file) 2015 - goto exit_destroy_bank; 2016 - 2017 - ab5500_val_file = debugfs_create_file("register-value", 2018 - (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_val_fops); 2019 - if (!ab5500_val_file) 2020 - goto exit_destroy_address; 2021 - 2022 - return; 2023 - 2024 - exit_destroy_address: 2025 - debugfs_remove(ab5500_address_file); 2026 - exit_destroy_bank: 2027 - debugfs_remove(ab5500_bank_file); 2028 - exit_destroy_reg: 2029 - debugfs_remove(ab5500_reg_file); 2030 - exit_destroy_dir: 2031 - debugfs_remove(ab5500_dir); 2032 - exit_no_debugfs: 2033 - dev_err(ab->dev, "failed to create debugfs entries.\n"); 2034 - return; 2035 - } 2036 - 2037 - static inline void ab5500_remove_debugfs(void) 2038 - { 2039 - debugfs_remove(ab5500_val_file); 2040 - debugfs_remove(ab5500_address_file); 2041 - debugfs_remove(ab5500_bank_file); 2042 - debugfs_remove(ab5500_reg_file); 2043 - debugfs_remove(ab5500_dir); 2044 - } 2045 - 2046 - #else /* !CONFIG_DEBUG_FS */ 2047 - static inline void ab5500_setup_debugfs(struct ab5500 *ab) 2048 - { 2049 - } 2050 - static inline void ab5500_remove_debugfs(void) 2051 - { 2052 - } 2053 - #endif 2054 - 2055 1330 /* 2056 1331 * ab5500_setup : Basic set-up, datastructure creation/destruction 2057 1332 * and I2C interface.This sets up a default config ··· 1267 2142 int i; 1268 2143 1269 2144 for (i = 0; i < size; i++) { 1270 - err = mask_and_set_register_interruptible(ab, 2145 + err = ab5500_mask_and_set_register_interruptible_raw(ab, 1271 2146 settings[i].bank, 1272 2147 settings[i].reg, 1273 2148 0xFF, settings[i].setting); ··· 1330 2205 platform_set_drvdata(pdev, ab); 1331 2206 1332 2207 /* Read chip ID register */ 1333 - err = get_register_interruptible(ab, AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP, 1334 - AB5500_CHIP_ID, &ab->chip_id); 2208 + err = ab5500_get_register_interruptible_raw(ab, 2209 + AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP, 2210 + AB5500_CHIP_ID, &ab->chip_id); 1335 2211 if (err) { 1336 2212 dev_err(&pdev->dev, "could not communicate with the analog " 1337 2213 "baseband chip\n"); ··· 1359 2233 u8 maskreg = AB5500_IT_MASK0_REG + i; 1360 2234 u8 val; 1361 2235 1362 - get_register_interruptible(ab, AB5500_BANK_IT, latchreg, &val); 2236 + ab5500_get_register_interruptible_raw(ab, AB5500_BANK_IT, 2237 + latchreg, &val); 1363 2238 set_register_interruptible(ab, AB5500_BANK_IT, maskreg, 0xff); 1364 2239 ab->mask[i] = ab->oldmask[i] = 0xff; 1365 2240 }
+87
drivers/mfd/ab5500-core.h
··· 1 + /* 2 + * Copyright (C) 2011 ST-Ericsson 3 + * License terms: GNU General Public License (GPL) version 2 4 + * Shared definitions and data structures for the AB5500 MFD driver 5 + */ 6 + 7 + /* Read/write operation values. */ 8 + #define AB5500_PERM_RD (0x01) 9 + #define AB5500_PERM_WR (0x02) 10 + 11 + /* Read/write permissions. */ 12 + #define AB5500_PERM_RO (AB5500_PERM_RD) 13 + #define AB5500_PERM_RW (AB5500_PERM_RD | AB5500_PERM_WR) 14 + 15 + #define AB5500_MASK_BASE (0x60) 16 + #define AB5500_MASK_END (0x79) 17 + #define AB5500_CHIP_ID (0x20) 18 + 19 + /** 20 + * struct ab5500_reg_range 21 + * @first: the first address of the range 22 + * @last: the last address of the range 23 + * @perm: access permissions for the range 24 + */ 25 + struct ab5500_reg_range { 26 + u8 first; 27 + u8 last; 28 + u8 perm; 29 + }; 30 + 31 + /** 32 + * struct ab5500_i2c_ranges 33 + * @count: the number of ranges in the list 34 + * @range: the list of register ranges 35 + */ 36 + struct ab5500_i2c_ranges { 37 + u8 nranges; 38 + u8 bankid; 39 + const struct ab5500_reg_range *range; 40 + }; 41 + 42 + /** 43 + * struct ab5500_i2c_banks 44 + * @count: the number of ranges in the list 45 + * @range: the list of register ranges 46 + */ 47 + struct ab5500_i2c_banks { 48 + u8 nbanks; 49 + const struct ab5500_i2c_ranges *bank; 50 + }; 51 + 52 + /** 53 + * struct ab5500_bank 54 + * @slave_addr: I2C slave_addr found in AB5500 specification 55 + * @name: Documentation name of the bank. For reference 56 + */ 57 + struct ab5500_bank { 58 + u8 slave_addr; 59 + const char *name; 60 + }; 61 + 62 + static const struct ab5500_bank bankinfo[AB5500_NUM_BANKS] = { 63 + [AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP] = { 64 + AB5500_ADDR_VIT_IO_I2C_CLK_TST_OTP, "VIT_IO_I2C_CLK_TST_OTP"}, 65 + [AB5500_BANK_VDDDIG_IO_I2C_CLK_TST] = { 66 + AB5500_ADDR_VDDDIG_IO_I2C_CLK_TST, "VDDDIG_IO_I2C_CLK_TST"}, 67 + [AB5500_BANK_VDENC] = {AB5500_ADDR_VDENC, "VDENC"}, 68 + [AB5500_BANK_SIM_USBSIM] = {AB5500_ADDR_SIM_USBSIM, "SIM_USBSIM"}, 69 + [AB5500_BANK_LED] = {AB5500_ADDR_LED, "LED"}, 70 + [AB5500_BANK_ADC] = {AB5500_ADDR_ADC, "ADC"}, 71 + [AB5500_BANK_RTC] = {AB5500_ADDR_RTC, "RTC"}, 72 + [AB5500_BANK_STARTUP] = {AB5500_ADDR_STARTUP, "STARTUP"}, 73 + [AB5500_BANK_DBI_ECI] = {AB5500_ADDR_DBI_ECI, "DBI-ECI"}, 74 + [AB5500_BANK_CHG] = {AB5500_ADDR_CHG, "CHG"}, 75 + [AB5500_BANK_FG_BATTCOM_ACC] = { 76 + AB5500_ADDR_FG_BATTCOM_ACC, "FG_BATCOM_ACC"}, 77 + [AB5500_BANK_USB] = {AB5500_ADDR_USB, "USB"}, 78 + [AB5500_BANK_IT] = {AB5500_ADDR_IT, "IT"}, 79 + [AB5500_BANK_VIBRA] = {AB5500_ADDR_VIBRA, "VIBRA"}, 80 + [AB5500_BANK_AUDIO_HEADSETUSB] = { 81 + AB5500_ADDR_AUDIO_HEADSETUSB, "AUDIO_HEADSETUSB"}, 82 + }; 83 + 84 + int ab5500_get_register_interruptible_raw(struct ab5500 *ab, u8 bank, u8 reg, 85 + u8 *value); 86 + int ab5500_mask_and_set_register_interruptible_raw(struct ab5500 *ab, u8 bank, 87 + u8 reg, u8 bitmask, u8 bitvalues);
+806
drivers/mfd/ab5500-debugfs.c
··· 1 + /* 2 + * Copyright (C) 2011 ST-Ericsson 3 + * License terms: GNU General Public License (GPL) version 2 4 + * Debugfs support for the AB5500 MFD driver 5 + */ 6 + 7 + #include <linux/debugfs.h> 8 + #include <linux/seq_file.h> 9 + #include <linux/mfd/ab5500/ab5500.h> 10 + #include <linux/mfd/abx500.h> 11 + #include <linux/uaccess.h> 12 + 13 + #include "ab5500-core.h" 14 + #include "ab5500-debugfs.h" 15 + 16 + static struct ab5500_i2c_ranges ab5500_reg_ranges[AB5500_NUM_BANKS] = { 17 + [AB5500_BANK_LED] = { 18 + .bankid = AB5500_BANK_LED, 19 + .nranges = 1, 20 + .range = (struct ab5500_reg_range[]) { 21 + { 22 + .first = 0x00, 23 + .last = 0x0C, 24 + .perm = AB5500_PERM_RW, 25 + }, 26 + }, 27 + }, 28 + [AB5500_BANK_ADC] = { 29 + .bankid = AB5500_BANK_ADC, 30 + .nranges = 6, 31 + .range = (struct ab5500_reg_range[]) { 32 + { 33 + .first = 0x1F, 34 + .last = 0x22, 35 + .perm = AB5500_PERM_RO, 36 + }, 37 + { 38 + .first = 0x23, 39 + .last = 0x24, 40 + .perm = AB5500_PERM_RW, 41 + }, 42 + { 43 + .first = 0x26, 44 + .last = 0x2D, 45 + .perm = AB5500_PERM_RO, 46 + }, 47 + { 48 + .first = 0x2F, 49 + .last = 0x34, 50 + .perm = AB5500_PERM_RW, 51 + }, 52 + { 53 + .first = 0x37, 54 + .last = 0x57, 55 + .perm = AB5500_PERM_RW, 56 + }, 57 + { 58 + .first = 0x58, 59 + .last = 0x58, 60 + .perm = AB5500_PERM_RO, 61 + }, 62 + }, 63 + }, 64 + [AB5500_BANK_RTC] = { 65 + .bankid = AB5500_BANK_RTC, 66 + .nranges = 2, 67 + .range = (struct ab5500_reg_range[]) { 68 + { 69 + .first = 0x00, 70 + .last = 0x04, 71 + .perm = AB5500_PERM_RW, 72 + }, 73 + { 74 + .first = 0x06, 75 + .last = 0x0C, 76 + .perm = AB5500_PERM_RW, 77 + }, 78 + }, 79 + }, 80 + [AB5500_BANK_STARTUP] = { 81 + .bankid = AB5500_BANK_STARTUP, 82 + .nranges = 12, 83 + .range = (struct ab5500_reg_range[]) { 84 + { 85 + .first = 0x00, 86 + .last = 0x01, 87 + .perm = AB5500_PERM_RW, 88 + }, 89 + { 90 + .first = 0x1F, 91 + .last = 0x1F, 92 + .perm = AB5500_PERM_RW, 93 + }, 94 + { 95 + .first = 0x2E, 96 + .last = 0x2E, 97 + .perm = AB5500_PERM_RO, 98 + }, 99 + { 100 + .first = 0x2F, 101 + .last = 0x30, 102 + .perm = AB5500_PERM_RW, 103 + }, 104 + { 105 + .first = 0x50, 106 + .last = 0x51, 107 + .perm = AB5500_PERM_RW, 108 + }, 109 + { 110 + .first = 0x60, 111 + .last = 0x61, 112 + .perm = AB5500_PERM_RW, 113 + }, 114 + { 115 + .first = 0x66, 116 + .last = 0x8A, 117 + .perm = AB5500_PERM_RW, 118 + }, 119 + { 120 + .first = 0x8C, 121 + .last = 0x96, 122 + .perm = AB5500_PERM_RW, 123 + }, 124 + { 125 + .first = 0xAA, 126 + .last = 0xB4, 127 + .perm = AB5500_PERM_RW, 128 + }, 129 + { 130 + .first = 0xB7, 131 + .last = 0xBF, 132 + .perm = AB5500_PERM_RW, 133 + }, 134 + { 135 + .first = 0xC1, 136 + .last = 0xCA, 137 + .perm = AB5500_PERM_RW, 138 + }, 139 + { 140 + .first = 0xD3, 141 + .last = 0xE0, 142 + .perm = AB5500_PERM_RW, 143 + }, 144 + }, 145 + }, 146 + [AB5500_BANK_DBI_ECI] = { 147 + .bankid = AB5500_BANK_DBI_ECI, 148 + .nranges = 3, 149 + .range = (struct ab5500_reg_range[]) { 150 + { 151 + .first = 0x00, 152 + .last = 0x07, 153 + .perm = AB5500_PERM_RW, 154 + }, 155 + { 156 + .first = 0x10, 157 + .last = 0x10, 158 + .perm = AB5500_PERM_RW, 159 + }, 160 + { 161 + .first = 0x13, 162 + .last = 0x13, 163 + .perm = AB5500_PERM_RW, 164 + }, 165 + }, 166 + }, 167 + [AB5500_BANK_CHG] = { 168 + .bankid = AB5500_BANK_CHG, 169 + .nranges = 2, 170 + .range = (struct ab5500_reg_range[]) { 171 + { 172 + .first = 0x11, 173 + .last = 0x11, 174 + .perm = AB5500_PERM_RO, 175 + }, 176 + { 177 + .first = 0x12, 178 + .last = 0x1B, 179 + .perm = AB5500_PERM_RW, 180 + }, 181 + }, 182 + }, 183 + [AB5500_BANK_FG_BATTCOM_ACC] = { 184 + .bankid = AB5500_BANK_FG_BATTCOM_ACC, 185 + .nranges = 2, 186 + .range = (struct ab5500_reg_range[]) { 187 + { 188 + .first = 0x00, 189 + .last = 0x0B, 190 + .perm = AB5500_PERM_RO, 191 + }, 192 + { 193 + .first = 0x0C, 194 + .last = 0x10, 195 + .perm = AB5500_PERM_RW, 196 + }, 197 + }, 198 + }, 199 + [AB5500_BANK_USB] = { 200 + .bankid = AB5500_BANK_USB, 201 + .nranges = 12, 202 + .range = (struct ab5500_reg_range[]) { 203 + { 204 + .first = 0x01, 205 + .last = 0x01, 206 + .perm = AB5500_PERM_RW, 207 + }, 208 + { 209 + .first = 0x80, 210 + .last = 0x83, 211 + .perm = AB5500_PERM_RW, 212 + }, 213 + { 214 + .first = 0x87, 215 + .last = 0x8A, 216 + .perm = AB5500_PERM_RW, 217 + }, 218 + { 219 + .first = 0x8B, 220 + .last = 0x8B, 221 + .perm = AB5500_PERM_RO, 222 + }, 223 + { 224 + .first = 0x91, 225 + .last = 0x92, 226 + .perm = AB5500_PERM_RO, 227 + }, 228 + { 229 + .first = 0x93, 230 + .last = 0x93, 231 + .perm = AB5500_PERM_RW, 232 + }, 233 + { 234 + .first = 0x94, 235 + .last = 0x94, 236 + .perm = AB5500_PERM_RO, 237 + }, 238 + { 239 + .first = 0xA8, 240 + .last = 0xB0, 241 + .perm = AB5500_PERM_RO, 242 + }, 243 + { 244 + .first = 0xB2, 245 + .last = 0xB2, 246 + .perm = AB5500_PERM_RO, 247 + }, 248 + { 249 + .first = 0xB4, 250 + .last = 0xBC, 251 + .perm = AB5500_PERM_RO, 252 + }, 253 + { 254 + .first = 0xBF, 255 + .last = 0xBF, 256 + .perm = AB5500_PERM_RO, 257 + }, 258 + { 259 + .first = 0xC1, 260 + .last = 0xC5, 261 + .perm = AB5500_PERM_RO, 262 + }, 263 + }, 264 + }, 265 + [AB5500_BANK_IT] = { 266 + .bankid = AB5500_BANK_IT, 267 + .nranges = 4, 268 + .range = (struct ab5500_reg_range[]) { 269 + { 270 + .first = 0x00, 271 + .last = 0x02, 272 + .perm = AB5500_PERM_RO, 273 + }, 274 + { 275 + .first = 0x20, 276 + .last = 0x36, 277 + .perm = AB5500_PERM_RO, 278 + }, 279 + { 280 + .first = 0x40, 281 + .last = 0x56, 282 + .perm = AB5500_PERM_RO, 283 + }, 284 + { 285 + .first = 0x60, 286 + .last = 0x76, 287 + .perm = AB5500_PERM_RO, 288 + }, 289 + }, 290 + }, 291 + [AB5500_BANK_VDDDIG_IO_I2C_CLK_TST] = { 292 + .bankid = AB5500_BANK_VDDDIG_IO_I2C_CLK_TST, 293 + .nranges = 7, 294 + .range = (struct ab5500_reg_range[]) { 295 + { 296 + .first = 0x02, 297 + .last = 0x02, 298 + .perm = AB5500_PERM_RW, 299 + }, 300 + { 301 + .first = 0x12, 302 + .last = 0x12, 303 + .perm = AB5500_PERM_RW, 304 + }, 305 + { 306 + .first = 0x30, 307 + .last = 0x34, 308 + .perm = AB5500_PERM_RW, 309 + }, 310 + { 311 + .first = 0x40, 312 + .last = 0x44, 313 + .perm = AB5500_PERM_RW, 314 + }, 315 + { 316 + .first = 0x50, 317 + .last = 0x54, 318 + .perm = AB5500_PERM_RW, 319 + }, 320 + { 321 + .first = 0x60, 322 + .last = 0x64, 323 + .perm = AB5500_PERM_RW, 324 + }, 325 + { 326 + .first = 0x70, 327 + .last = 0x74, 328 + .perm = AB5500_PERM_RW, 329 + }, 330 + }, 331 + }, 332 + [AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP] = { 333 + .bankid = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP, 334 + .nranges = 13, 335 + .range = (struct ab5500_reg_range[]) { 336 + { 337 + .first = 0x01, 338 + .last = 0x01, 339 + .perm = AB5500_PERM_RW, 340 + }, 341 + { 342 + .first = 0x02, 343 + .last = 0x02, 344 + .perm = AB5500_PERM_RO, 345 + }, 346 + { 347 + .first = 0x0D, 348 + .last = 0x0F, 349 + .perm = AB5500_PERM_RW, 350 + }, 351 + { 352 + .first = 0x1C, 353 + .last = 0x1C, 354 + .perm = AB5500_PERM_RW, 355 + }, 356 + { 357 + .first = 0x1E, 358 + .last = 0x1E, 359 + .perm = AB5500_PERM_RW, 360 + }, 361 + { 362 + .first = 0x20, 363 + .last = 0x21, 364 + .perm = AB5500_PERM_RW, 365 + }, 366 + { 367 + .first = 0x25, 368 + .last = 0x25, 369 + .perm = AB5500_PERM_RW, 370 + }, 371 + { 372 + .first = 0x28, 373 + .last = 0x2A, 374 + .perm = AB5500_PERM_RW, 375 + }, 376 + { 377 + .first = 0x30, 378 + .last = 0x33, 379 + .perm = AB5500_PERM_RW, 380 + }, 381 + { 382 + .first = 0x40, 383 + .last = 0x43, 384 + .perm = AB5500_PERM_RW, 385 + }, 386 + { 387 + .first = 0x50, 388 + .last = 0x53, 389 + .perm = AB5500_PERM_RW, 390 + }, 391 + { 392 + .first = 0x60, 393 + .last = 0x63, 394 + .perm = AB5500_PERM_RW, 395 + }, 396 + { 397 + .first = 0x70, 398 + .last = 0x73, 399 + .perm = AB5500_PERM_RW, 400 + }, 401 + }, 402 + }, 403 + [AB5500_BANK_VIBRA] = { 404 + .bankid = AB5500_BANK_VIBRA, 405 + .nranges = 2, 406 + .range = (struct ab5500_reg_range[]) { 407 + { 408 + .first = 0x10, 409 + .last = 0x13, 410 + .perm = AB5500_PERM_RW, 411 + }, 412 + { 413 + .first = 0xFE, 414 + .last = 0xFE, 415 + .perm = AB5500_PERM_RW, 416 + }, 417 + }, 418 + }, 419 + [AB5500_BANK_AUDIO_HEADSETUSB] = { 420 + .bankid = AB5500_BANK_AUDIO_HEADSETUSB, 421 + .nranges = 2, 422 + .range = (struct ab5500_reg_range[]) { 423 + { 424 + .first = 0x00, 425 + .last = 0x48, 426 + .perm = AB5500_PERM_RW, 427 + }, 428 + { 429 + .first = 0xEB, 430 + .last = 0xFB, 431 + .perm = AB5500_PERM_RW, 432 + }, 433 + }, 434 + }, 435 + [AB5500_BANK_SIM_USBSIM] = { 436 + .bankid = AB5500_BANK_SIM_USBSIM, 437 + .nranges = 1, 438 + .range = (struct ab5500_reg_range[]) { 439 + { 440 + .first = 0x13, 441 + .last = 0x19, 442 + .perm = AB5500_PERM_RW, 443 + }, 444 + }, 445 + }, 446 + [AB5500_BANK_VDENC] = { 447 + .bankid = AB5500_BANK_VDENC, 448 + .nranges = 12, 449 + .range = (struct ab5500_reg_range[]) { 450 + { 451 + .first = 0x00, 452 + .last = 0x08, 453 + .perm = AB5500_PERM_RW, 454 + }, 455 + { 456 + .first = 0x09, 457 + .last = 0x09, 458 + .perm = AB5500_PERM_RO, 459 + }, 460 + { 461 + .first = 0x0A, 462 + .last = 0x12, 463 + .perm = AB5500_PERM_RW, 464 + }, 465 + { 466 + .first = 0x15, 467 + .last = 0x19, 468 + .perm = AB5500_PERM_RW, 469 + }, 470 + { 471 + .first = 0x1B, 472 + .last = 0x21, 473 + .perm = AB5500_PERM_RW, 474 + }, 475 + { 476 + .first = 0x27, 477 + .last = 0x2C, 478 + .perm = AB5500_PERM_RW, 479 + }, 480 + { 481 + .first = 0x41, 482 + .last = 0x41, 483 + .perm = AB5500_PERM_RW, 484 + }, 485 + { 486 + .first = 0x45, 487 + .last = 0x5B, 488 + .perm = AB5500_PERM_RW, 489 + }, 490 + { 491 + .first = 0x5D, 492 + .last = 0x5D, 493 + .perm = AB5500_PERM_RW, 494 + }, 495 + { 496 + .first = 0x69, 497 + .last = 0x69, 498 + .perm = AB5500_PERM_RW, 499 + }, 500 + { 501 + .first = 0x6C, 502 + .last = 0x6D, 503 + .perm = AB5500_PERM_RW, 504 + }, 505 + { 506 + .first = 0x80, 507 + .last = 0x81, 508 + .perm = AB5500_PERM_RW, 509 + }, 510 + }, 511 + }, 512 + }; 513 + 514 + static int ab5500_registers_print(struct seq_file *s, void *p) 515 + { 516 + struct ab5500 *ab = s->private; 517 + unsigned int i; 518 + u8 bank = (u8)ab->debug_bank; 519 + 520 + seq_printf(s, "ab5500 register values:\n"); 521 + for (bank = 0; bank < AB5500_NUM_BANKS; bank++) { 522 + seq_printf(s, " bank %u, %s (0x%x):\n", bank, 523 + bankinfo[bank].name, 524 + bankinfo[bank].slave_addr); 525 + for (i = 0; i < ab5500_reg_ranges[bank].nranges; i++) { 526 + u8 reg; 527 + int err; 528 + 529 + for (reg = ab5500_reg_ranges[bank].range[i].first; 530 + reg <= ab5500_reg_ranges[bank].range[i].last; 531 + reg++) { 532 + u8 value; 533 + 534 + err = ab5500_get_register_interruptible_raw(ab, 535 + bank, reg, 536 + &value); 537 + if (err < 0) { 538 + dev_err(ab->dev, "get_reg failed %d" 539 + "bank 0x%x reg 0x%x\n", 540 + err, bank, reg); 541 + return err; 542 + } 543 + 544 + err = seq_printf(s, "[%d/0x%02X]: 0x%02X\n", 545 + bank, reg, value); 546 + if (err < 0) { 547 + dev_err(ab->dev, 548 + "seq_printf overflow\n"); 549 + /* 550 + * Error is not returned here since 551 + * the output is wanted in any case 552 + */ 553 + return 0; 554 + } 555 + } 556 + } 557 + } 558 + return 0; 559 + } 560 + 561 + static int ab5500_registers_open(struct inode *inode, struct file *file) 562 + { 563 + return single_open(file, ab5500_registers_print, inode->i_private); 564 + } 565 + 566 + static const struct file_operations ab5500_registers_fops = { 567 + .open = ab5500_registers_open, 568 + .read = seq_read, 569 + .llseek = seq_lseek, 570 + .release = single_release, 571 + .owner = THIS_MODULE, 572 + }; 573 + 574 + static int ab5500_bank_print(struct seq_file *s, void *p) 575 + { 576 + struct ab5500 *ab = s->private; 577 + 578 + seq_printf(s, "%d\n", ab->debug_bank); 579 + return 0; 580 + } 581 + 582 + static int ab5500_bank_open(struct inode *inode, struct file *file) 583 + { 584 + return single_open(file, ab5500_bank_print, inode->i_private); 585 + } 586 + 587 + static ssize_t ab5500_bank_write(struct file *file, 588 + const char __user *user_buf, 589 + size_t count, loff_t *ppos) 590 + { 591 + struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private; 592 + char buf[32]; 593 + int buf_size; 594 + unsigned long user_bank; 595 + int err; 596 + 597 + /* Get userspace string and assure termination */ 598 + buf_size = min(count, (sizeof(buf) - 1)); 599 + if (copy_from_user(buf, user_buf, buf_size)) 600 + return -EFAULT; 601 + buf[buf_size] = 0; 602 + 603 + err = strict_strtoul(buf, 0, &user_bank); 604 + if (err) 605 + return -EINVAL; 606 + 607 + if (user_bank >= AB5500_NUM_BANKS) { 608 + dev_err(ab->dev, 609 + "debugfs error input > number of banks\n"); 610 + return -EINVAL; 611 + } 612 + 613 + ab->debug_bank = user_bank; 614 + 615 + return buf_size; 616 + } 617 + 618 + static int ab5500_address_print(struct seq_file *s, void *p) 619 + { 620 + struct ab5500 *ab = s->private; 621 + 622 + seq_printf(s, "0x%02X\n", ab->debug_address); 623 + return 0; 624 + } 625 + 626 + static int ab5500_address_open(struct inode *inode, struct file *file) 627 + { 628 + return single_open(file, ab5500_address_print, inode->i_private); 629 + } 630 + 631 + static ssize_t ab5500_address_write(struct file *file, 632 + const char __user *user_buf, 633 + size_t count, loff_t *ppos) 634 + { 635 + struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private; 636 + char buf[32]; 637 + int buf_size; 638 + unsigned long user_address; 639 + int err; 640 + 641 + /* Get userspace string and assure termination */ 642 + buf_size = min(count, (sizeof(buf) - 1)); 643 + if (copy_from_user(buf, user_buf, buf_size)) 644 + return -EFAULT; 645 + buf[buf_size] = 0; 646 + 647 + err = strict_strtoul(buf, 0, &user_address); 648 + if (err) 649 + return -EINVAL; 650 + if (user_address > 0xff) { 651 + dev_err(ab->dev, 652 + "debugfs error input > 0xff\n"); 653 + return -EINVAL; 654 + } 655 + ab->debug_address = user_address; 656 + return buf_size; 657 + } 658 + 659 + static int ab5500_val_print(struct seq_file *s, void *p) 660 + { 661 + struct ab5500 *ab = s->private; 662 + int err; 663 + u8 regvalue; 664 + 665 + err = ab5500_get_register_interruptible_raw(ab, (u8)ab->debug_bank, 666 + (u8)ab->debug_address, &regvalue); 667 + if (err) { 668 + dev_err(ab->dev, "get_reg failed %d, bank 0x%x" 669 + ", reg 0x%x\n", err, ab->debug_bank, 670 + ab->debug_address); 671 + return -EINVAL; 672 + } 673 + seq_printf(s, "0x%02X\n", regvalue); 674 + 675 + return 0; 676 + } 677 + 678 + static int ab5500_val_open(struct inode *inode, struct file *file) 679 + { 680 + return single_open(file, ab5500_val_print, inode->i_private); 681 + } 682 + 683 + static ssize_t ab5500_val_write(struct file *file, 684 + const char __user *user_buf, 685 + size_t count, loff_t *ppos) 686 + { 687 + struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private; 688 + char buf[32]; 689 + int buf_size; 690 + unsigned long user_val; 691 + int err; 692 + u8 regvalue; 693 + 694 + /* Get userspace string and assure termination */ 695 + buf_size = min(count, (sizeof(buf)-1)); 696 + if (copy_from_user(buf, user_buf, buf_size)) 697 + return -EFAULT; 698 + buf[buf_size] = 0; 699 + 700 + err = strict_strtoul(buf, 0, &user_val); 701 + if (err) 702 + return -EINVAL; 703 + if (user_val > 0xff) { 704 + dev_err(ab->dev, 705 + "debugfs error input > 0xff\n"); 706 + return -EINVAL; 707 + } 708 + err = ab5500_mask_and_set_register_interruptible_raw( 709 + ab, (u8)ab->debug_bank, 710 + (u8)ab->debug_address, 0xFF, (u8)user_val); 711 + if (err) 712 + return -EINVAL; 713 + 714 + ab5500_get_register_interruptible_raw(ab, (u8)ab->debug_bank, 715 + (u8)ab->debug_address, &regvalue); 716 + if (err) 717 + return -EINVAL; 718 + 719 + return buf_size; 720 + } 721 + 722 + static const struct file_operations ab5500_bank_fops = { 723 + .open = ab5500_bank_open, 724 + .write = ab5500_bank_write, 725 + .read = seq_read, 726 + .llseek = seq_lseek, 727 + .release = single_release, 728 + .owner = THIS_MODULE, 729 + }; 730 + 731 + static const struct file_operations ab5500_address_fops = { 732 + .open = ab5500_address_open, 733 + .write = ab5500_address_write, 734 + .read = seq_read, 735 + .llseek = seq_lseek, 736 + .release = single_release, 737 + .owner = THIS_MODULE, 738 + }; 739 + 740 + static const struct file_operations ab5500_val_fops = { 741 + .open = ab5500_val_open, 742 + .write = ab5500_val_write, 743 + .read = seq_read, 744 + .llseek = seq_lseek, 745 + .release = single_release, 746 + .owner = THIS_MODULE, 747 + }; 748 + 749 + static struct dentry *ab5500_dir; 750 + static struct dentry *ab5500_reg_file; 751 + static struct dentry *ab5500_bank_file; 752 + static struct dentry *ab5500_address_file; 753 + static struct dentry *ab5500_val_file; 754 + 755 + void __init ab5500_setup_debugfs(struct ab5500 *ab) 756 + { 757 + ab->debug_bank = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP; 758 + ab->debug_address = AB5500_CHIP_ID; 759 + 760 + ab5500_dir = debugfs_create_dir("ab5500", NULL); 761 + if (!ab5500_dir) 762 + goto exit_no_debugfs; 763 + 764 + ab5500_reg_file = debugfs_create_file("all-bank-registers", 765 + S_IRUGO, ab5500_dir, ab, &ab5500_registers_fops); 766 + if (!ab5500_reg_file) 767 + goto exit_destroy_dir; 768 + 769 + ab5500_bank_file = debugfs_create_file("register-bank", 770 + (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_bank_fops); 771 + if (!ab5500_bank_file) 772 + goto exit_destroy_reg; 773 + 774 + ab5500_address_file = debugfs_create_file("register-address", 775 + (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_address_fops); 776 + if (!ab5500_address_file) 777 + goto exit_destroy_bank; 778 + 779 + ab5500_val_file = debugfs_create_file("register-value", 780 + (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_val_fops); 781 + if (!ab5500_val_file) 782 + goto exit_destroy_address; 783 + 784 + return; 785 + 786 + exit_destroy_address: 787 + debugfs_remove(ab5500_address_file); 788 + exit_destroy_bank: 789 + debugfs_remove(ab5500_bank_file); 790 + exit_destroy_reg: 791 + debugfs_remove(ab5500_reg_file); 792 + exit_destroy_dir: 793 + debugfs_remove(ab5500_dir); 794 + exit_no_debugfs: 795 + dev_err(ab->dev, "failed to create debugfs entries.\n"); 796 + return; 797 + } 798 + 799 + void __exit ab5500_remove_debugfs(void) 800 + { 801 + debugfs_remove(ab5500_val_file); 802 + debugfs_remove(ab5500_address_file); 803 + debugfs_remove(ab5500_bank_file); 804 + debugfs_remove(ab5500_reg_file); 805 + debugfs_remove(ab5500_dir); 806 + }
+22
drivers/mfd/ab5500-debugfs.h
··· 1 + /* 2 + * Copyright (C) 2011 ST-Ericsson 3 + * License terms: GNU General Public License (GPL) version 2 4 + * Debugfs interface to the AB5500 core driver 5 + */ 6 + 7 + #ifdef CONFIG_DEBUG_FS 8 + 9 + void ab5500_setup_debugfs(struct ab5500 *ab); 10 + void ab5500_remove_debugfs(void); 11 + 12 + #else /* !CONFIG_DEBUG_FS */ 13 + 14 + static inline void ab5500_setup_debugfs(struct ab5500 *ab) 15 + { 16 + } 17 + 18 + static inline void ab5500_remove_debugfs(void) 19 + { 20 + } 21 + 22 + #endif