Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-or-later
2 : : /*
3 : : * Linux I2C core ACPI support code
4 : : *
5 : : * Copyright (C) 2014 Intel Corp, Author: Lan Tianyu <tianyu.lan@intel.com>
6 : : */
7 : :
8 : : #include <linux/acpi.h>
9 : : #include <linux/device.h>
10 : : #include <linux/err.h>
11 : : #include <linux/i2c.h>
12 : : #include <linux/list.h>
13 : : #include <linux/module.h>
14 : : #include <linux/slab.h>
15 : :
16 : : #include "i2c-core.h"
17 : :
18 : : struct i2c_acpi_handler_data {
19 : : struct acpi_connection_info info;
20 : : struct i2c_adapter *adapter;
21 : : };
22 : :
23 : : struct gsb_buffer {
24 : : u8 status;
25 : : u8 len;
26 : : union {
27 : : u16 wdata;
28 : : u8 bdata;
29 : : u8 data[0];
30 : : };
31 : : } __packed;
32 : :
33 : : struct i2c_acpi_lookup {
34 : : struct i2c_board_info *info;
35 : : acpi_handle adapter_handle;
36 : : acpi_handle device_handle;
37 : : acpi_handle search_handle;
38 : : int n;
39 : : int index;
40 : : u32 speed;
41 : : u32 min_speed;
42 : : u32 force_speed;
43 : : };
44 : :
45 : : /**
46 : : * i2c_acpi_get_i2c_resource - Gets I2cSerialBus resource if type matches
47 : : * @ares: ACPI resource
48 : : * @i2c: Pointer to I2cSerialBus resource will be returned here
49 : : *
50 : : * Checks if the given ACPI resource is of type I2cSerialBus.
51 : : * In this case, returns a pointer to it to the caller.
52 : : *
53 : : * Returns true if resource type is of I2cSerialBus, otherwise false.
54 : : */
55 : 0 : bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
56 : : struct acpi_resource_i2c_serialbus **i2c)
57 : : {
58 : 0 : struct acpi_resource_i2c_serialbus *sb;
59 : :
60 [ # # # # ]: 0 : if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
61 : : return false;
62 : :
63 : 0 : sb = &ares->data.i2c_serial_bus;
64 [ # # # # : 0 : if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C)
# # ]
65 : : return false;
66 : :
67 : 0 : *i2c = sb;
68 : 0 : return true;
69 : : }
70 : : EXPORT_SYMBOL_GPL(i2c_acpi_get_i2c_resource);
71 : :
72 : 0 : static int i2c_acpi_fill_info(struct acpi_resource *ares, void *data)
73 : : {
74 : 0 : struct i2c_acpi_lookup *lookup = data;
75 : 0 : struct i2c_board_info *info = lookup->info;
76 : 0 : struct acpi_resource_i2c_serialbus *sb;
77 : 0 : acpi_status status;
78 : :
79 [ # # # # ]: 0 : if (info->addr || !i2c_acpi_get_i2c_resource(ares, &sb))
80 : : return 1;
81 : :
82 [ # # # # ]: 0 : if (lookup->index != -1 && lookup->n++ != lookup->index)
83 : : return 1;
84 : :
85 : 0 : status = acpi_get_handle(lookup->device_handle,
86 : : sb->resource_source.string_ptr,
87 : : &lookup->adapter_handle);
88 [ # # ]: 0 : if (ACPI_FAILURE(status))
89 : : return 1;
90 : :
91 : 0 : info->addr = sb->slave_address;
92 : 0 : lookup->speed = sb->connection_speed;
93 [ # # ]: 0 : if (sb->access_mode == ACPI_I2C_10BIT_MODE)
94 : 0 : info->flags |= I2C_CLIENT_TEN;
95 : :
96 : : return 1;
97 : : }
98 : :
99 : : static const struct acpi_device_id i2c_acpi_ignored_device_ids[] = {
100 : : /*
101 : : * ACPI video acpi_devices, which are handled by the acpi-video driver
102 : : * sometimes contain a SERIAL_TYPE_I2C ACPI resource, ignore these.
103 : : */
104 : : { ACPI_VIDEO_HID, 0 },
105 : : {}
106 : : };
107 : :
108 : 0 : static int i2c_acpi_do_lookup(struct acpi_device *adev,
109 : : struct i2c_acpi_lookup *lookup)
110 : : {
111 : 0 : struct i2c_board_info *info = lookup->info;
112 : 0 : struct list_head resource_list;
113 : 0 : int ret;
114 : :
115 [ # # # # ]: 0 : if (acpi_bus_get_status(adev) || !adev->status.present)
116 : : return -EINVAL;
117 : :
118 [ # # ]: 0 : if (acpi_match_device_ids(adev, i2c_acpi_ignored_device_ids) == 0)
119 : : return -ENODEV;
120 : :
121 : 0 : memset(info, 0, sizeof(*info));
122 [ # # ]: 0 : lookup->device_handle = acpi_device_handle(adev);
123 : :
124 : : /* Look up for I2cSerialBus resource */
125 : 0 : INIT_LIST_HEAD(&resource_list);
126 : 0 : ret = acpi_dev_get_resources(adev, &resource_list,
127 : : i2c_acpi_fill_info, lookup);
128 : 0 : acpi_dev_free_resource_list(&resource_list);
129 : :
130 [ # # # # ]: 0 : if (ret < 0 || !info->addr)
131 : 0 : return -EINVAL;
132 : :
133 : : return 0;
134 : : }
135 : :
136 : 0 : static int i2c_acpi_add_resource(struct acpi_resource *ares, void *data)
137 : : {
138 : 0 : int *irq = data;
139 : 0 : struct resource r;
140 : :
141 [ # # # # ]: 0 : if (*irq <= 0 && acpi_dev_resource_interrupt(ares, 0, &r))
142 : 0 : *irq = i2c_dev_irq_from_resources(&r, 1);
143 : :
144 : 0 : return 1; /* No need to add resource to the list */
145 : : }
146 : :
147 : : /**
148 : : * i2c_acpi_get_irq - get device IRQ number from ACPI
149 : : * @client: Pointer to the I2C client device
150 : : *
151 : : * Find the IRQ number used by a specific client device.
152 : : *
153 : : * Return: The IRQ number or an error code.
154 : : */
155 : 0 : int i2c_acpi_get_irq(struct i2c_client *client)
156 : : {
157 [ # # ]: 0 : struct acpi_device *adev = ACPI_COMPANION(&client->dev);
158 : 0 : struct list_head resource_list;
159 : 0 : int irq = -ENOENT;
160 : 0 : int ret;
161 : :
162 : 0 : INIT_LIST_HEAD(&resource_list);
163 : :
164 : 0 : ret = acpi_dev_get_resources(adev, &resource_list,
165 : : i2c_acpi_add_resource, &irq);
166 [ # # ]: 0 : if (ret < 0)
167 : : return ret;
168 : :
169 : 0 : acpi_dev_free_resource_list(&resource_list);
170 : :
171 [ # # ]: 0 : if (irq == -ENOENT)
172 : 0 : irq = acpi_dev_gpio_irq_get(adev, 0);
173 : :
174 : 0 : return irq;
175 : : }
176 : :
177 : 0 : static int i2c_acpi_get_info(struct acpi_device *adev,
178 : : struct i2c_board_info *info,
179 : : struct i2c_adapter *adapter,
180 : : acpi_handle *adapter_handle)
181 : : {
182 : 0 : struct i2c_acpi_lookup lookup;
183 : 0 : int ret;
184 : :
185 : 0 : memset(&lookup, 0, sizeof(lookup));
186 : 0 : lookup.info = info;
187 : 0 : lookup.index = -1;
188 : :
189 [ # # # # ]: 0 : if (acpi_device_enumerated(adev))
190 : : return -EINVAL;
191 : :
192 : 0 : ret = i2c_acpi_do_lookup(adev, &lookup);
193 [ # # ]: 0 : if (ret)
194 : : return ret;
195 : :
196 [ # # ]: 0 : if (adapter) {
197 : : /* The adapter must match the one in I2cSerialBus() connector */
198 [ # # # # : 0 : if (ACPI_HANDLE(&adapter->dev) != lookup.adapter_handle)
# # ]
199 : : return -ENODEV;
200 : : } else {
201 : 0 : struct acpi_device *adapter_adev;
202 : :
203 : : /* The adapter must be present */
204 [ # # ]: 0 : if (acpi_bus_get_device(lookup.adapter_handle, &adapter_adev))
205 : 0 : return -ENODEV;
206 [ # # ]: 0 : if (acpi_bus_get_status(adapter_adev) ||
207 [ # # ]: 0 : !adapter_adev->status.present)
208 : : return -ENODEV;
209 : : }
210 : :
211 [ # # ]: 0 : info->fwnode = acpi_fwnode_handle(adev);
212 [ # # ]: 0 : if (adapter_handle)
213 : 0 : *adapter_handle = lookup.adapter_handle;
214 : :
215 [ # # ]: 0 : acpi_set_modalias(adev, dev_name(&adev->dev), info->type,
216 : : sizeof(info->type));
217 : :
218 : 0 : return 0;
219 : : }
220 : :
221 : 0 : static void i2c_acpi_register_device(struct i2c_adapter *adapter,
222 : : struct acpi_device *adev,
223 : : struct i2c_board_info *info)
224 : : {
225 : 0 : adev->power.flags.ignore_parent = true;
226 : 0 : acpi_device_set_enumerated(adev);
227 : :
228 [ # # ]: 0 : if (IS_ERR(i2c_new_client_device(adapter, info))) {
229 : 0 : adev->power.flags.ignore_parent = false;
230 [ # # ]: 0 : dev_err(&adapter->dev,
231 : : "failed to add I2C device %s from ACPI\n",
232 : : dev_name(&adev->dev));
233 : : }
234 : 0 : }
235 : :
236 : 0 : static acpi_status i2c_acpi_add_device(acpi_handle handle, u32 level,
237 : : void *data, void **return_value)
238 : : {
239 : 0 : struct i2c_adapter *adapter = data;
240 : 0 : struct acpi_device *adev;
241 : 0 : struct i2c_board_info info;
242 : :
243 [ # # ]: 0 : if (acpi_bus_get_device(handle, &adev))
244 : : return AE_OK;
245 : :
246 [ # # ]: 0 : if (i2c_acpi_get_info(adev, &info, adapter, NULL))
247 : : return AE_OK;
248 : :
249 : 0 : i2c_acpi_register_device(adapter, adev, &info);
250 : :
251 : 0 : return AE_OK;
252 : : }
253 : :
254 : : #define I2C_ACPI_MAX_SCAN_DEPTH 32
255 : :
256 : : /**
257 : : * i2c_acpi_register_devices - enumerate I2C slave devices behind adapter
258 : : * @adap: pointer to adapter
259 : : *
260 : : * Enumerate all I2C slave devices behind this adapter by walking the ACPI
261 : : * namespace. When a device is found it will be added to the Linux device
262 : : * model and bound to the corresponding ACPI handle.
263 : : */
264 : 0 : void i2c_acpi_register_devices(struct i2c_adapter *adap)
265 : : {
266 : 0 : acpi_status status;
267 : :
268 [ # # ]: 0 : if (!has_acpi_companion(&adap->dev))
269 : : return;
270 : :
271 : 0 : status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
272 : : I2C_ACPI_MAX_SCAN_DEPTH,
273 : : i2c_acpi_add_device, NULL,
274 : : adap, NULL);
275 [ # # ]: 0 : if (ACPI_FAILURE(status))
276 : 0 : dev_warn(&adap->dev, "failed to enumerate I2C slaves\n");
277 : : }
278 : :
279 : : const struct acpi_device_id *
280 : 0 : i2c_acpi_match_device(const struct acpi_device_id *matches,
281 : : struct i2c_client *client)
282 : : {
283 [ # # ]: 0 : if (!(client && matches))
284 : : return NULL;
285 : :
286 : 0 : return acpi_match_device(matches, &client->dev);
287 : : }
288 : :
289 : : static const struct acpi_device_id i2c_acpi_force_400khz_device_ids[] = {
290 : : /*
291 : : * These Silead touchscreen controllers only work at 400KHz, for
292 : : * some reason they do not work at 100KHz. On some devices the ACPI
293 : : * tables list another device at their bus as only being capable
294 : : * of 100KHz, testing has shown that these other devices work fine
295 : : * at 400KHz (as can be expected of any recent i2c hw) so we force
296 : : * the speed of the bus to 400 KHz if a Silead device is present.
297 : : */
298 : : { "MSSL1680", 0 },
299 : : {}
300 : : };
301 : :
302 : 0 : static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level,
303 : : void *data, void **return_value)
304 : : {
305 : 0 : struct i2c_acpi_lookup *lookup = data;
306 : 0 : struct acpi_device *adev;
307 : :
308 [ # # ]: 0 : if (acpi_bus_get_device(handle, &adev))
309 : : return AE_OK;
310 : :
311 [ # # ]: 0 : if (i2c_acpi_do_lookup(adev, lookup))
312 : : return AE_OK;
313 : :
314 [ # # ]: 0 : if (lookup->search_handle != lookup->adapter_handle)
315 : : return AE_OK;
316 : :
317 [ # # ]: 0 : if (lookup->speed <= lookup->min_speed)
318 : 0 : lookup->min_speed = lookup->speed;
319 : :
320 [ # # ]: 0 : if (acpi_match_device_ids(adev, i2c_acpi_force_400khz_device_ids) == 0)
321 : 0 : lookup->force_speed = 400000;
322 : :
323 : : return AE_OK;
324 : : }
325 : :
326 : : /**
327 : : * i2c_acpi_find_bus_speed - find I2C bus speed from ACPI
328 : : * @dev: The device owning the bus
329 : : *
330 : : * Find the I2C bus speed by walking the ACPI namespace for all I2C slaves
331 : : * devices connected to this bus and use the speed of slowest device.
332 : : *
333 : : * Returns the speed in Hz or zero
334 : : */
335 : 0 : u32 i2c_acpi_find_bus_speed(struct device *dev)
336 : : {
337 : 0 : struct i2c_acpi_lookup lookup;
338 : 0 : struct i2c_board_info dummy;
339 : 0 : acpi_status status;
340 : :
341 [ # # ]: 0 : if (!has_acpi_companion(dev))
342 : : return 0;
343 : :
344 : 0 : memset(&lookup, 0, sizeof(lookup));
345 [ # # # # ]: 0 : lookup.search_handle = ACPI_HANDLE(dev);
346 : 0 : lookup.min_speed = UINT_MAX;
347 : 0 : lookup.info = &dummy;
348 : 0 : lookup.index = -1;
349 : :
350 : 0 : status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
351 : : I2C_ACPI_MAX_SCAN_DEPTH,
352 : : i2c_acpi_lookup_speed, NULL,
353 : : &lookup, NULL);
354 : :
355 [ # # ]: 0 : if (ACPI_FAILURE(status)) {
356 : 0 : dev_warn(dev, "unable to find I2C bus speed from ACPI\n");
357 : 0 : return 0;
358 : : }
359 : :
360 [ # # ]: 0 : if (lookup.force_speed) {
361 [ # # ]: 0 : if (lookup.force_speed != lookup.min_speed)
362 : 0 : dev_warn(dev, FW_BUG "DSDT uses known not-working I2C bus speed %d, forcing it to %d\n",
363 : : lookup.min_speed, lookup.force_speed);
364 : 0 : return lookup.force_speed;
365 [ # # ]: 0 : } else if (lookup.min_speed != UINT_MAX) {
366 : : return lookup.min_speed;
367 : : } else {
368 : 0 : return 0;
369 : : }
370 : : }
371 : : EXPORT_SYMBOL_GPL(i2c_acpi_find_bus_speed);
372 : :
373 : 0 : static int i2c_acpi_find_match_adapter(struct device *dev, const void *data)
374 : : {
375 : 0 : struct i2c_adapter *adapter = i2c_verify_adapter(dev);
376 : :
377 [ # # ]: 0 : if (!adapter)
378 : : return 0;
379 : :
380 [ # # # # ]: 0 : return ACPI_HANDLE(dev) == (acpi_handle)data;
381 : : }
382 : :
383 : 0 : struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle)
384 : : {
385 : 0 : struct device *dev;
386 : :
387 : 0 : dev = bus_find_device(&i2c_bus_type, NULL, handle,
388 : : i2c_acpi_find_match_adapter);
389 : :
390 [ # # ]: 0 : return dev ? i2c_verify_adapter(dev) : NULL;
391 : : }
392 : : EXPORT_SYMBOL_GPL(i2c_acpi_find_adapter_by_handle);
393 : :
394 : 0 : static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev)
395 : : {
396 : 0 : struct device *dev;
397 : 0 : struct i2c_client *client;
398 : :
399 : 0 : dev = bus_find_device_by_acpi_dev(&i2c_bus_type, adev);
400 [ # # ]: 0 : if (!dev)
401 : : return NULL;
402 : :
403 : 0 : client = i2c_verify_client(dev);
404 [ # # ]: 0 : if (!client)
405 : 0 : put_device(dev);
406 : :
407 : : return client;
408 : : }
409 : :
410 : 0 : static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value,
411 : : void *arg)
412 : : {
413 : 0 : struct acpi_device *adev = arg;
414 : 0 : struct i2c_board_info info;
415 : 0 : acpi_handle adapter_handle;
416 : 0 : struct i2c_adapter *adapter;
417 : 0 : struct i2c_client *client;
418 : :
419 [ # # # ]: 0 : switch (value) {
420 : 0 : case ACPI_RECONFIG_DEVICE_ADD:
421 [ # # ]: 0 : if (i2c_acpi_get_info(adev, &info, NULL, &adapter_handle))
422 : : break;
423 : :
424 : 0 : adapter = i2c_acpi_find_adapter_by_handle(adapter_handle);
425 [ # # ]: 0 : if (!adapter)
426 : : break;
427 : :
428 : 0 : i2c_acpi_register_device(adapter, adev, &info);
429 : 0 : break;
430 : : case ACPI_RECONFIG_DEVICE_REMOVE:
431 [ # # # # ]: 0 : if (!acpi_device_enumerated(adev))
432 : : break;
433 : :
434 : 0 : client = i2c_acpi_find_client_by_adev(adev);
435 [ # # ]: 0 : if (!client)
436 : : break;
437 : :
438 : 0 : i2c_unregister_device(client);
439 : 0 : put_device(&client->dev);
440 : 0 : break;
441 : : }
442 : :
443 : 0 : return NOTIFY_OK;
444 : : }
445 : :
446 : : struct notifier_block i2c_acpi_notifier = {
447 : : .notifier_call = i2c_acpi_notify,
448 : : };
449 : :
450 : : /**
451 : : * i2c_acpi_new_device - Create i2c-client for the Nth I2cSerialBus resource
452 : : * @dev: Device owning the ACPI resources to get the client from
453 : : * @index: Index of ACPI resource to get
454 : : * @info: describes the I2C device; note this is modified (addr gets set)
455 : : * Context: can sleep
456 : : *
457 : : * By default the i2c subsys creates an i2c-client for the first I2cSerialBus
458 : : * resource of an acpi_device, but some acpi_devices have multiple I2cSerialBus
459 : : * resources, in that case this function can be used to create an i2c-client
460 : : * for other I2cSerialBus resources in the Current Resource Settings table.
461 : : *
462 : : * Also see i2c_new_client_device, which this function calls to create the
463 : : * i2c-client.
464 : : *
465 : : * Returns a pointer to the new i2c-client, or error pointer in case of failure.
466 : : * Specifically, -EPROBE_DEFER is returned if the adapter is not found.
467 : : */
468 : 0 : struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
469 : : struct i2c_board_info *info)
470 : : {
471 : 0 : struct i2c_acpi_lookup lookup;
472 : 0 : struct i2c_adapter *adapter;
473 : 0 : struct acpi_device *adev;
474 : 0 : LIST_HEAD(resource_list);
475 : 0 : int ret;
476 : :
477 [ # # ]: 0 : adev = ACPI_COMPANION(dev);
478 [ # # ]: 0 : if (!adev)
479 : : return ERR_PTR(-EINVAL);
480 : :
481 : 0 : memset(&lookup, 0, sizeof(lookup));
482 : 0 : lookup.info = info;
483 : 0 : lookup.device_handle = acpi_device_handle(adev);
484 : 0 : lookup.index = index;
485 : :
486 : 0 : ret = acpi_dev_get_resources(adev, &resource_list,
487 : : i2c_acpi_fill_info, &lookup);
488 [ # # ]: 0 : if (ret < 0)
489 : 0 : return ERR_PTR(ret);
490 : :
491 : 0 : acpi_dev_free_resource_list(&resource_list);
492 : :
493 [ # # ]: 0 : if (!info->addr)
494 : : return ERR_PTR(-EADDRNOTAVAIL);
495 : :
496 : 0 : adapter = i2c_acpi_find_adapter_by_handle(lookup.adapter_handle);
497 [ # # ]: 0 : if (!adapter)
498 : : return ERR_PTR(-EPROBE_DEFER);
499 : :
500 : 0 : return i2c_new_client_device(adapter, info);
501 : : }
502 : : EXPORT_SYMBOL_GPL(i2c_acpi_new_device);
503 : :
504 : : #ifdef CONFIG_ACPI_I2C_OPREGION
505 : 0 : static int acpi_gsb_i2c_read_bytes(struct i2c_client *client,
506 : : u8 cmd, u8 *data, u8 data_len)
507 : : {
508 : :
509 : 0 : struct i2c_msg msgs[2];
510 : 0 : int ret;
511 : 0 : u8 *buffer;
512 : :
513 : 0 : buffer = kzalloc(data_len, GFP_KERNEL);
514 [ # # ]: 0 : if (!buffer)
515 : : return AE_NO_MEMORY;
516 : :
517 : 0 : msgs[0].addr = client->addr;
518 : 0 : msgs[0].flags = client->flags;
519 : 0 : msgs[0].len = 1;
520 : 0 : msgs[0].buf = &cmd;
521 : :
522 : 0 : msgs[1].addr = client->addr;
523 : 0 : msgs[1].flags = client->flags | I2C_M_RD;
524 : 0 : msgs[1].len = data_len;
525 : 0 : msgs[1].buf = buffer;
526 : :
527 : 0 : ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
528 [ # # ]: 0 : if (ret < 0) {
529 : : /* Getting a NACK is unfortunately normal with some DSTDs */
530 [ # # ]: 0 : if (ret == -EREMOTEIO)
531 : : dev_dbg(&client->adapter->dev, "i2c read %d bytes from client@%#x starting at reg %#x failed, error: %d\n",
532 : : data_len, client->addr, cmd, ret);
533 : : else
534 : 0 : dev_err(&client->adapter->dev, "i2c read %d bytes from client@%#x starting at reg %#x failed, error: %d\n",
535 : : data_len, client->addr, cmd, ret);
536 : : /* 2 transfers must have completed successfully */
537 [ # # ]: 0 : } else if (ret == 2) {
538 : 0 : memcpy(data, buffer, data_len);
539 : 0 : ret = 0;
540 : : } else {
541 : : ret = -EIO;
542 : : }
543 : :
544 : 0 : kfree(buffer);
545 : 0 : return ret;
546 : : }
547 : :
548 : 0 : static int acpi_gsb_i2c_write_bytes(struct i2c_client *client,
549 : : u8 cmd, u8 *data, u8 data_len)
550 : : {
551 : :
552 : 0 : struct i2c_msg msgs[1];
553 : 0 : u8 *buffer;
554 : 0 : int ret = AE_OK;
555 : :
556 : 0 : buffer = kzalloc(data_len + 1, GFP_KERNEL);
557 [ # # ]: 0 : if (!buffer)
558 : : return AE_NO_MEMORY;
559 : :
560 : 0 : buffer[0] = cmd;
561 : 0 : memcpy(buffer + 1, data, data_len);
562 : :
563 : 0 : msgs[0].addr = client->addr;
564 : 0 : msgs[0].flags = client->flags;
565 : 0 : msgs[0].len = data_len + 1;
566 : 0 : msgs[0].buf = buffer;
567 : :
568 : 0 : ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
569 : :
570 : 0 : kfree(buffer);
571 : :
572 [ # # ]: 0 : if (ret < 0) {
573 : 0 : dev_err(&client->adapter->dev, "i2c write failed: %d\n", ret);
574 : 0 : return ret;
575 : : }
576 : :
577 : : /* 1 transfer must have completed successfully */
578 [ # # ]: 0 : return (ret == 1) ? 0 : -EIO;
579 : : }
580 : :
581 : : static acpi_status
582 : 0 : i2c_acpi_space_handler(u32 function, acpi_physical_address command,
583 : : u32 bits, u64 *value64,
584 : : void *handler_context, void *region_context)
585 : : {
586 : 0 : struct gsb_buffer *gsb = (struct gsb_buffer *)value64;
587 : 0 : struct i2c_acpi_handler_data *data = handler_context;
588 : 0 : struct acpi_connection_info *info = &data->info;
589 : 0 : struct acpi_resource_i2c_serialbus *sb;
590 : 0 : struct i2c_adapter *adapter = data->adapter;
591 : 0 : struct i2c_client *client;
592 : 0 : struct acpi_resource *ares;
593 : 0 : u32 accessor_type = function >> 16;
594 : 0 : u8 action = function & ACPI_IO_MASK;
595 : 0 : acpi_status ret;
596 : 0 : int status;
597 : :
598 : 0 : ret = acpi_buffer_to_resource(info->connection, info->length, &ares);
599 [ # # ]: 0 : if (ACPI_FAILURE(ret))
600 : : return ret;
601 : :
602 : 0 : client = kzalloc(sizeof(*client), GFP_KERNEL);
603 [ # # ]: 0 : if (!client) {
604 : 0 : ret = AE_NO_MEMORY;
605 : 0 : goto err;
606 : : }
607 : :
608 [ # # # # : 0 : if (!value64 || !i2c_acpi_get_i2c_resource(ares, &sb)) {
# # ]
609 : 0 : ret = AE_BAD_PARAMETER;
610 : 0 : goto err;
611 : : }
612 : :
613 : 0 : client->adapter = adapter;
614 : 0 : client->addr = sb->slave_address;
615 : :
616 [ # # ]: 0 : if (sb->access_mode == ACPI_I2C_10BIT_MODE)
617 : 0 : client->flags |= I2C_CLIENT_TEN;
618 : :
619 [ # # # # : 0 : switch (accessor_type) {
# # ]
620 : 0 : case ACPI_GSB_ACCESS_ATTRIB_SEND_RCV:
621 [ # # ]: 0 : if (action == ACPI_READ) {
622 : 0 : status = i2c_smbus_read_byte(client);
623 [ # # ]: 0 : if (status >= 0) {
624 : 0 : gsb->bdata = status;
625 : 0 : status = 0;
626 : : }
627 : : } else {
628 : 0 : status = i2c_smbus_write_byte(client, gsb->bdata);
629 : : }
630 : : break;
631 : :
632 : 0 : case ACPI_GSB_ACCESS_ATTRIB_BYTE:
633 [ # # ]: 0 : if (action == ACPI_READ) {
634 : 0 : status = i2c_smbus_read_byte_data(client, command);
635 [ # # ]: 0 : if (status >= 0) {
636 : 0 : gsb->bdata = status;
637 : 0 : status = 0;
638 : : }
639 : : } else {
640 : 0 : status = i2c_smbus_write_byte_data(client, command,
641 : 0 : gsb->bdata);
642 : : }
643 : : break;
644 : :
645 : 0 : case ACPI_GSB_ACCESS_ATTRIB_WORD:
646 [ # # ]: 0 : if (action == ACPI_READ) {
647 : 0 : status = i2c_smbus_read_word_data(client, command);
648 [ # # ]: 0 : if (status >= 0) {
649 : 0 : gsb->wdata = status;
650 : 0 : status = 0;
651 : : }
652 : : } else {
653 : 0 : status = i2c_smbus_write_word_data(client, command,
654 : 0 : gsb->wdata);
655 : : }
656 : : break;
657 : :
658 : 0 : case ACPI_GSB_ACCESS_ATTRIB_BLOCK:
659 [ # # ]: 0 : if (action == ACPI_READ) {
660 : 0 : status = i2c_smbus_read_block_data(client, command,
661 : 0 : gsb->data);
662 [ # # ]: 0 : if (status >= 0) {
663 : 0 : gsb->len = status;
664 : 0 : status = 0;
665 : : }
666 : : } else {
667 : 0 : status = i2c_smbus_write_block_data(client, command,
668 : 0 : gsb->len, gsb->data);
669 : : }
670 : : break;
671 : :
672 : 0 : case ACPI_GSB_ACCESS_ATTRIB_MULTIBYTE:
673 [ # # ]: 0 : if (action == ACPI_READ) {
674 : 0 : status = acpi_gsb_i2c_read_bytes(client, command,
675 : 0 : gsb->data, info->access_length);
676 : : } else {
677 : 0 : status = acpi_gsb_i2c_write_bytes(client, command,
678 : 0 : gsb->data, info->access_length);
679 : : }
680 : : break;
681 : :
682 : 0 : default:
683 : 0 : dev_warn(&adapter->dev, "protocol 0x%02x not supported for client 0x%02x\n",
684 : : accessor_type, client->addr);
685 : 0 : ret = AE_BAD_PARAMETER;
686 : 0 : goto err;
687 : : }
688 : :
689 : 0 : gsb->status = status;
690 : :
691 : 0 : err:
692 : 0 : kfree(client);
693 : 0 : ACPI_FREE(ares);
694 : 0 : return ret;
695 : : }
696 : :
697 : :
698 : 0 : int i2c_acpi_install_space_handler(struct i2c_adapter *adapter)
699 : : {
700 : 0 : acpi_handle handle;
701 : 0 : struct i2c_acpi_handler_data *data;
702 : 0 : acpi_status status;
703 : :
704 [ # # ]: 0 : if (!adapter->dev.parent)
705 : : return -ENODEV;
706 : :
707 [ # # # # ]: 0 : handle = ACPI_HANDLE(adapter->dev.parent);
708 : :
709 [ # # ]: 0 : if (!handle)
710 : : return -ENODEV;
711 : :
712 : 0 : data = kzalloc(sizeof(struct i2c_acpi_handler_data),
713 : : GFP_KERNEL);
714 [ # # ]: 0 : if (!data)
715 : : return -ENOMEM;
716 : :
717 : 0 : data->adapter = adapter;
718 : 0 : status = acpi_bus_attach_private_data(handle, (void *)data);
719 [ # # ]: 0 : if (ACPI_FAILURE(status)) {
720 : 0 : kfree(data);
721 : 0 : return -ENOMEM;
722 : : }
723 : :
724 : 0 : status = acpi_install_address_space_handler(handle,
725 : : ACPI_ADR_SPACE_GSBUS,
726 : : &i2c_acpi_space_handler,
727 : : NULL,
728 : : data);
729 [ # # ]: 0 : if (ACPI_FAILURE(status)) {
730 : 0 : dev_err(&adapter->dev, "Error installing i2c space handler\n");
731 : 0 : acpi_bus_detach_private_data(handle);
732 : 0 : kfree(data);
733 : 0 : return -ENOMEM;
734 : : }
735 : :
736 : 0 : acpi_walk_dep_device_list(handle);
737 : 0 : return 0;
738 : : }
739 : :
740 : 0 : void i2c_acpi_remove_space_handler(struct i2c_adapter *adapter)
741 : : {
742 : 0 : acpi_handle handle;
743 : 0 : struct i2c_acpi_handler_data *data;
744 : 0 : acpi_status status;
745 : :
746 [ # # ]: 0 : if (!adapter->dev.parent)
747 : 0 : return;
748 : :
749 [ # # # # ]: 0 : handle = ACPI_HANDLE(adapter->dev.parent);
750 : :
751 [ # # ]: 0 : if (!handle)
752 : : return;
753 : :
754 : 0 : acpi_remove_address_space_handler(handle,
755 : : ACPI_ADR_SPACE_GSBUS,
756 : : &i2c_acpi_space_handler);
757 : :
758 : 0 : status = acpi_bus_get_private_data(handle, (void **)&data);
759 [ # # ]: 0 : if (ACPI_SUCCESS(status))
760 : 0 : kfree(data);
761 : :
762 : 0 : acpi_bus_detach_private_data(handle);
763 : : }
764 : : #endif /* CONFIG_ACPI_I2C_OPREGION */
|