11
11
#include <linux/slab.h>
12
12
#include <linux/jiffies.h>
13
13
#include <linux/i2c.h>
14
+ #include <linux/i3c/device.h>
14
15
#include <linux/hwmon.h>
15
16
#include <linux/err.h>
16
17
#include <linux/of.h>
@@ -112,6 +113,8 @@ struct lm75_data {
112
113
unsigned int sample_time ; /* In ms */
113
114
enum lm75_type kind ;
114
115
const struct lm75_params * params ;
116
+ u8 reg_buf [1 ];
117
+ u8 val_buf [3 ];
115
118
};
116
119
117
120
/*-----------------------------------------------------------------------*/
@@ -606,6 +609,77 @@ static const struct regmap_bus lm75_i2c_regmap_bus = {
606
609
.reg_write = lm75_i2c_reg_write ,
607
610
};
608
611
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
+
609
683
static const struct regmap_config lm75_regmap_config = {
610
684
.reg_bits = 8 ,
611
685
.val_bits = 16 ,
@@ -626,7 +700,7 @@ static void lm75_remove(void *data)
626
700
}
627
701
628
702
static 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 )
630
704
{
631
705
struct device * hwmon_dev ;
632
706
struct lm75_data * data ;
@@ -639,7 +713,7 @@ static int lm75_generic_probe(struct device *dev, const char *name,
639
713
/* needed by custom regmap callbacks */
640
714
dev_set_drvdata (dev , data );
641
715
642
- data -> kind = ( uintptr_t ) kind_ptr ;
716
+ data -> kind = kind ;
643
717
data -> regmap = regmap ;
644
718
645
719
err = devm_regulator_get_enable (dev , "vs" );
@@ -711,7 +785,7 @@ static int lm75_i2c_probe(struct i2c_client *client)
711
785
if (IS_ERR (regmap ))
712
786
return PTR_ERR (regmap );
713
787
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 ),
715
789
client -> irq , regmap );
716
790
}
717
791
@@ -750,6 +824,37 @@ static const struct i2c_device_id lm75_i2c_ids[] = {
750
824
};
751
825
MODULE_DEVICE_TABLE (i2c , lm75_i2c_ids );
752
826
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
+
753
858
static const struct of_device_id __maybe_unused lm75_of_match [] = {
754
859
{
755
860
.compatible = "adi,adt75" ,
@@ -1008,7 +1113,15 @@ static struct i2c_driver lm75_i2c_driver = {
1008
1113
.address_list = normal_i2c ,
1009
1114
};
1010
1115
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 )
1012
1125
1013
1126
MODULE_AUTHOR (
"Frodo Looijaard <[email protected] >" );
1014
1127
MODULE_DESCRIPTION ("LM75 driver" );
0 commit comments