1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- /*
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2021 YADRO
- *
- * Authors:
- * Nikita Shubin <n.shubin@yadro.com>
- *
- * derivate: lib/utils/gpio/fdt_gpio.c
- * Authors:
- * Anup Patel <anup.patel@wdc.com>
- */
- #include <libfdt.h>
- #include <sbi/sbi_error.h>
- #include <sbi_utils/fdt/fdt_helper.h>
- #include <sbi_utils/i2c/fdt_i2c.h>
- /* List of FDT i2c adapter drivers generated at compile time */
- extern struct fdt_i2c_adapter *fdt_i2c_adapter_drivers[];
- extern unsigned long fdt_i2c_adapter_drivers_size;
- static int fdt_i2c_adapter_init(void *fdt, int nodeoff)
- {
- int pos, rc;
- struct fdt_i2c_adapter *drv;
- const struct fdt_match *match;
- /* Try all I2C drivers one-by-one */
- for (pos = 0; pos < fdt_i2c_adapter_drivers_size; pos++) {
- drv = fdt_i2c_adapter_drivers[pos];
- match = fdt_match_node(fdt, nodeoff, drv->match_table);
- if (match && drv->init) {
- rc = drv->init(fdt, nodeoff, match);
- if (rc == SBI_ENODEV)
- continue;
- if (rc)
- return rc;
- return 0;
- }
- }
- return SBI_ENOSYS;
- }
- static int fdt_i2c_adapter_find(void *fdt, int nodeoff,
- struct i2c_adapter **out_adapter)
- {
- int rc;
- struct i2c_adapter *adapter = i2c_adapter_find(nodeoff);
- if (!adapter) {
- /* I2C adapter not found so initialize matching driver */
- rc = fdt_i2c_adapter_init(fdt, nodeoff);
- if (rc)
- return rc;
- /* Try to find I2C adapter again */
- adapter = i2c_adapter_find(nodeoff);
- if (!adapter)
- return SBI_ENOSYS;
- }
- if (out_adapter)
- *out_adapter = adapter;
- return 0;
- }
- int fdt_i2c_adapter_get(void *fdt, int nodeoff,
- struct i2c_adapter **out_adapter)
- {
- int rc;
- struct i2c_adapter *adapter;
- if (!fdt || (nodeoff < 0) || !out_adapter)
- return SBI_EINVAL;
- rc = fdt_i2c_adapter_find(fdt, nodeoff, &adapter);
- if (rc)
- return rc;
- *out_adapter = adapter;
- return 0;
- }
|