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

mfd: ab8500-debug: Add support for the AB8540

Allow GPADC debug information to be shown when executing on an AB8540
based platform.

Signed-off-by: Alexandre Bourdiol <alexandre.bourdiol@stericsson.com>
Reviewed-by: Marcus COOPER <marcus.xm.cooper@stericsson.com>
Reviewed-by: Philippe LANGLAIS <philippe.langlais@stericsson.com>
Acked-by: Samuel Ortiz <sameo@linux.intel.com>

Lee Jones bc6b4132 e4bffe8d

+332 -1
+285 -1
drivers/mfd/ab8500-debugfs.c
··· 1633 1633 .owner = THIS_MODULE, 1634 1634 }; 1635 1635 1636 + static int ab8540_gpadc_xtal_temp_print(struct seq_file *s, void *p) 1637 + { 1638 + int xtal_temp_raw; 1639 + int xtal_temp_convert; 1640 + struct ab8500_gpadc *gpadc; 1641 + 1642 + gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); 1643 + xtal_temp_raw = ab8500_gpadc_read_raw(gpadc, XTAL_TEMP, 1644 + avg_sample, trig_edge, trig_timer, conv_type); 1645 + xtal_temp_convert = ab8500_gpadc_ad_to_voltage(gpadc, XTAL_TEMP, 1646 + xtal_temp_raw); 1647 + 1648 + return seq_printf(s, "%d,0x%X\n", 1649 + xtal_temp_convert, xtal_temp_raw); 1650 + } 1651 + 1652 + static int ab8540_gpadc_xtal_temp_open(struct inode *inode, struct file *file) 1653 + { 1654 + return single_open(file, ab8540_gpadc_xtal_temp_print, 1655 + inode->i_private); 1656 + } 1657 + 1658 + static const struct file_operations ab8540_gpadc_xtal_temp_fops = { 1659 + .open = ab8540_gpadc_xtal_temp_open, 1660 + .read = seq_read, 1661 + .llseek = seq_lseek, 1662 + .release = single_release, 1663 + .owner = THIS_MODULE, 1664 + }; 1665 + 1666 + static int ab8540_gpadc_vbat_true_meas_print(struct seq_file *s, void *p) 1667 + { 1668 + int vbat_true_meas_raw; 1669 + int vbat_true_meas_convert; 1670 + struct ab8500_gpadc *gpadc; 1671 + 1672 + gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); 1673 + vbat_true_meas_raw = ab8500_gpadc_read_raw(gpadc, VBAT_TRUE_MEAS, 1674 + avg_sample, trig_edge, trig_timer, conv_type); 1675 + vbat_true_meas_convert = ab8500_gpadc_ad_to_voltage(gpadc, VBAT_TRUE_MEAS, 1676 + vbat_true_meas_raw); 1677 + 1678 + return seq_printf(s, "%d,0x%X\n", 1679 + vbat_true_meas_convert, vbat_true_meas_raw); 1680 + } 1681 + 1682 + static int ab8540_gpadc_vbat_true_meas_open(struct inode *inode, 1683 + struct file *file) 1684 + { 1685 + return single_open(file, ab8540_gpadc_vbat_true_meas_print, 1686 + inode->i_private); 1687 + } 1688 + 1689 + static const struct file_operations ab8540_gpadc_vbat_true_meas_fops = { 1690 + .open = ab8540_gpadc_vbat_true_meas_open, 1691 + .read = seq_read, 1692 + .llseek = seq_lseek, 1693 + .release = single_release, 1694 + .owner = THIS_MODULE, 1695 + }; 1696 + 1697 + static int ab8540_gpadc_bat_ctrl_and_ibat_print(struct seq_file *s, void *p) 1698 + { 1699 + int bat_ctrl_raw; 1700 + int bat_ctrl_convert; 1701 + int ibat_raw; 1702 + int ibat_convert; 1703 + struct ab8500_gpadc *gpadc; 1704 + 1705 + gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); 1706 + bat_ctrl_raw = ab8500_gpadc_double_read_raw(gpadc, BAT_CTRL_AND_IBAT, 1707 + avg_sample, trig_edge, trig_timer, conv_type, &ibat_raw); 1708 + 1709 + bat_ctrl_convert = ab8500_gpadc_ad_to_voltage(gpadc, BAT_CTRL, 1710 + bat_ctrl_raw); 1711 + ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL, 1712 + ibat_raw); 1713 + 1714 + return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n", 1715 + bat_ctrl_convert, bat_ctrl_raw, 1716 + ibat_convert, ibat_raw); 1717 + } 1718 + 1719 + static int ab8540_gpadc_bat_ctrl_and_ibat_open(struct inode *inode, 1720 + struct file *file) 1721 + { 1722 + return single_open(file, ab8540_gpadc_bat_ctrl_and_ibat_print, 1723 + inode->i_private); 1724 + } 1725 + 1726 + static const struct file_operations ab8540_gpadc_bat_ctrl_and_ibat_fops = { 1727 + .open = ab8540_gpadc_bat_ctrl_and_ibat_open, 1728 + .read = seq_read, 1729 + .llseek = seq_lseek, 1730 + .release = single_release, 1731 + .owner = THIS_MODULE, 1732 + }; 1733 + 1734 + static int ab8540_gpadc_vbat_meas_and_ibat_print(struct seq_file *s, void *p) 1735 + { 1736 + int vbat_meas_raw; 1737 + int vbat_meas_convert; 1738 + int ibat_raw; 1739 + int ibat_convert; 1740 + struct ab8500_gpadc *gpadc; 1741 + 1742 + gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); 1743 + vbat_meas_raw = ab8500_gpadc_double_read_raw(gpadc, VBAT_MEAS_AND_IBAT, 1744 + avg_sample, trig_edge, trig_timer, conv_type, &ibat_raw); 1745 + vbat_meas_convert = ab8500_gpadc_ad_to_voltage(gpadc, MAIN_BAT_V, 1746 + vbat_meas_raw); 1747 + ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL, 1748 + ibat_raw); 1749 + 1750 + return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n", 1751 + vbat_meas_convert, vbat_meas_raw, 1752 + ibat_convert, ibat_raw); 1753 + } 1754 + 1755 + static int ab8540_gpadc_vbat_meas_and_ibat_open(struct inode *inode, 1756 + struct file *file) 1757 + { 1758 + return single_open(file, ab8540_gpadc_vbat_meas_and_ibat_print, 1759 + inode->i_private); 1760 + } 1761 + 1762 + static const struct file_operations ab8540_gpadc_vbat_meas_and_ibat_fops = { 1763 + .open = ab8540_gpadc_vbat_meas_and_ibat_open, 1764 + .read = seq_read, 1765 + .llseek = seq_lseek, 1766 + .release = single_release, 1767 + .owner = THIS_MODULE, 1768 + }; 1769 + 1770 + static int ab8540_gpadc_vbat_true_meas_and_ibat_print(struct seq_file *s, void *p) 1771 + { 1772 + int vbat_true_meas_raw; 1773 + int vbat_true_meas_convert; 1774 + int ibat_raw; 1775 + int ibat_convert; 1776 + struct ab8500_gpadc *gpadc; 1777 + 1778 + gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); 1779 + vbat_true_meas_raw = ab8500_gpadc_double_read_raw(gpadc, 1780 + VBAT_TRUE_MEAS_AND_IBAT, avg_sample, trig_edge, 1781 + trig_timer, conv_type, &ibat_raw); 1782 + vbat_true_meas_convert = ab8500_gpadc_ad_to_voltage(gpadc, 1783 + VBAT_TRUE_MEAS, vbat_true_meas_raw); 1784 + ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL, 1785 + ibat_raw); 1786 + 1787 + return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n", 1788 + vbat_true_meas_convert, vbat_true_meas_raw, 1789 + ibat_convert, ibat_raw); 1790 + } 1791 + 1792 + static int ab8540_gpadc_vbat_true_meas_and_ibat_open(struct inode *inode, 1793 + struct file *file) 1794 + { 1795 + return single_open(file, ab8540_gpadc_vbat_true_meas_and_ibat_print, 1796 + inode->i_private); 1797 + } 1798 + 1799 + static const struct file_operations ab8540_gpadc_vbat_true_meas_and_ibat_fops = { 1800 + .open = ab8540_gpadc_vbat_true_meas_and_ibat_open, 1801 + .read = seq_read, 1802 + .llseek = seq_lseek, 1803 + .release = single_release, 1804 + .owner = THIS_MODULE, 1805 + }; 1806 + 1807 + static int ab8540_gpadc_bat_temp_and_ibat_print(struct seq_file *s, void *p) 1808 + { 1809 + int bat_temp_raw; 1810 + int bat_temp_convert; 1811 + int ibat_raw; 1812 + int ibat_convert; 1813 + struct ab8500_gpadc *gpadc; 1814 + 1815 + gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); 1816 + bat_temp_raw = ab8500_gpadc_double_read_raw(gpadc, BAT_TEMP_AND_IBAT, 1817 + avg_sample, trig_edge, trig_timer, conv_type, &ibat_raw); 1818 + bat_temp_convert = ab8500_gpadc_ad_to_voltage(gpadc, BTEMP_BALL, 1819 + bat_temp_raw); 1820 + ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL, 1821 + ibat_raw); 1822 + 1823 + return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n", 1824 + bat_temp_convert, bat_temp_raw, 1825 + ibat_convert, ibat_raw); 1826 + } 1827 + 1828 + static int ab8540_gpadc_bat_temp_and_ibat_open(struct inode *inode, 1829 + struct file *file) 1830 + { 1831 + return single_open(file, ab8540_gpadc_bat_temp_and_ibat_print, 1832 + inode->i_private); 1833 + } 1834 + 1835 + static const struct file_operations ab8540_gpadc_bat_temp_and_ibat_fops = { 1836 + .open = ab8540_gpadc_bat_temp_and_ibat_open, 1837 + .read = seq_read, 1838 + .llseek = seq_lseek, 1839 + .release = single_release, 1840 + .owner = THIS_MODULE, 1841 + }; 1842 + 1843 + static int ab8540_gpadc_otp_cal_print(struct seq_file *s, void *p) 1844 + { 1845 + struct ab8500_gpadc *gpadc; 1846 + u16 vmain_l, vmain_h, btemp_l, btemp_h; 1847 + u16 vbat_l, vbat_h, ibat_l, ibat_h; 1848 + 1849 + gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); 1850 + ab8540_gpadc_get_otp(gpadc, &vmain_l, &vmain_h, &btemp_l, &btemp_h, 1851 + &vbat_l, &vbat_h, &ibat_l, &ibat_h); 1852 + return seq_printf(s, "VMAIN_L:0x%X\n" 1853 + "VMAIN_H:0x%X\n" 1854 + "BTEMP_L:0x%X\n" 1855 + "BTEMP_H:0x%X\n" 1856 + "VBAT_L:0x%X\n" 1857 + "VBAT_H:0x%X\n" 1858 + "IBAT_L:0x%X\n" 1859 + "IBAT_H:0x%X\n" 1860 + , 1861 + vmain_l, 1862 + vmain_h, 1863 + btemp_l, 1864 + btemp_h, 1865 + vbat_l, 1866 + vbat_h, 1867 + ibat_l, 1868 + ibat_h); 1869 + } 1870 + 1871 + static int ab8540_gpadc_otp_cal_open(struct inode *inode, struct file *file) 1872 + { 1873 + return single_open(file, ab8540_gpadc_otp_cal_print, inode->i_private); 1874 + } 1875 + 1876 + static const struct file_operations ab8540_gpadc_otp_calib_fops = { 1877 + .open = ab8540_gpadc_otp_cal_open, 1878 + .read = seq_read, 1879 + .llseek = seq_lseek, 1880 + .release = single_release, 1881 + .owner = THIS_MODULE, 1882 + }; 1883 + 1636 1884 static int ab8500_gpadc_avg_sample_print(struct seq_file *s, void *p) 1637 1885 { 1638 1886 return seq_printf(s, "%d\n", avg_sample); ··· 2634 2386 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_die_temp_fops); 2635 2387 if (!file) 2636 2388 goto err; 2637 - 2389 + if (is_ab8540(ab8500)) { 2390 + file = debugfs_create_file("xtal_temp", (S_IRUGO | S_IWUGO), 2391 + ab8500_gpadc_dir, &plf->dev, &ab8540_gpadc_xtal_temp_fops); 2392 + if (!file) 2393 + goto err; 2394 + file = debugfs_create_file("vbattruemeas", (S_IRUGO | S_IWUGO), 2395 + ab8500_gpadc_dir, &plf->dev, 2396 + &ab8540_gpadc_vbat_true_meas_fops); 2397 + if (!file) 2398 + goto err; 2399 + file = debugfs_create_file("batctrl_and_ibat", 2400 + (S_IRUGO | S_IWUGO), ab8500_gpadc_dir, 2401 + &plf->dev, &ab8540_gpadc_bat_ctrl_and_ibat_fops); 2402 + if (!file) 2403 + goto err; 2404 + file = debugfs_create_file("vbatmeas_and_ibat", 2405 + (S_IRUGO | S_IWUGO), ab8500_gpadc_dir, 2406 + &plf->dev, 2407 + &ab8540_gpadc_vbat_meas_and_ibat_fops); 2408 + if (!file) 2409 + goto err; 2410 + file = debugfs_create_file("vbattruemeas_and_ibat", 2411 + (S_IRUGO | S_IWUGO), ab8500_gpadc_dir, 2412 + &plf->dev, 2413 + &ab8540_gpadc_vbat_true_meas_and_ibat_fops); 2414 + if (!file) 2415 + goto err; 2416 + file = debugfs_create_file("battemp_and_ibat", 2417 + (S_IRUGO | S_IWUGO), ab8500_gpadc_dir, 2418 + &plf->dev, &ab8540_gpadc_bat_temp_and_ibat_fops); 2419 + if (!file) 2420 + goto err; 2421 + file = debugfs_create_file("otp_calib", (S_IRUGO | S_IWUGO), 2422 + ab8500_gpadc_dir, &plf->dev, &ab8540_gpadc_otp_calib_fops); 2423 + if (!file) 2424 + goto err; 2425 + } 2638 2426 file = debugfs_create_file("avg_sample", (S_IRUGO | S_IWUGO), 2639 2427 ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_avg_sample_fops); 2640 2428 if (!file)
+44
drivers/mfd/ab8500-gpadc.c
··· 135 135 struct adc_cal_data { 136 136 s64 gain; 137 137 s64 offset; 138 + u16 otp_calib_hi; 139 + u16 otp_calib_lo; 138 140 }; 139 141 140 142 /** ··· 831 829 vmain_high = (((gpadc_cal[1] & 0xFF) << 2) | 832 830 ((gpadc_cal[2] & 0xC0) >> 6)); 833 831 vmain_low = ((gpadc_cal[2] & 0x3E) >> 1); 832 + 833 + gpadc->cal_data[ADC_INPUT_VMAIN].otp_calib_hi = 834 + (u16)vmain_high; 835 + gpadc->cal_data[ADC_INPUT_VMAIN].otp_calib_lo = 836 + (u16)vmain_low; 837 + 834 838 gpadc->cal_data[ADC_INPUT_VMAIN].gain = CALIB_SCALE * 835 839 (19500 - 315) / (vmain_high - vmain_low); 836 840 gpadc->cal_data[ADC_INPUT_VMAIN].offset = CALIB_SCALE * ··· 863 855 ((gpadc_otp4[1] & 0xFE) >> 1)); 864 856 ibat_low = (((gpadc_otp4[1] & 0x01) << 5) | 865 857 ((gpadc_otp4[2] & 0xF8) >> 3)); 858 + 859 + gpadc->cal_data[ADC_INPUT_IBAT].otp_calib_hi = 860 + (u16)ibat_high; 861 + gpadc->cal_data[ADC_INPUT_IBAT].otp_calib_lo = 862 + (u16)ibat_low; 866 863 867 864 V_gain = ((IBAT_VDROP_H - IBAT_VDROP_L) 868 865 << CALIB_SHIFT_IBAT) / (ibat_high - ibat_low); ··· 905 892 ((gpadc_cal[2] & 0xC0) >> 6)); 906 893 vmain_low = ((gpadc_cal[2] & 0x3E) >> 1); 907 894 895 + gpadc->cal_data[ADC_INPUT_VMAIN].otp_calib_hi = 896 + (u16)vmain_high; 897 + gpadc->cal_data[ADC_INPUT_VMAIN].otp_calib_lo = 898 + (u16)vmain_low; 899 + 908 900 gpadc->cal_data[ADC_INPUT_VMAIN].gain = CALIB_SCALE * 909 901 (19500 - 315) / (vmain_high - vmain_low); 910 902 ··· 920 902 gpadc->cal_data[ADC_INPUT_VMAIN].gain = 0; 921 903 } 922 904 } 905 + 923 906 /* Calculate gain and offset for BTEMP if all reads succeeded */ 924 907 if (!(ret[2] < 0 || ret[3] < 0 || ret[4] < 0)) { 925 908 btemp_high = (((gpadc_cal[2] & 0x01) << 9) | 926 909 (gpadc_cal[3] << 1) | ((gpadc_cal[4] & 0x80) >> 7)); 927 910 btemp_low = ((gpadc_cal[4] & 0x7C) >> 2); 911 + 912 + gpadc->cal_data[ADC_INPUT_BTEMP].otp_calib_hi = (u16)btemp_high; 913 + gpadc->cal_data[ADC_INPUT_BTEMP].otp_calib_lo = (u16)btemp_low; 928 914 929 915 gpadc->cal_data[ADC_INPUT_BTEMP].gain = 930 916 CALIB_SCALE * (1300 - 21) / (btemp_high - btemp_low); ··· 943 921 if (!(ret[4] < 0 || ret[5] < 0 || ret[6] < 0)) { 944 922 vbat_high = (((gpadc_cal[4] & 0x03) << 8) | gpadc_cal[5]); 945 923 vbat_low = ((gpadc_cal[6] & 0xFC) >> 2); 924 + 925 + gpadc->cal_data[ADC_INPUT_VBAT].otp_calib_hi = (u16)vbat_high; 926 + gpadc->cal_data[ADC_INPUT_VBAT].otp_calib_lo = (u16)vbat_low; 946 927 947 928 gpadc->cal_data[ADC_INPUT_VBAT].gain = CALIB_SCALE * 948 929 (4700 - 2380) / (vbat_high - vbat_low); ··· 1154 1129 static void __exit ab8500_gpadc_exit(void) 1155 1130 { 1156 1131 platform_driver_unregister(&ab8500_gpadc_driver); 1132 + } 1133 + 1134 + /** 1135 + * ab8540_gpadc_get_otp() - returns OTP values 1136 + * 1137 + */ 1138 + void ab8540_gpadc_get_otp(struct ab8500_gpadc *gpadc, 1139 + u16 *vmain_l, u16 *vmain_h, u16 *btemp_l, u16 *btemp_h, 1140 + u16 *vbat_l, u16 *vbat_h, u16 *ibat_l, u16 *ibat_h) 1141 + { 1142 + *vmain_l = gpadc->cal_data[ADC_INPUT_VMAIN].otp_calib_lo; 1143 + *vmain_h = gpadc->cal_data[ADC_INPUT_VMAIN].otp_calib_hi; 1144 + *btemp_l = gpadc->cal_data[ADC_INPUT_BTEMP].otp_calib_lo; 1145 + *btemp_h = gpadc->cal_data[ADC_INPUT_BTEMP].otp_calib_hi; 1146 + *vbat_l = gpadc->cal_data[ADC_INPUT_VBAT].otp_calib_lo; 1147 + *vbat_h = gpadc->cal_data[ADC_INPUT_VBAT].otp_calib_hi; 1148 + *ibat_l = gpadc->cal_data[ADC_INPUT_IBAT].otp_calib_lo; 1149 + *ibat_h = gpadc->cal_data[ADC_INPUT_IBAT].otp_calib_hi; 1150 + return ; 1157 1151 } 1158 1152 1159 1153 subsys_initcall_sync(ab8500_gpadc_init);
+3
include/linux/mfd/abx500/ab8500-gpadc.h
··· 68 68 int *ibat); 69 69 int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, 70 70 u8 channel, int ad_value); 71 + void ab8540_gpadc_get_otp(struct ab8500_gpadc *gpadc, 72 + u16 *vmain_l, u16 *vmain_h, u16 *btemp_l, u16 *btemp_h, 73 + u16 *vbat_l, u16 *vbat_h, u16 *ibat_l, u16 *ibat_h); 71 74 72 75 #endif /* _AB8500_GPADC_H */