1111#include <linux/slab.h>
1212#include <linux/jiffies.h>
1313#include <linux/i2c.h>
14+ #include <linux/i3c/device.h>
1415#include <linux/hwmon.h>
1516#include <linux/err.h>
1617#include <linux/of.h>
@@ -112,6 +113,8 @@ struct lm75_data {
112113 unsigned int sample_time ; /* In ms */
113114 enum lm75_type kind ;
114115 const struct lm75_params * params ;
116+ u8 reg_buf [1 ];
117+ u8 val_buf [3 ];
115118};
116119
117120/*-----------------------------------------------------------------------*/
@@ -606,6 +609,77 @@ static const struct regmap_bus lm75_i2c_regmap_bus = {
606609 .reg_write = lm75_i2c_reg_write ,
607610};
608611
612+ static int lm75_i3c_reg_read (void * context , unsigned int reg , unsigned int * val )
613+ {
614+ struct i3c_device * i3cdev = context ;
615+ struct lm75_data * data = i3cdev_get_drvdata (i3cdev );
616+ struct i3c_priv_xfer xfers [] = {
617+ {
618+ .rnw = false,
619+ .len = 1 ,
620+ .data .out = data -> reg_buf ,
621+ },
622+ {
623+ .rnw = true,
624+ .len = 2 ,
625+ .data .out = data -> val_buf ,
626+ },
627+ };
628+ int ret ;
629+
630+ data -> reg_buf [0 ] = reg ;
631+
632+ if (reg == LM75_REG_CONF && !data -> params -> config_reg_16bits )
633+ xfers [1 ].len -- ;
634+
635+ ret = i3c_device_do_priv_xfers (i3cdev , xfers , 2 );
636+ if (ret < 0 )
637+ return ret ;
638+
639+ if (reg == LM75_REG_CONF && !data -> params -> config_reg_16bits )
640+ * val = data -> val_buf [0 ];
641+ else if (reg == LM75_REG_CONF )
642+ * val = data -> val_buf [0 ] | (data -> val_buf [1 ] << 8 );
643+ else
644+ * val = data -> val_buf [1 ] | (data -> val_buf [0 ] << 8 );
645+
646+ return 0 ;
647+ }
648+
649+ static int lm75_i3c_reg_write (void * context , unsigned int reg , unsigned int val )
650+ {
651+ struct i3c_device * i3cdev = context ;
652+ struct lm75_data * data = i3cdev_get_drvdata (i3cdev );
653+ struct i3c_priv_xfer xfers [] = {
654+ {
655+ .rnw = false,
656+ .len = 3 ,
657+ .data .out = data -> val_buf ,
658+ },
659+ };
660+
661+ data -> val_buf [0 ] = reg ;
662+
663+ if (reg == PCT2075_REG_IDLE ||
664+ (reg == LM75_REG_CONF && !data -> params -> config_reg_16bits )) {
665+ xfers [0 ].len -- ;
666+ data -> val_buf [1 ] = val & 0xff ;
667+ } else if (reg == LM75_REG_CONF ) {
668+ data -> val_buf [1 ] = val & 0xff ;
669+ data -> val_buf [2 ] = (val >> 8 ) & 0xff ;
670+ } else {
671+ data -> val_buf [1 ] = (val >> 8 ) & 0xff ;
672+ data -> val_buf [2 ] = val & 0xff ;
673+ }
674+
675+ return i3c_device_do_priv_xfers (i3cdev , xfers , 1 );
676+ }
677+
678+ static const struct regmap_bus lm75_i3c_regmap_bus = {
679+ .reg_read = lm75_i3c_reg_read ,
680+ .reg_write = lm75_i3c_reg_write ,
681+ };
682+
609683static const struct regmap_config lm75_regmap_config = {
610684 .reg_bits = 8 ,
611685 .val_bits = 16 ,
@@ -626,7 +700,7 @@ static void lm75_remove(void *data)
626700}
627701
628702static int lm75_generic_probe (struct device * dev , const char * name ,
629- const void * kind_ptr , int irq , struct regmap * regmap )
703+ enum lm75_type kind , int irq , struct regmap * regmap )
630704{
631705 struct device * hwmon_dev ;
632706 struct lm75_data * data ;
@@ -639,7 +713,7 @@ static int lm75_generic_probe(struct device *dev, const char *name,
639713 /* needed by custom regmap callbacks */
640714 dev_set_drvdata (dev , data );
641715
642- data -> kind = ( uintptr_t ) kind_ptr ;
716+ data -> kind = kind ;
643717 data -> regmap = regmap ;
644718
645719 err = devm_regulator_get_enable (dev , "vs" );
@@ -711,7 +785,7 @@ static int lm75_i2c_probe(struct i2c_client *client)
711785 if (IS_ERR (regmap ))
712786 return PTR_ERR (regmap );
713787
714- return lm75_generic_probe (dev , client -> name , i2c_get_match_data (client ),
788+ return lm75_generic_probe (dev , client -> name , ( uintptr_t ) i2c_get_match_data (client ),
715789 client -> irq , regmap );
716790}
717791
@@ -750,6 +824,37 @@ static const struct i2c_device_id lm75_i2c_ids[] = {
750824};
751825MODULE_DEVICE_TABLE (i2c , lm75_i2c_ids );
752826
827+ struct lm75_i3c_device {
828+ enum lm75_type type ;
829+ const char * name ;
830+ };
831+
832+ static const struct lm75_i3c_device lm75_i3c_p3t1755 = {
833+ .name = "p3t1755" ,
834+ .type = p3t1755 ,
835+ };
836+
837+ static const struct i3c_device_id lm75_i3c_ids [] = {
838+ I3C_DEVICE (0x011b , 0x152a , & lm75_i3c_p3t1755 ),
839+ { /* LIST END */ }
840+ };
841+ MODULE_DEVICE_TABLE (i3c , lm75_i3c_ids );
842+
843+ static int lm75_i3c_probe (struct i3c_device * i3cdev )
844+ {
845+ struct device * dev = i3cdev_to_dev (i3cdev );
846+ const struct lm75_i3c_device * id_data ;
847+ struct regmap * regmap ;
848+
849+ regmap = devm_regmap_init (dev , & lm75_i3c_regmap_bus , i3cdev , & lm75_regmap_config );
850+ if (IS_ERR (regmap ))
851+ return PTR_ERR (regmap );
852+
853+ id_data = i3c_device_match_id (i3cdev , lm75_i3c_ids )-> data ;
854+
855+ return lm75_generic_probe (dev , id_data -> name , id_data -> type , 0 , regmap );
856+ }
857+
753858static const struct of_device_id __maybe_unused lm75_of_match [] = {
754859 {
755860 .compatible = "adi,adt75" ,
@@ -1008,7 +1113,15 @@ static struct i2c_driver lm75_i2c_driver = {
10081113 .address_list = normal_i2c ,
10091114};
10101115
1011- module_i2c_driver (lm75_i2c_driver );
1116+ static struct i3c_driver lm75_i3c_driver = {
1117+ .driver = {
1118+ .name = "lm75_i3c" ,
1119+ },
1120+ .probe = lm75_i3c_probe ,
1121+ .id_table = lm75_i3c_ids ,
1122+ };
1123+
1124+ module_i3c_i2c_driver (lm75_i3c_driver , & lm75_i2c_driver )
10121125
10131126MODULE_AUTHOR (
"Frodo Looijaard <[email protected] >" );
10141127MODULE_DESCRIPTION ("LM75 driver" );
0 commit comments