@@ -78,6 +78,10 @@ static const struct mfd_cell cros_ec_rtc_cells[] = {
78
78
{ .name = "cros-ec-rtc" , },
79
79
};
80
80
81
+ static const struct mfd_cell cros_ec_sensorhub_cells [] = {
82
+ { .name = "cros-ec-sensorhub" , },
83
+ };
84
+
81
85
static const struct mfd_cell cros_usbpd_charger_cells [] = {
82
86
{ .name = "cros-usbpd-charger" , },
83
87
{ .name = "cros-usbpd-logger" , },
@@ -112,229 +116,11 @@ static const struct mfd_cell cros_ec_vbc_cells[] = {
112
116
{ .name = "cros-ec-vbc" , }
113
117
};
114
118
115
- static int cros_ec_check_features (struct cros_ec_dev * ec , int feature )
116
- {
117
- struct cros_ec_command * msg ;
118
- int ret ;
119
-
120
- if (ec -> features [0 ] == -1U && ec -> features [1 ] == -1U ) {
121
- /* features bitmap not read yet */
122
- msg = kzalloc (sizeof (* msg ) + sizeof (ec -> features ), GFP_KERNEL );
123
- if (!msg )
124
- return - ENOMEM ;
125
-
126
- msg -> command = EC_CMD_GET_FEATURES + ec -> cmd_offset ;
127
- msg -> insize = sizeof (ec -> features );
128
-
129
- ret = cros_ec_cmd_xfer_status (ec -> ec_dev , msg );
130
- if (ret < 0 ) {
131
- dev_warn (ec -> dev , "cannot get EC features: %d/%d\n" ,
132
- ret , msg -> result );
133
- memset (ec -> features , 0 , sizeof (ec -> features ));
134
- } else {
135
- memcpy (ec -> features , msg -> data , sizeof (ec -> features ));
136
- }
137
-
138
- dev_dbg (ec -> dev , "EC features %08x %08x\n" ,
139
- ec -> features [0 ], ec -> features [1 ]);
140
-
141
- kfree (msg );
142
- }
143
-
144
- return ec -> features [feature / 32 ] & EC_FEATURE_MASK_0 (feature );
145
- }
146
-
147
119
static void cros_ec_class_release (struct device * dev )
148
120
{
149
121
kfree (to_cros_ec_dev (dev ));
150
122
}
151
123
152
- static void cros_ec_sensors_register (struct cros_ec_dev * ec )
153
- {
154
- /*
155
- * Issue a command to get the number of sensor reported.
156
- * Build an array of sensors driver and register them all.
157
- */
158
- int ret , i , id , sensor_num ;
159
- struct mfd_cell * sensor_cells ;
160
- struct cros_ec_sensor_platform * sensor_platforms ;
161
- int sensor_type [MOTIONSENSE_TYPE_MAX ];
162
- struct ec_params_motion_sense * params ;
163
- struct ec_response_motion_sense * resp ;
164
- struct cros_ec_command * msg ;
165
-
166
- msg = kzalloc (sizeof (struct cros_ec_command ) +
167
- max (sizeof (* params ), sizeof (* resp )), GFP_KERNEL );
168
- if (msg == NULL )
169
- return ;
170
-
171
- msg -> version = 2 ;
172
- msg -> command = EC_CMD_MOTION_SENSE_CMD + ec -> cmd_offset ;
173
- msg -> outsize = sizeof (* params );
174
- msg -> insize = sizeof (* resp );
175
-
176
- params = (struct ec_params_motion_sense * )msg -> data ;
177
- params -> cmd = MOTIONSENSE_CMD_DUMP ;
178
-
179
- ret = cros_ec_cmd_xfer_status (ec -> ec_dev , msg );
180
- if (ret < 0 ) {
181
- dev_warn (ec -> dev , "cannot get EC sensor information: %d/%d\n" ,
182
- ret , msg -> result );
183
- goto error ;
184
- }
185
-
186
- resp = (struct ec_response_motion_sense * )msg -> data ;
187
- sensor_num = resp -> dump .sensor_count ;
188
- /*
189
- * Allocate 2 extra sensors if lid angle sensor and/or FIFO are needed.
190
- */
191
- sensor_cells = kcalloc (sensor_num + 2 , sizeof (struct mfd_cell ),
192
- GFP_KERNEL );
193
- if (sensor_cells == NULL )
194
- goto error ;
195
-
196
- sensor_platforms = kcalloc (sensor_num ,
197
- sizeof (struct cros_ec_sensor_platform ),
198
- GFP_KERNEL );
199
- if (sensor_platforms == NULL )
200
- goto error_platforms ;
201
-
202
- memset (sensor_type , 0 , sizeof (sensor_type ));
203
- id = 0 ;
204
- for (i = 0 ; i < sensor_num ; i ++ ) {
205
- params -> cmd = MOTIONSENSE_CMD_INFO ;
206
- params -> info .sensor_num = i ;
207
- ret = cros_ec_cmd_xfer_status (ec -> ec_dev , msg );
208
- if (ret < 0 ) {
209
- dev_warn (ec -> dev , "no info for EC sensor %d : %d/%d\n" ,
210
- i , ret , msg -> result );
211
- continue ;
212
- }
213
- switch (resp -> info .type ) {
214
- case MOTIONSENSE_TYPE_ACCEL :
215
- sensor_cells [id ].name = "cros-ec-accel" ;
216
- break ;
217
- case MOTIONSENSE_TYPE_BARO :
218
- sensor_cells [id ].name = "cros-ec-baro" ;
219
- break ;
220
- case MOTIONSENSE_TYPE_GYRO :
221
- sensor_cells [id ].name = "cros-ec-gyro" ;
222
- break ;
223
- case MOTIONSENSE_TYPE_MAG :
224
- sensor_cells [id ].name = "cros-ec-mag" ;
225
- break ;
226
- case MOTIONSENSE_TYPE_PROX :
227
- sensor_cells [id ].name = "cros-ec-prox" ;
228
- break ;
229
- case MOTIONSENSE_TYPE_LIGHT :
230
- sensor_cells [id ].name = "cros-ec-light" ;
231
- break ;
232
- case MOTIONSENSE_TYPE_ACTIVITY :
233
- sensor_cells [id ].name = "cros-ec-activity" ;
234
- break ;
235
- default :
236
- dev_warn (ec -> dev , "unknown type %d\n" , resp -> info .type );
237
- continue ;
238
- }
239
- sensor_platforms [id ].sensor_num = i ;
240
- sensor_cells [id ].id = sensor_type [resp -> info .type ];
241
- sensor_cells [id ].platform_data = & sensor_platforms [id ];
242
- sensor_cells [id ].pdata_size =
243
- sizeof (struct cros_ec_sensor_platform );
244
-
245
- sensor_type [resp -> info .type ]++ ;
246
- id ++ ;
247
- }
248
-
249
- if (sensor_type [MOTIONSENSE_TYPE_ACCEL ] >= 2 )
250
- ec -> has_kb_wake_angle = true;
251
-
252
- if (cros_ec_check_features (ec , EC_FEATURE_MOTION_SENSE_FIFO )) {
253
- sensor_cells [id ].name = "cros-ec-ring" ;
254
- id ++ ;
255
- }
256
- if (cros_ec_check_features (ec ,
257
- EC_FEATURE_REFINED_TABLET_MODE_HYSTERESIS )) {
258
- sensor_cells [id ].name = "cros-ec-lid-angle" ;
259
- id ++ ;
260
- }
261
-
262
- ret = mfd_add_devices (ec -> dev , 0 , sensor_cells , id ,
263
- NULL , 0 , NULL );
264
- if (ret )
265
- dev_err (ec -> dev , "failed to add EC sensors\n" );
266
-
267
- kfree (sensor_platforms );
268
- error_platforms :
269
- kfree (sensor_cells );
270
- error :
271
- kfree (msg );
272
- }
273
-
274
- static struct cros_ec_sensor_platform sensor_platforms [] = {
275
- { .sensor_num = 0 },
276
- { .sensor_num = 1 }
277
- };
278
-
279
- static const struct mfd_cell cros_ec_accel_legacy_cells [] = {
280
- {
281
- .name = "cros-ec-accel-legacy" ,
282
- .platform_data = & sensor_platforms [0 ],
283
- .pdata_size = sizeof (struct cros_ec_sensor_platform ),
284
- },
285
- {
286
- .name = "cros-ec-accel-legacy" ,
287
- .platform_data = & sensor_platforms [1 ],
288
- .pdata_size = sizeof (struct cros_ec_sensor_platform ),
289
- }
290
- };
291
-
292
- static void cros_ec_accel_legacy_register (struct cros_ec_dev * ec )
293
- {
294
- struct cros_ec_device * ec_dev = ec -> ec_dev ;
295
- u8 status ;
296
- int ret ;
297
-
298
- /*
299
- * ECs that need legacy support are the main EC, directly connected to
300
- * the AP.
301
- */
302
- if (ec -> cmd_offset != 0 )
303
- return ;
304
-
305
- /*
306
- * Check if EC supports direct memory reads and if EC has
307
- * accelerometers.
308
- */
309
- if (ec_dev -> cmd_readmem ) {
310
- ret = ec_dev -> cmd_readmem (ec_dev , EC_MEMMAP_ACC_STATUS , 1 ,
311
- & status );
312
- if (ret < 0 ) {
313
- dev_warn (ec -> dev , "EC direct read error.\n" );
314
- return ;
315
- }
316
-
317
- /* Check if EC has accelerometers. */
318
- if (!(status & EC_MEMMAP_ACC_STATUS_PRESENCE_BIT )) {
319
- dev_info (ec -> dev , "EC does not have accelerometers.\n" );
320
- return ;
321
- }
322
- }
323
-
324
- /*
325
- * The device may still support accelerometers:
326
- * it would be an older ARM based device that do not suppor the
327
- * EC_CMD_GET_FEATURES command.
328
- *
329
- * Register 2 accelerometers, we will fail in the IIO driver if there
330
- * are no sensors.
331
- */
332
- ret = mfd_add_hotplug_devices (ec -> dev , cros_ec_accel_legacy_cells ,
333
- ARRAY_SIZE (cros_ec_accel_legacy_cells ));
334
- if (ret )
335
- dev_err (ec_dev -> dev , "failed to add EC sensors\n" );
336
- }
337
-
338
124
static int ec_device_probe (struct platform_device * pdev )
339
125
{
340
126
int retval = - ENOMEM ;
@@ -390,11 +176,14 @@ static int ec_device_probe(struct platform_device *pdev)
390
176
goto failed ;
391
177
392
178
/* check whether this EC is a sensor hub. */
393
- if (cros_ec_check_features (ec , EC_FEATURE_MOTION_SENSE ))
394
- cros_ec_sensors_register (ec );
395
- else
396
- /* Workaroud for older EC firmware */
397
- cros_ec_accel_legacy_register (ec );
179
+ if (cros_ec_get_sensor_count (ec ) > 0 ) {
180
+ retval = mfd_add_hotplug_devices (ec -> dev ,
181
+ cros_ec_sensorhub_cells ,
182
+ ARRAY_SIZE (cros_ec_sensorhub_cells ));
183
+ if (retval )
184
+ dev_err (ec -> dev , "failed to add %s subdevice: %d\n" ,
185
+ cros_ec_sensorhub_cells -> name , retval );
186
+ }
398
187
399
188
/*
400
189
* The following subdevices can be detected by sending the
0 commit comments