14
14
#include <linux/dmi.h>
15
15
#include <linux/slab.h>
16
16
#include <linux/module.h>
17
+ #include <linux/i2c.h>
17
18
#include <linux/input.h>
18
19
#include <linux/input/mt.h>
20
+ #include <linux/platform_device.h>
19
21
#include <linux/serio.h>
20
22
#include <linux/libps2.h>
21
23
#include <asm/unaligned.h>
22
24
#include "psmouse.h"
23
25
#include "elantech.h"
26
+ #include "elan_i2c.h"
24
27
25
28
#define elantech_debug (fmt , ...) \
26
29
do { \
@@ -1084,7 +1087,8 @@ static unsigned int elantech_convert_res(unsigned int val)
1084
1087
1085
1088
static int elantech_get_resolution_v4 (struct psmouse * psmouse ,
1086
1089
unsigned int * x_res ,
1087
- unsigned int * y_res )
1090
+ unsigned int * y_res ,
1091
+ unsigned int * bus )
1088
1092
{
1089
1093
unsigned char param [3 ];
1090
1094
@@ -1093,6 +1097,7 @@ static int elantech_get_resolution_v4(struct psmouse *psmouse,
1093
1097
1094
1098
* x_res = elantech_convert_res (param [1 ] & 0x0f );
1095
1099
* y_res = elantech_convert_res ((param [1 ] & 0xf0 ) >> 4 );
1100
+ * bus = param [2 ];
1096
1101
1097
1102
return 0 ;
1098
1103
}
@@ -1474,6 +1479,12 @@ static void elantech_disconnect(struct psmouse *psmouse)
1474
1479
{
1475
1480
struct elantech_data * etd = psmouse -> private ;
1476
1481
1482
+ /*
1483
+ * We might have left a breadcrumb when trying to
1484
+ * set up SMbus companion.
1485
+ */
1486
+ psmouse_smbus_cleanup (psmouse );
1487
+
1477
1488
if (etd -> tp_dev )
1478
1489
input_unregister_device (etd -> tp_dev );
1479
1490
sysfs_remove_group (& psmouse -> ps2dev .serio -> dev .kobj ,
@@ -1659,6 +1670,8 @@ static int elantech_query_info(struct psmouse *psmouse,
1659
1670
{
1660
1671
unsigned char param [3 ];
1661
1672
1673
+ memset (info , 0 , sizeof (* info ));
1674
+
1662
1675
/*
1663
1676
* Do the version query again so we can store the result
1664
1677
*/
@@ -1717,7 +1730,8 @@ static int elantech_query_info(struct psmouse *psmouse,
1717
1730
if (info -> hw_version == 4 ) {
1718
1731
if (elantech_get_resolution_v4 (psmouse ,
1719
1732
& info -> x_res ,
1720
- & info -> y_res )) {
1733
+ & info -> y_res ,
1734
+ & info -> bus )) {
1721
1735
psmouse_warn (psmouse ,
1722
1736
"failed to query resolution data.\n" );
1723
1737
}
@@ -1726,6 +1740,129 @@ static int elantech_query_info(struct psmouse *psmouse,
1726
1740
return 0 ;
1727
1741
}
1728
1742
1743
+ #if defined(CONFIG_MOUSE_PS2_ELANTECH_SMBUS )
1744
+
1745
+ /*
1746
+ * The newest Elantech device can use a secondary bus (over SMBus) which
1747
+ * provides a better bandwidth and allow a better control of the touchpads.
1748
+ * This is used to decide if we need to use this bus or not.
1749
+ */
1750
+ enum {
1751
+ ELANTECH_SMBUS_NOT_SET = -1 ,
1752
+ ELANTECH_SMBUS_OFF ,
1753
+ ELANTECH_SMBUS_ON ,
1754
+ };
1755
+
1756
+ static int elantech_smbus = IS_ENABLED (CONFIG_MOUSE_ELAN_I2C_SMBUS ) ?
1757
+ ELANTECH_SMBUS_NOT_SET : ELANTECH_SMBUS_OFF ;
1758
+ module_param_named (elantech_smbus , elantech_smbus , int , 0644 );
1759
+ MODULE_PARM_DESC (elantech_smbus , "Use a secondary bus for the Elantech device." );
1760
+
1761
+ static int elantech_create_smbus (struct psmouse * psmouse ,
1762
+ struct elantech_device_info * info ,
1763
+ bool leave_breadcrumbs )
1764
+ {
1765
+ const struct property_entry i2c_properties [] = {
1766
+ PROPERTY_ENTRY_BOOL ("elan,trackpoint" ),
1767
+ { },
1768
+ };
1769
+ struct i2c_board_info smbus_board = {
1770
+ I2C_BOARD_INFO ("elan_i2c" , 0x15 ),
1771
+ .flags = I2C_CLIENT_HOST_NOTIFY ,
1772
+ };
1773
+
1774
+ if (info -> has_trackpoint )
1775
+ smbus_board .properties = i2c_properties ;
1776
+
1777
+ return psmouse_smbus_init (psmouse , & smbus_board , NULL , 0 ,
1778
+ leave_breadcrumbs );
1779
+ }
1780
+
1781
+ /**
1782
+ * elantech_setup_smbus - called once the PS/2 devices are enumerated
1783
+ * and decides to instantiate a SMBus InterTouch device.
1784
+ */
1785
+ static int elantech_setup_smbus (struct psmouse * psmouse ,
1786
+ struct elantech_device_info * info ,
1787
+ bool leave_breadcrumbs )
1788
+ {
1789
+ int error ;
1790
+
1791
+ if (elantech_smbus == ELANTECH_SMBUS_OFF )
1792
+ return - ENXIO ;
1793
+
1794
+ if (elantech_smbus == ELANTECH_SMBUS_NOT_SET ) {
1795
+ /*
1796
+ * FIXME:
1797
+ * constraint the I2C capable devices by using FW version,
1798
+ * board version, or by using DMI matching
1799
+ */
1800
+ return - ENXIO ;
1801
+ }
1802
+
1803
+ psmouse_info (psmouse , "Trying to set up SMBus access\n" );
1804
+
1805
+ error = elantech_create_smbus (psmouse , info , leave_breadcrumbs );
1806
+ if (error ) {
1807
+ if (error == - EAGAIN )
1808
+ psmouse_info (psmouse , "SMbus companion is not ready yet\n" );
1809
+ else
1810
+ psmouse_err (psmouse , "unable to create intertouch device\n" );
1811
+
1812
+ return error ;
1813
+ }
1814
+
1815
+ return 0 ;
1816
+ }
1817
+
1818
+ static bool elantech_use_host_notify (struct psmouse * psmouse ,
1819
+ struct elantech_device_info * info )
1820
+ {
1821
+ switch (info -> bus ) {
1822
+ case ETP_BUS_PS2_ONLY :
1823
+ /* expected case */
1824
+ break ;
1825
+ case ETP_BUS_SMB_ALERT_ONLY :
1826
+ /* fall-through */
1827
+ case ETP_BUS_PS2_SMB_ALERT :
1828
+ psmouse_dbg (psmouse , "Ignoring SMBus provider through alert protocol.\n" );
1829
+ break ;
1830
+ case ETP_BUS_SMB_HST_NTFY_ONLY :
1831
+ /* fall-through */
1832
+ case ETP_BUS_PS2_SMB_HST_NTFY :
1833
+ return true;
1834
+ default :
1835
+ psmouse_dbg (psmouse ,
1836
+ "Ignoring SMBus bus provider %d.\n" ,
1837
+ info -> bus );
1838
+ }
1839
+
1840
+ return false;
1841
+ }
1842
+
1843
+ int elantech_init_smbus (struct psmouse * psmouse )
1844
+ {
1845
+ struct elantech_device_info info ;
1846
+ int error = - EINVAL ;
1847
+
1848
+ psmouse_reset (psmouse );
1849
+
1850
+ error = elantech_query_info (psmouse , & info );
1851
+ if (error )
1852
+ goto init_fail ;
1853
+
1854
+ if (info .hw_version < 4 ) {
1855
+ error = - ENXIO ;
1856
+ goto init_fail ;
1857
+ }
1858
+
1859
+ return elantech_create_smbus (psmouse , & info , false);
1860
+ init_fail :
1861
+ psmouse_reset (psmouse );
1862
+ return error ;
1863
+ }
1864
+ #endif /* CONFIG_MOUSE_PS2_ELANTECH_SMBUS */
1865
+
1729
1866
/*
1730
1867
* Initialize the touchpad and create sysfs entries
1731
1868
*/
@@ -1734,7 +1871,7 @@ static int elantech_setup_ps2(struct psmouse *psmouse,
1734
1871
{
1735
1872
struct elantech_data * etd ;
1736
1873
int i ;
1737
- int error ;
1874
+ int error = - EINVAL ;
1738
1875
struct input_dev * tp_dev ;
1739
1876
1740
1877
psmouse -> private = etd = kzalloc (sizeof (* etd ), GFP_KERNEL );
@@ -1821,7 +1958,7 @@ static int elantech_setup_ps2(struct psmouse *psmouse,
1821
1958
return error ;
1822
1959
}
1823
1960
1824
- int elantech_init (struct psmouse * psmouse )
1961
+ int elantech_init_ps2 (struct psmouse * psmouse )
1825
1962
{
1826
1963
struct elantech_device_info info ;
1827
1964
int error = - EINVAL ;
@@ -1841,3 +1978,46 @@ int elantech_init(struct psmouse *psmouse)
1841
1978
psmouse_reset (psmouse );
1842
1979
return error ;
1843
1980
}
1981
+
1982
+ int elantech_init (struct psmouse * psmouse )
1983
+ {
1984
+ struct elantech_device_info info ;
1985
+ int error = - EINVAL ;
1986
+
1987
+ psmouse_reset (psmouse );
1988
+
1989
+ error = elantech_query_info (psmouse , & info );
1990
+ if (error )
1991
+ goto init_fail ;
1992
+
1993
+ #if defined(CONFIG_MOUSE_PS2_ELANTECH_SMBUS )
1994
+
1995
+ if (elantech_use_host_notify (psmouse , & info )) {
1996
+ if (!IS_ENABLED (CONFIG_MOUSE_ELAN_I2C_SMBUS ) ||
1997
+ !IS_ENABLED (CONFIG_MOUSE_PS2_ELANTECH_SMBUS )) {
1998
+ psmouse_warn (psmouse ,
1999
+ "The touchpad can support a better bus than the too old PS/2 protocol. "
2000
+ "Make sure MOUSE_PS2_ELANTECH_SMBUS and MOUSE_ELAN_I2C_SMBUS are enabled to get a better touchpad experience.\n" );
2001
+ }
2002
+ error = elantech_setup_smbus (psmouse , & info , true);
2003
+ if (!error )
2004
+ return PSMOUSE_ELANTECH_SMBUS ;
2005
+ }
2006
+
2007
+ #endif /* CONFIG_MOUSE_PS2_ELANTECH_SMBUS */
2008
+
2009
+ error = elantech_setup_ps2 (psmouse , & info );
2010
+ if (error < 0 ) {
2011
+ /*
2012
+ * Not using any flavor of Elantech support, so clean up
2013
+ * SMbus breadcrumbs, if any.
2014
+ */
2015
+ psmouse_smbus_cleanup (psmouse );
2016
+ goto init_fail ;
2017
+ }
2018
+
2019
+ return PSMOUSE_ELANTECH ;
2020
+ init_fail :
2021
+ psmouse_reset (psmouse );
2022
+ return error ;
2023
+ }
0 commit comments