@@ -1457,6 +1457,94 @@ static int si5341_clk_select_active_input(struct clk_si5341 *data)
14571457 return res ;
14581458}
14591459
1460+ static ssize_t input_present_show (struct device * dev ,
1461+ struct device_attribute * attr ,
1462+ char * buf )
1463+ {
1464+ struct clk_si5341 * data = dev_get_drvdata (dev );
1465+ u32 status ;
1466+ int res = regmap_read (data -> regmap , SI5341_STATUS , & status );
1467+
1468+ if (res < 0 )
1469+ return res ;
1470+ res = !(status & SI5341_STATUS_LOSREF );
1471+ return snprintf (buf , PAGE_SIZE , "%d\n" , res );
1472+ }
1473+ static DEVICE_ATTR_RO (input_present );
1474+
1475+ static ssize_t input_present_sticky_show (struct device * dev ,
1476+ struct device_attribute * attr ,
1477+ char * buf )
1478+ {
1479+ struct clk_si5341 * data = dev_get_drvdata (dev );
1480+ u32 status ;
1481+ int res = regmap_read (data -> regmap , SI5341_STATUS_STICKY , & status );
1482+
1483+ if (res < 0 )
1484+ return res ;
1485+ res = !(status & SI5341_STATUS_LOSREF );
1486+ return snprintf (buf , PAGE_SIZE , "%d\n" , res );
1487+ }
1488+ static DEVICE_ATTR_RO (input_present_sticky );
1489+
1490+ static ssize_t pll_locked_show (struct device * dev ,
1491+ struct device_attribute * attr ,
1492+ char * buf )
1493+ {
1494+ struct clk_si5341 * data = dev_get_drvdata (dev );
1495+ u32 status ;
1496+ int res = regmap_read (data -> regmap , SI5341_STATUS , & status );
1497+
1498+ if (res < 0 )
1499+ return res ;
1500+ res = !(status & SI5341_STATUS_LOL );
1501+ return snprintf (buf , PAGE_SIZE , "%d\n" , res );
1502+ }
1503+ static DEVICE_ATTR_RO (pll_locked );
1504+
1505+ static ssize_t pll_locked_sticky_show (struct device * dev ,
1506+ struct device_attribute * attr ,
1507+ char * buf )
1508+ {
1509+ struct clk_si5341 * data = dev_get_drvdata (dev );
1510+ u32 status ;
1511+ int res = regmap_read (data -> regmap , SI5341_STATUS_STICKY , & status );
1512+
1513+ if (res < 0 )
1514+ return res ;
1515+ res = !(status & SI5341_STATUS_LOL );
1516+ return snprintf (buf , PAGE_SIZE , "%d\n" , res );
1517+ }
1518+ static DEVICE_ATTR_RO (pll_locked_sticky );
1519+
1520+ static ssize_t clear_sticky_store (struct device * dev ,
1521+ struct device_attribute * attr ,
1522+ const char * buf , size_t count )
1523+ {
1524+ struct clk_si5341 * data = dev_get_drvdata (dev );
1525+ long val ;
1526+
1527+ if (kstrtol (buf , 10 , & val ))
1528+ return - EINVAL ;
1529+ if (val ) {
1530+ int res = regmap_write (data -> regmap , SI5341_STATUS_STICKY , 0 );
1531+
1532+ if (res < 0 )
1533+ return res ;
1534+ }
1535+ return count ;
1536+ }
1537+ static DEVICE_ATTR_WO (clear_sticky );
1538+
1539+ static const struct attribute * si5341_attributes [] = {
1540+ & dev_attr_input_present .attr ,
1541+ & dev_attr_input_present_sticky .attr ,
1542+ & dev_attr_pll_locked .attr ,
1543+ & dev_attr_pll_locked_sticky .attr ,
1544+ & dev_attr_clear_sticky .attr ,
1545+ NULL
1546+ };
1547+
14601548static int si5341_probe (struct i2c_client * client ,
14611549 const struct i2c_device_id * id )
14621550{
@@ -1687,6 +1775,12 @@ static int si5341_probe(struct i2c_client *client,
16871775 goto cleanup ;
16881776 }
16891777
1778+ err = sysfs_create_files (& client -> dev .kobj , si5341_attributes );
1779+ if (err ) {
1780+ dev_err (& client -> dev , "unable to create sysfs files\n" );
1781+ goto cleanup ;
1782+ }
1783+
16901784 /* Free the names, clk framework makes copies */
16911785 for (i = 0 ; i < data -> num_synth ; ++ i )
16921786 devm_kfree (& client -> dev , (void * )synth_clock_names [i ]);
@@ -1706,6 +1800,8 @@ static int si5341_remove(struct i2c_client *client)
17061800 struct clk_si5341 * data = i2c_get_clientdata (client );
17071801 int i ;
17081802
1803+ sysfs_remove_files (& client -> dev .kobj , si5341_attributes );
1804+
17091805 for (i = 0 ; i < SI5341_MAX_NUM_OUTPUTS ; ++ i ) {
17101806 if (data -> clk [i ].vddo_reg )
17111807 regulator_disable (data -> clk [i ].vddo_reg );
0 commit comments