1919#include <linux/usb/role.h>
2020#include <linux/workqueue.h>
2121#include <linux/firmware.h>
22+ #include <linux/sysfs.h>
23+ #include <linux/string.h>
2224
2325#include "tps6598x.h"
2426#include "trace.h"
4345#define TPS_REG_POWER_STATUS 0x3f
4446#define TPS_REG_PD_STATUS 0x40
4547#define TPS_REG_RX_IDENTITY_SOP 0x48
48+ #define TPS_REG_TX_VDM 0x4d
4649#define TPS_REG_DATA_STATUS 0x5f
4750#define TPS_REG_SLEEP_CONF 0x70
4851
9598 TPS_MODE_BIST ,
9699 TPS_MODE_DISC ,
97100 TPS_MODE_PTCH ,
101+ CD_MODE_DBMA ,
98102};
99103
100104static const char * const modes [] = {
@@ -103,11 +107,14 @@ static const char *const modes[] = {
103107 [TPS_MODE_BIST ] = "BIST" ,
104108 [TPS_MODE_DISC ] = "DISC" ,
105109 [TPS_MODE_PTCH ] = "PTCH" ,
110+ [CD_MODE_DBMA ] = "DBMa" ,
106111};
107112
108113/* Unrecognized commands will be replaced with "!CMD" */
109114#define INVALID_CMD (_cmd_ ) (_cmd_ == 0x444d4321)
110115
116+ #define TPS_VDMS_MAX_LEN (7 * 4 + 1)
117+
111118struct tps6598x ;
112119
113120struct tipd_data {
@@ -125,6 +132,7 @@ struct tps6598x {
125132 struct regmap * regmap ;
126133 struct mutex lock ; /* device lock */
127134 u8 i2c_protocol :1 ;
135+ u8 cd321x_unlocked :1 ;
128136
129137 struct gpio_desc * reset ;
130138 struct typec_port * port ;
@@ -726,6 +734,8 @@ static int tps6598x_check_mode(struct tps6598x *tps)
726734 return ret ;
727735 case TPS_MODE_BIST :
728736 case TPS_MODE_DISC :
737+ case CD_MODE_DBMA :
738+ return ret ;
729739 default :
730740 dev_err (tps -> dev , "controller in unsupported mode \"%s\"\n" ,
731741 mode );
@@ -1193,6 +1203,175 @@ static int tps6598x_apply_patch(struct tps6598x *tps)
11931203 return ret ;
11941204}
11951205
1206+
1207+ static ssize_t lock_show (struct device * dev , struct device_attribute * attr ,
1208+ char * buf )
1209+ {
1210+ struct i2c_client * client = to_i2c_client (dev );
1211+ struct tps6598x * tps = i2c_get_clientdata (client );
1212+
1213+ if (tps -> cd321x_unlocked )
1214+ return sysfs_emit (buf , "unlocked\n" );
1215+ else
1216+ return sysfs_emit (buf , "locked\n" );
1217+ }
1218+ static DEVICE_ATTR_RO (lock );
1219+
1220+ static ssize_t mode_show (struct device * dev , struct device_attribute * attr ,
1221+ char * buf )
1222+ {
1223+ struct i2c_client * client = to_i2c_client (dev );
1224+ struct tps6598x * tps = i2c_get_clientdata (client );
1225+
1226+ int mode = tps6598x_check_mode (tps );
1227+ switch (mode ) {
1228+ case TPS_MODE_APP ... CD_MODE_DBMA :
1229+ return sysfs_emit (buf , "%s\n" , modes [mode ]);
1230+ default :
1231+ return sysfs_emit (buf , "unkown\n" );
1232+ }
1233+ }
1234+ static DEVICE_ATTR_RO (mode );
1235+
1236+ static ssize_t power_status_show (struct device * dev ,
1237+ struct device_attribute * attr , char * buf )
1238+ {
1239+ struct i2c_client * client = to_i2c_client (dev );
1240+ struct tps6598x * tps = i2c_get_clientdata (client );
1241+
1242+ return sysfs_emit (buf , "0x%04hx\n" , tps -> pwr_status );
1243+ }
1244+ static DEVICE_ATTR_RO (power_status );
1245+
1246+ /* this assumes cd321x has a customized UnlockCode */
1247+ static ssize_t commad_lock (struct tps6598x * tps , const char * buf , size_t count )
1248+ {
1249+ const char default_code [4 ] = { 0 , 0 , 0 , 0 };
1250+ int ret ;
1251+
1252+ if (count < 4 )
1253+ return - EINVAL ;
1254+
1255+ ret = tps6598x_exec_cmd (tps , "LOCK" , 4 , buf , 0 , NULL );
1256+ if (ret )
1257+ dev_err (tps -> dev , "Unlock command failed: %d\n" , ret );
1258+ else
1259+ /* Key 0 locks cd321x when UnlockCode is customized */
1260+ tps -> cd321x_unlocked = !!memcmp (buf , default_code , 4 );
1261+
1262+ return count ;
1263+ }
1264+
1265+ static ssize_t commad_dbma (struct tps6598x * tps , const char * buf , size_t count )
1266+ {
1267+ int ret , mode ;
1268+ bool enable ;
1269+
1270+ if (count < 1 )
1271+ return - EINVAL ;
1272+
1273+ enable = buf [0 ] != 0 ;
1274+
1275+ if (enable && !tps -> cd321x_unlocked )
1276+ return - EINVAL ;
1277+
1278+ ret = tps6598x_exec_cmd (tps , "DBMa" , 1 , buf , 0 , NULL );
1279+ if (ret ) {
1280+ dev_err (tps -> dev , "Failed to exec 'DBMa' command: %d\n" , ret );
1281+ return ret ;
1282+ }
1283+
1284+ mode = tps6598x_check_mode (tps );
1285+ if (enable && mode != CD_MODE_DBMA ) {
1286+ dev_err (tps -> dev , "CD321x failed to enter \"DBMa\" mode\n" );
1287+ return - EIO ;
1288+ } else if (!enable && mode != TPS_MODE_APP ) {
1289+ dev_err (tps -> dev , "CD321x failed to exit \"DBMa\" mode\n" );
1290+ return - EIO ;
1291+ }
1292+
1293+ return count ;
1294+ }
1295+
1296+ static ssize_t commad_vdms (struct tps6598x * tps , const char * buf , size_t count )
1297+ {
1298+ int ret ;
1299+
1300+ if (count < 5 || ((count - 1 ) % 4 ) != 0 || count > TPS_VDMS_MAX_LEN )
1301+ return - EINVAL ;
1302+
1303+ if (tps6598x_check_mode (tps ) != CD_MODE_DBMA )
1304+ return - EIO ;
1305+
1306+ ret = tps6598x_exec_cmd_tmo (tps , "VDMs" , count , buf , 0 , NULL , 200 , 200 );
1307+ if (ret ) {
1308+ dev_err (tps -> dev , "Sending VDM failed: %d\n" , ret );
1309+ return ret ;
1310+ }
1311+
1312+ return count ;
1313+ }
1314+
1315+ static ssize_t commad_devn (struct tps6598x * tps , const char * buf , size_t count )
1316+ {
1317+ int ret ;
1318+
1319+ if (count < 4 )
1320+ return - EINVAL ;
1321+
1322+ if (tps6598x_check_mode (tps ) != CD_MODE_DBMA )
1323+ return - EIO ;
1324+
1325+ ret = tps6598x_exec_cmd (tps , "DVEn" , 4 , buf , 0 , NULL );
1326+ if (ret )
1327+ dev_err (tps -> dev , "Could not enter local serial mode: %d\n" ,
1328+ ret );
1329+
1330+ return count ;
1331+ }
1332+
1333+ #define CMD_LEN 4
1334+ static ssize_t command_store (struct device * dev , struct device_attribute * attr ,
1335+ const char * buf , size_t count )
1336+ {
1337+ struct i2c_client * client = to_i2c_client (dev );
1338+ struct tps6598x * tps = i2c_get_clientdata (client );
1339+ int ret ;
1340+
1341+ if (count < CMD_LEN )
1342+ return - EINVAL ;
1343+
1344+ if (memcmp (buf , "LOCK" , CMD_LEN ) == 0 )
1345+ ret = commad_lock (tps , buf + 4 , count - 4 );
1346+ else if (memcmp (buf , "DBMa" , CMD_LEN ) == 0 )
1347+ ret = commad_dbma (tps , buf + 4 , count - 4 );
1348+ else if (memcmp (buf , "VDMs" , CMD_LEN ) == 0 )
1349+ ret = commad_vdms (tps , buf + 4 , count - 4 );
1350+ else if (memcmp (buf , "DEVn" , CMD_LEN ) == 0 )
1351+ ret = commad_devn (tps , buf + 4 , count - 4 );
1352+ else
1353+ return - EINVAL ;
1354+
1355+ if (ret < 0 )
1356+ return ret ;
1357+
1358+ return ret + CMD_LEN ;
1359+ }
1360+ static DEVICE_ATTR_WO (command );
1361+
1362+ static struct attribute * vdm_attrs [] = {
1363+ & dev_attr_lock .attr ,
1364+ & dev_attr_mode .attr ,
1365+ & dev_attr_power_status .attr ,
1366+ & dev_attr_command .attr ,
1367+ NULL ,
1368+ };
1369+
1370+ static const struct attribute_group vdm_group = {
1371+ .name = "cd321x_vdm" ,
1372+ .attrs = vdm_attrs ,
1373+ };
1374+
11961375static int cd321x_init (struct tps6598x * tps )
11971376{
11981377 return 0 ;
@@ -1433,6 +1612,14 @@ static int tps6598x_probe(struct i2c_client *client)
14331612 enable_irq_wake (client -> irq );
14341613 }
14351614
1615+ if (device_is_compatible (tps -> dev , "apple,cd321x" )) {
1616+ int err ;
1617+ err = sysfs_create_group (& client -> dev .kobj , & vdm_group );
1618+ if (err < 0 )
1619+ dev_err (tps -> dev , "Couldn't register sysfs group for "
1620+ "CD321x VDMs\n" );
1621+ }
1622+
14361623 return 0 ;
14371624
14381625err_disconnect :
@@ -1456,6 +1643,9 @@ static void tps6598x_remove(struct i2c_client *client)
14561643{
14571644 struct tps6598x * tps = i2c_get_clientdata (client );
14581645
1646+ if (device_is_compatible (tps -> dev , "apple,cd321x" ))
1647+ sysfs_remove_group (& client -> dev .kobj , & vdm_group );
1648+
14591649 if (!client -> irq )
14601650 cancel_delayed_work_sync (& tps -> wq_poll );
14611651 else
0 commit comments