36
36
#define LIDAR_REG_STATUS_INVALID BIT(3)
37
37
#define LIDAR_REG_STATUS_READY BIT(0)
38
38
39
- #define LIDAR_REG_DATA_HBYTE 0x0f
40
- #define LIDAR_REG_DATA_LBYTE 0x10
39
+ #define LIDAR_REG_DATA_HBYTE 0x0f
40
+ #define LIDAR_REG_DATA_LBYTE 0x10
41
+ #define LIDAR_REG_DATA_WORD_READ BIT(7)
42
+
41
43
#define LIDAR_REG_PWR_CONTROL 0x65
42
44
43
45
#define LIDAR_DRV_NAME "lidar"
@@ -46,6 +48,9 @@ struct lidar_data {
46
48
struct iio_dev * indio_dev ;
47
49
struct i2c_client * client ;
48
50
51
+ int (* xfer )(struct lidar_data * data , u8 reg , u8 * val , int len );
52
+ int i2c_enabled ;
53
+
49
54
u16 buffer [8 ]; /* 2 byte distance + 8 byte timestamp */
50
55
};
51
56
@@ -64,7 +69,28 @@ static const struct iio_chan_spec lidar_channels[] = {
64
69
IIO_CHAN_SOFT_TIMESTAMP (1 ),
65
70
};
66
71
67
- static int lidar_read_byte (struct lidar_data * data , int reg )
72
+ static int lidar_i2c_xfer (struct lidar_data * data , u8 reg , u8 * val , int len )
73
+ {
74
+ struct i2c_client * client = data -> client ;
75
+ struct i2c_msg msg [2 ];
76
+ int ret ;
77
+
78
+ msg [0 ].addr = client -> addr ;
79
+ msg [0 ].flags = client -> flags | I2C_M_STOP ;
80
+ msg [0 ].len = 1 ;
81
+ msg [0 ].buf = (char * ) & reg ;
82
+
83
+ msg [1 ].addr = client -> addr ;
84
+ msg [1 ].flags = client -> flags | I2C_M_RD ;
85
+ msg [1 ].len = len ;
86
+ msg [1 ].buf = (char * ) val ;
87
+
88
+ ret = i2c_transfer (client -> adapter , msg , 2 );
89
+
90
+ return (ret == 2 ) ? 0 : ret ;
91
+ }
92
+
93
+ static int lidar_smbus_xfer (struct lidar_data * data , u8 reg , u8 * val , int len )
68
94
{
69
95
struct i2c_client * client = data -> client ;
70
96
int ret ;
@@ -74,17 +100,35 @@ static int lidar_read_byte(struct lidar_data *data, int reg)
74
100
* so in turn i2c_smbus_read_byte_data cannot be used
75
101
*/
76
102
77
- ret = i2c_smbus_write_byte (client , reg );
78
- if (ret < 0 ) {
79
- dev_err (& client -> dev , "cannot write addr value" );
80
- return ret ;
103
+ while (len -- ) {
104
+ ret = i2c_smbus_write_byte (client , reg ++ );
105
+ if (ret < 0 ) {
106
+ dev_err (& client -> dev , "cannot write addr value" );
107
+ return ret ;
108
+ }
109
+
110
+ ret = i2c_smbus_read_byte (client );
111
+ if (ret < 0 ) {
112
+ dev_err (& client -> dev , "cannot read data value" );
113
+ return ret ;
114
+ }
115
+
116
+ * (val ++ ) = ret ;
81
117
}
82
118
83
- ret = i2c_smbus_read_byte (client );
119
+ return 0 ;
120
+ }
121
+
122
+ static int lidar_read_byte (struct lidar_data * data , u8 reg )
123
+ {
124
+ int ret ;
125
+ u8 val ;
126
+
127
+ ret = data -> xfer (data , reg , & val , 1 );
84
128
if (ret < 0 )
85
- dev_err ( & client -> dev , "cannot read data value" ) ;
129
+ return ret ;
86
130
87
- return ret ;
131
+ return val ;
88
132
}
89
133
90
134
static inline int lidar_write_control (struct lidar_data * data , int val )
@@ -100,22 +144,14 @@ static inline int lidar_write_power(struct lidar_data *data, int val)
100
144
101
145
static int lidar_read_measurement (struct lidar_data * data , u16 * reg )
102
146
{
103
- int ret ;
104
- int val ;
105
-
106
- ret = lidar_read_byte (data , LIDAR_REG_DATA_HBYTE );
107
- if (ret < 0 )
108
- return ret ;
109
- val = ret << 8 ;
147
+ int ret = data -> xfer (data , LIDAR_REG_DATA_HBYTE |
148
+ (data -> i2c_enabled ? LIDAR_REG_DATA_WORD_READ : 0 ),
149
+ (u8 * ) reg , 2 );
110
150
111
- ret = lidar_read_byte (data , LIDAR_REG_DATA_LBYTE );
112
- if (ret < 0 )
113
- return ret ;
151
+ if (!ret )
152
+ * reg = be16_to_cpu (* reg );
114
153
115
- val |= ret ;
116
- * reg = val ;
117
-
118
- return 0 ;
154
+ return ret ;
119
155
}
120
156
121
157
static int lidar_get_measurement (struct lidar_data * data , u16 * reg )
@@ -233,14 +269,23 @@ static int lidar_probe(struct i2c_client *client,
233
269
indio_dev = devm_iio_device_alloc (& client -> dev , sizeof (* data ));
234
270
if (!indio_dev )
235
271
return - ENOMEM ;
272
+ data = iio_priv (indio_dev );
273
+
274
+ if (i2c_check_functionality (client -> adapter , I2C_FUNC_I2C )) {
275
+ data -> xfer = lidar_i2c_xfer ;
276
+ data -> i2c_enabled = 1 ;
277
+ } else if (i2c_check_functionality (client -> adapter ,
278
+ I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BYTE ))
279
+ data -> xfer = lidar_smbus_xfer ;
280
+ else
281
+ return - ENOTSUPP ;
236
282
237
283
indio_dev -> info = & lidar_info ;
238
284
indio_dev -> name = LIDAR_DRV_NAME ;
239
285
indio_dev -> channels = lidar_channels ;
240
286
indio_dev -> num_channels = ARRAY_SIZE (lidar_channels );
241
287
indio_dev -> modes = INDIO_DIRECT_MODE ;
242
288
243
- data = iio_priv (indio_dev );
244
289
i2c_set_clientdata (client , indio_dev );
245
290
246
291
data -> client = client ;
0 commit comments