@@ -77,6 +77,7 @@ static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
7777
7878#define TRANSCEIVER_PRESENT_ATTR_ID (index ) MODULE_PRESENT_##index
7979#define TRANSCEIVER_RESET_ATTR_ID (index ) MODULE_RESET_##index
80+ #define TRANSCEIVER_LPMODE_ATTR_ID (index ) MODULE_LPMODE_##index
8081#define TRANSCEIVER_TXDISABLE_ATTR_ID (index ) MODULE_TXDISABLE_##index
8182#define TRANSCEIVER_RXLOS_ATTR_ID (index ) MODULE_RXLOS_##index
8283
@@ -138,6 +139,32 @@ enum as7946_30xb_cpld_sysfs_attributes {
138139 TRANSCEIVER_RESET_ATTR_ID (24 ),
139140 TRANSCEIVER_RESET_ATTR_ID (25 ),
140141 TRANSCEIVER_RESET_ATTR_ID (26 ),
142+ TRANSCEIVER_LPMODE_ATTR_ID (1 ),
143+ TRANSCEIVER_LPMODE_ATTR_ID (2 ),
144+ TRANSCEIVER_LPMODE_ATTR_ID (3 ),
145+ TRANSCEIVER_LPMODE_ATTR_ID (4 ),
146+ TRANSCEIVER_LPMODE_ATTR_ID (5 ),
147+ TRANSCEIVER_LPMODE_ATTR_ID (6 ),
148+ TRANSCEIVER_LPMODE_ATTR_ID (7 ),
149+ TRANSCEIVER_LPMODE_ATTR_ID (8 ),
150+ TRANSCEIVER_LPMODE_ATTR_ID (9 ),
151+ TRANSCEIVER_LPMODE_ATTR_ID (10 ),
152+ TRANSCEIVER_LPMODE_ATTR_ID (11 ),
153+ TRANSCEIVER_LPMODE_ATTR_ID (12 ),
154+ TRANSCEIVER_LPMODE_ATTR_ID (13 ),
155+ TRANSCEIVER_LPMODE_ATTR_ID (14 ),
156+ TRANSCEIVER_LPMODE_ATTR_ID (15 ),
157+ TRANSCEIVER_LPMODE_ATTR_ID (16 ),
158+ TRANSCEIVER_LPMODE_ATTR_ID (17 ),
159+ TRANSCEIVER_LPMODE_ATTR_ID (18 ),
160+ TRANSCEIVER_LPMODE_ATTR_ID (19 ),
161+ TRANSCEIVER_LPMODE_ATTR_ID (20 ),
162+ TRANSCEIVER_LPMODE_ATTR_ID (21 ),
163+ TRANSCEIVER_LPMODE_ATTR_ID (22 ),
164+ TRANSCEIVER_LPMODE_ATTR_ID (23 ),
165+ TRANSCEIVER_LPMODE_ATTR_ID (24 ),
166+ TRANSCEIVER_LPMODE_ATTR_ID (25 ),
167+ TRANSCEIVER_LPMODE_ATTR_ID (26 ),
141168 TRANSCEIVER_TXDISABLE_ATTR_ID (27 ),
142169 TRANSCEIVER_TXDISABLE_ATTR_ID (28 ),
143170 TRANSCEIVER_TXDISABLE_ATTR_ID (29 ),
@@ -159,20 +186,24 @@ enum as7946_30xb_cpld_sysfs_attributes {
159186 static SENSOR_DEVICE_ATTR(module_present_##index, S_IRUGO, show_status, \
160187 NULL, MODULE_PRESENT_##index); \
161188 static SENSOR_DEVICE_ATTR(module_reset_##index, S_IRUGO | S_IWUSR, \
162- show_status, set_control, MODULE_RESET_##index)
189+ show_status, set_control, MODULE_RESET_##index); \
190+ static SENSOR_DEVICE_ATTR(module_lpmode_##index, S_IRUGO | S_IWUSR, \
191+ show_status, set_control, MODULE_LPMODE_##index);
163192#define DECLARE_QSFP28_TRANSCEIVER_ATTR (index ) \
164193 &sensor_dev_attr_module_present_##index.dev_attr.attr, \
165- &sensor_dev_attr_module_reset_##index.dev_attr.attr
166-
194+ &sensor_dev_attr_module_reset_##index.dev_attr.attr, \
195+ &sensor_dev_attr_module_lpmode_##index.dev_attr.attr
167196#define DECLARE_QSFPDD_TRANSCEIVER_SENSOR_DEVICE_ATTR (index ) \
168197 static SENSOR_DEVICE_ATTR(module_present_##index, S_IRUGO, \
169198 show_status, NULL, MODULE_PRESENT_##index); \
170199 static SENSOR_DEVICE_ATTR(module_reset_##index, S_IRUGO | S_IWUSR, \
171- show_status, set_control, MODULE_RESET_##index)
200+ show_status, set_control, MODULE_RESET_##index); \
201+ static SENSOR_DEVICE_ATTR(module_lpmode_##index, S_IRUGO | S_IWUSR, \
202+ show_status, set_control, MODULE_LPMODE_##index)
172203#define DECLARE_QSFPDD_TRANSCEIVER_ATTR (index ) \
173204 &sensor_dev_attr_module_present_##index.dev_attr.attr, \
174- &sensor_dev_attr_module_reset_##index.dev_attr.attr
175-
205+ &sensor_dev_attr_module_reset_##index.dev_attr.attr, \
206+ &sensor_dev_attr_module_lpmode_##index.dev_attr.attr
176207/* sfp transceiver attributes */
177208#define DECLARE_SFP_TRANSCEIVER_SENSOR_DEVICE_ATTR (index ) \
178209 static SENSOR_DEVICE_ATTR(module_present_##index, S_IRUGO, show_status, \
@@ -379,6 +410,26 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da,
379410 reg = 0x9 ;
380411 mask = 0x1 << (attr -> index - MODULE_RESET_25 );
381412 break ;
413+ case MODULE_LPMODE_1 ... MODULE_LPMODE_8 :
414+ reg = 0xC ;
415+ mask = 0x1 << (attr -> index - MODULE_LPMODE_1 );
416+ invert = 0 ;
417+ break ;
418+ case MODULE_LPMODE_9 ... MODULE_LPMODE_16 :
419+ reg = 0xD ;
420+ mask = 0x1 << (attr -> index - MODULE_LPMODE_9 );
421+ invert = 0 ;
422+ break ;
423+ case MODULE_LPMODE_17 ... MODULE_LPMODE_24 :
424+ reg = 0xC ;
425+ mask = 0x1 << (attr -> index - MODULE_LPMODE_17 );
426+ invert = 0 ;
427+ break ;
428+ case MODULE_LPMODE_25 ... MODULE_LPMODE_26 :
429+ reg = 0xD ;
430+ mask = 0x1 << (attr -> index - MODULE_LPMODE_25 );
431+ invert = 0 ;
432+ break ;
382433 case MODULE_TXDISABLE_27 ... MODULE_TXDISABLE_30 :
383434 reg = 0xA ;
384435 mask = 0x1 << (attr -> index - MODULE_TXDISABLE_27 );
@@ -533,44 +584,68 @@ static ssize_t set_control(struct device *dev, struct device_attribute *da,
533584 struct sensor_device_attribute * attr = to_sensor_dev_attr (da );
534585 struct i2c_client * client = to_i2c_client (dev );
535586 struct as7946_30xb_cpld_data * data = i2c_get_clientdata (client );
536- long reset ;
587+ long value ;
537588 int status , bus , addr ;
538- u8 reg = 0 , mask = 0 ;
589+ u8 reg = 0 , mask = 0 , invert = 1 ;
539590
540- status = kstrtol (buf , 10 , & reset );
591+ status = kstrtol (buf , 10 , & value );
541592 if (status )
542593 return status ;
543594
544595 switch (attr -> index ) {
545596 case MODULE_RESET_1 ... MODULE_RESET_8 :/*QSFP*/
546597 reg = 0x8 ;
547598 mask = 0x1 << (attr -> index - MODULE_RESET_1 );
599+ invert = 1 ;
548600 break ;
549601 case MODULE_RESET_9 ... MODULE_RESET_16 :/*QSFP*/
550602 reg = 0x9 ;
551603 mask = 0x1 << (attr -> index - MODULE_RESET_9 );
604+ invert = 1 ;
552605 break ;
553606 case MODULE_RESET_17 ... MODULE_RESET_24 :/*QSFP*/
554607 reg = 0x8 ;
555608 mask = 0x1 << (attr -> index - MODULE_RESET_17 );
609+ invert = 1 ;
556610 break ;
557611 case MODULE_RESET_25 ... MODULE_RESET_26 :/*QSFP*/
558612 reg = 0x9 ;
559613 mask = 0x1 << (attr -> index - MODULE_RESET_25 );
614+ invert = 1 ;
615+ break ;
616+ case MODULE_LPMODE_1 ... MODULE_LPMODE_8 :/*QSFP*/
617+ reg = 0xC ;
618+ mask = 0x1 << (attr -> index - MODULE_LPMODE_1 );
619+ invert = 0 ;
620+ break ;
621+ case MODULE_LPMODE_9 ... MODULE_LPMODE_16 :/*QSFP*/
622+ reg = 0xD ;
623+ mask = 0x1 << (attr -> index - MODULE_LPMODE_9 );
624+ invert = 0 ;
625+ break ;
626+ case MODULE_LPMODE_17 ... MODULE_LPMODE_24 :/*QSFP*/
627+ reg = 0xC ;
628+ mask = 0x1 << (attr -> index - MODULE_LPMODE_17 );
629+ invert = 0 ;
630+ break ;
631+ case MODULE_LPMODE_25 ... MODULE_LPMODE_26 :/*QSFP*/
632+ reg = 0xD ;
633+ mask = 0x1 << (attr -> index - MODULE_LPMODE_25 );
634+ invert = 0 ;
560635 break ;
561636 default :
562637 return - ENXIO ;
563638 }
564639
565640 mutex_lock (& data -> update_lock );
566641 switch (data -> index ) {
567- /* Port 1-16 reset status: read from i2c bus number '12'
642+ /* Port 1-16 reset and lpmode status: read from i2c bus number '12'
568643 and CPLD slave address 0x61 */
569644 case as7946_30xb_cpld1 :
570645 bus = 12 ;
571646 addr = 0x61 ;
572647 break ;
573- /* Port 17-30 reset status: read from i2c bus number '13'
648+ /* Port 17-30 reset and lpmode status: read from i2c bus number '13'
574649 and CPLD slave address 0x62 */
575650 case as7946_30xb_cpld2 :
576651 bus = 13 ;
@@ -585,11 +660,18 @@ static ssize_t set_control(struct device *dev, struct device_attribute *da,
585660 if (unlikely (status < 0 ))
586661 goto exit ;
587662
588- /* Update reset status */
589- if (reset )
590- status &= ~mask ;
663+ /* Update reset and lpmode status */
664+ if (invert )
665+ if (value )
666+ status &= ~mask ;
667+ else
668+ status |= mask ;
591669 else
592- status |= mask ;
670+ if (value )
671+ status |= mask ;
672+ else
673+ status &= ~mask ;
674+
593675
594676 status = as7946_30xb_cpld_write (bus , addr , reg , status );
595677 if (unlikely (status < 0 ))
0 commit comments