1313#include <linux/usb/typec.h>
1414#include <linux/usb/typec_mux.h>
1515
16- struct typec_mode {
17- int index ;
16+ struct typec_altmode {
17+ struct device dev ;
18+ u16 svid ;
19+ u8 mode ;
20+
1821 u32 vdo ;
1922 char * desc ;
2023 enum typec_port_type roles ;
21-
22- struct typec_altmode * alt_mode ;
23-
2424 unsigned int active :1 ;
2525
26+ struct attribute * attrs [5 ];
2627 char group_name [6 ];
2728 struct attribute_group group ;
28- struct attribute * attrs [5 ];
29- struct device_attribute vdo_attr ;
30- struct device_attribute desc_attr ;
31- struct device_attribute active_attr ;
32- struct device_attribute roles_attr ;
33- };
34-
35- struct typec_altmode {
36- struct device dev ;
37- u16 svid ;
38- int n_modes ;
39- struct typec_mode modes [ALTMODE_MAX_MODES ];
40- const struct attribute_group * mode_groups [ALTMODE_MAX_MODES ];
29+ const struct attribute_group * groups [2 ];
4130};
4231
4332struct typec_plug {
@@ -177,23 +166,20 @@ static void typec_report_identity(struct device *dev)
177166/**
178167 * typec_altmode_update_active - Report Enter/Exit mode
179168 * @alt: Handle to the alternate mode
180- * @mode: Mode index
181169 * @active: True when the mode has been entered
182170 *
183171 * If a partner or cable plug executes Enter/Exit Mode command successfully, the
184172 * drivers use this routine to report the updated state of the mode.
185173 */
186- void typec_altmode_update_active (struct typec_altmode * alt , int mode ,
187- bool active )
174+ void typec_altmode_update_active (struct typec_altmode * alt , bool active )
188175{
189- struct typec_mode * m = & alt -> modes [mode ];
190176 char dir [6 ];
191177
192- if (m -> active == active )
178+ if (alt -> active == active )
193179 return ;
194180
195- m -> active = active ;
196- snprintf (dir , sizeof (dir ), "mode%d" , mode );
181+ alt -> active = active ;
182+ snprintf (dir , sizeof (dir ), "mode%d" , alt -> mode );
197183 sysfs_notify (& alt -> dev .kobj , dir , "active" );
198184 kobject_uevent (& alt -> dev .kobj , KOBJ_CHANGE );
199185}
@@ -220,42 +206,36 @@ struct typec_port *typec_altmode2port(struct typec_altmode *alt)
220206EXPORT_SYMBOL_GPL (typec_altmode2port );
221207
222208static ssize_t
223- typec_altmode_vdo_show (struct device * dev , struct device_attribute * attr ,
224- char * buf )
209+ vdo_show (struct device * dev , struct device_attribute * attr , char * buf )
225210{
226- struct typec_mode * mode = container_of (attr , struct typec_mode ,
227- vdo_attr );
211+ struct typec_altmode * alt = to_altmode (dev );
228212
229- return sprintf (buf , "0x%08x\n" , mode -> vdo );
213+ return sprintf (buf , "0x%08x\n" , alt -> vdo );
230214}
215+ static DEVICE_ATTR_RO (vdo );
231216
232217static ssize_t
233- typec_altmode_desc_show (struct device * dev , struct device_attribute * attr ,
234- char * buf )
218+ description_show (struct device * dev , struct device_attribute * attr , char * buf )
235219{
236- struct typec_mode * mode = container_of (attr , struct typec_mode ,
237- desc_attr );
220+ struct typec_altmode * alt = to_altmode (dev );
238221
239- return sprintf (buf , "%s\n" , mode -> desc ? mode -> desc : "" );
222+ return sprintf (buf , "%s\n" , alt -> desc ? alt -> desc : "" );
240223}
224+ static DEVICE_ATTR_RO (description );
241225
242226static ssize_t
243- typec_altmode_active_show (struct device * dev , struct device_attribute * attr ,
244- char * buf )
227+ active_show (struct device * dev , struct device_attribute * attr , char * buf )
245228{
246- struct typec_mode * mode = container_of (attr , struct typec_mode ,
247- active_attr );
229+ struct typec_altmode * alt = to_altmode (dev );
248230
249- return sprintf (buf , "%s\n" , mode -> active ? "yes" : "no" );
231+ return sprintf (buf , "%s\n" , alt -> active ? "yes" : "no" );
250232}
251233
252- static ssize_t
253- typec_altmode_active_store (struct device * dev , struct device_attribute * attr ,
254- const char * buf , size_t size )
234+ static ssize_t active_store (struct device * dev , struct device_attribute * attr ,
235+ const char * buf , size_t size )
255236{
256- struct typec_mode * mode = container_of (attr , struct typec_mode ,
257- active_attr );
258- struct typec_port * port = typec_altmode2port (mode -> alt_mode );
237+ struct typec_altmode * alt = to_altmode (dev );
238+ struct typec_port * port = typec_altmode2port (alt );
259239 bool activate ;
260240 int ret ;
261241
@@ -266,22 +246,22 @@ typec_altmode_active_store(struct device *dev, struct device_attribute *attr,
266246 if (ret )
267247 return ret ;
268248
269- ret = port -> cap -> activate_mode (port -> cap , mode -> index , activate );
249+ ret = port -> cap -> activate_mode (port -> cap , alt -> mode , activate );
270250 if (ret )
271251 return ret ;
272252
273253 return size ;
274254}
255+ static DEVICE_ATTR_RW (active );
275256
276257static ssize_t
277- typec_altmode_roles_show (struct device * dev , struct device_attribute * attr ,
278- char * buf )
258+ supported_roles_show (struct device * dev , struct device_attribute * attr ,
259+ char * buf )
279260{
280- struct typec_mode * mode = container_of (attr , struct typec_mode ,
281- roles_attr );
261+ struct typec_altmode * alt = to_altmode (dev );
282262 ssize_t ret ;
283263
284- switch (mode -> roles ) {
264+ switch (alt -> roles ) {
285265 case TYPEC_PORT_SRC :
286266 ret = sprintf (buf , "source\n" );
287267 break ;
@@ -295,61 +275,13 @@ typec_altmode_roles_show(struct device *dev, struct device_attribute *attr,
295275 }
296276 return ret ;
297277}
278+ static DEVICE_ATTR_RO (supported_roles );
298279
299- static void typec_init_modes (struct typec_altmode * alt ,
300- const struct typec_mode_desc * desc , bool is_port )
280+ static void typec_altmode_release (struct device * dev )
301281{
302- int i ;
303-
304- for (i = 0 ; i < alt -> n_modes ; i ++ , desc ++ ) {
305- struct typec_mode * mode = & alt -> modes [i ];
306-
307- /* Not considering the human readable description critical */
308- mode -> desc = kstrdup (desc -> desc , GFP_KERNEL );
309- if (desc -> desc && !mode -> desc )
310- dev_err (& alt -> dev , "failed to copy mode%d desc\n" , i );
311-
312- mode -> alt_mode = alt ;
313- mode -> vdo = desc -> vdo ;
314- mode -> roles = desc -> roles ;
315- mode -> index = desc -> index ;
316- sprintf (mode -> group_name , "mode%d" , desc -> index );
317-
318- sysfs_attr_init (& mode -> vdo_attr .attr );
319- mode -> vdo_attr .attr .name = "vdo" ;
320- mode -> vdo_attr .attr .mode = 0444 ;
321- mode -> vdo_attr .show = typec_altmode_vdo_show ;
322-
323- sysfs_attr_init (& mode -> desc_attr .attr );
324- mode -> desc_attr .attr .name = "description" ;
325- mode -> desc_attr .attr .mode = 0444 ;
326- mode -> desc_attr .show = typec_altmode_desc_show ;
327-
328- sysfs_attr_init (& mode -> active_attr .attr );
329- mode -> active_attr .attr .name = "active" ;
330- mode -> active_attr .attr .mode = 0644 ;
331- mode -> active_attr .show = typec_altmode_active_show ;
332- mode -> active_attr .store = typec_altmode_active_store ;
333-
334- mode -> attrs [0 ] = & mode -> vdo_attr .attr ;
335- mode -> attrs [1 ] = & mode -> desc_attr .attr ;
336- mode -> attrs [2 ] = & mode -> active_attr .attr ;
337-
338- /* With ports, list the roles that the mode is supported with */
339- if (is_port ) {
340- sysfs_attr_init (& mode -> roles_attr .attr );
341- mode -> roles_attr .attr .name = "supported_roles" ;
342- mode -> roles_attr .attr .mode = 0444 ;
343- mode -> roles_attr .show = typec_altmode_roles_show ;
344-
345- mode -> attrs [3 ] = & mode -> roles_attr .attr ;
346- }
347-
348- mode -> group .attrs = mode -> attrs ;
349- mode -> group .name = mode -> group_name ;
282+ struct typec_altmode * alt = to_altmode (dev );
350283
351- alt -> mode_groups [i ] = & mode -> group ;
352- }
284+ kfree (alt );
353285}
354286
355287static ssize_t svid_show (struct device * dev , struct device_attribute * attr ,
@@ -367,16 +299,6 @@ static struct attribute *typec_altmode_attrs[] = {
367299};
368300ATTRIBUTE_GROUPS (typec_altmode );
369301
370- static void typec_altmode_release (struct device * dev )
371- {
372- struct typec_altmode * alt = to_altmode (dev );
373- int i ;
374-
375- for (i = 0 ; i < alt -> n_modes ; i ++ )
376- kfree (alt -> modes [i ].desc );
377- kfree (alt );
378- }
379-
380302static const struct device_type typec_altmode_dev_type = {
381303 .name = "typec_alternate_mode" ,
382304 .groups = typec_altmode_groups ,
@@ -395,13 +317,27 @@ typec_register_altmode(struct device *parent,
395317 return ERR_PTR (- ENOMEM );
396318
397319 alt -> svid = desc -> svid ;
398- alt -> n_modes = desc -> n_modes ;
399- typec_init_modes (alt , desc -> modes , is_typec_port (parent ));
320+ alt -> mode = desc -> mode ;
321+ alt -> vdo = desc -> vdo ;
322+ alt -> roles = desc -> roles ;
323+
324+ alt -> attrs [0 ] = & dev_attr_vdo .attr ;
325+ alt -> attrs [1 ] = & dev_attr_description .attr ;
326+ alt -> attrs [2 ] = & dev_attr_active .attr ;
327+
328+ if (is_typec_port (parent ))
329+ alt -> attrs [3 ] = & dev_attr_supported_roles .attr ;
330+
331+ sprintf (alt -> group_name , "mode%d" , desc -> mode );
332+ alt -> group .name = alt -> group_name ;
333+ alt -> group .attrs = alt -> attrs ;
334+ alt -> groups [0 ] = & alt -> group ;
400335
401336 alt -> dev .parent = parent ;
402- alt -> dev .groups = alt -> mode_groups ;
337+ alt -> dev .groups = alt -> groups ;
403338 alt -> dev .type = & typec_altmode_dev_type ;
404- dev_set_name (& alt -> dev , "svid-%04x" , alt -> svid );
339+ dev_set_name (& alt -> dev , "%s-%04x:%u" , dev_name (parent ),
340+ alt -> svid , alt -> mode );
405341
406342 ret = device_register (& alt -> dev );
407343 if (ret ) {
0 commit comments