Add support for ACPI-based I2C mux attachment.
This commit is contained in:
parent
3a8ddc74d3
commit
608e11c703
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: i2cmux_fdt.c,v 1.6 2021/01/18 02:35:49 thorpej Exp $ */
|
||||
/* $NetBSD: i2cmux_fdt.c,v 1.7 2021/01/25 12:18:18 jmcneill Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2020 The NetBSD Foundation, Inc.
|
||||
|
@ -30,7 +30,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: i2cmux_fdt.c,v 1.6 2021/01/18 02:35:49 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: i2cmux_fdt.c,v 1.7 2021/01/25 12:18:18 jmcneill Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/device.h>
|
||||
|
@ -63,7 +63,7 @@ iicmux_gpio_get_mux_info(struct iicmux_softc * const sc)
|
|||
|
||||
mux_data = kmem_zalloc(sizeof(*mux_data), KM_SLEEP);
|
||||
|
||||
mux_data->npins = fdtbus_gpio_count(sc->sc_phandle, "mux-gpios");
|
||||
mux_data->npins = fdtbus_gpio_count(sc->sc_handle, "mux-gpios");
|
||||
if (mux_data->npins == 0) {
|
||||
aprint_error_dev(sc->sc_dev,
|
||||
"unable to get mux-gpios property\n");
|
||||
|
@ -73,7 +73,7 @@ iicmux_gpio_get_mux_info(struct iicmux_softc * const sc)
|
|||
mux_data->pins =
|
||||
kmem_zalloc(sizeof(*mux_data->pins) * mux_data->npins, KM_SLEEP);
|
||||
for (i = 0; i < mux_data->npins; i++) {
|
||||
mux_data->pins[i] = fdtbus_gpio_acquire_index(sc->sc_phandle,
|
||||
mux_data->pins[i] = fdtbus_gpio_acquire_index(sc->sc_handle,
|
||||
"mux-gpios", i, GPIO_PIN_OUTPUT);
|
||||
if (mux_data->pins[i] == NULL) {
|
||||
aprint_error_dev(sc->sc_dev,
|
||||
|
@ -83,7 +83,7 @@ iicmux_gpio_get_mux_info(struct iicmux_softc * const sc)
|
|||
}
|
||||
|
||||
mux_data->has_idle_value =
|
||||
of_getprop_uint32(sc->sc_phandle, "idle-state",
|
||||
of_getprop_uint32(sc->sc_handle, "idle-state",
|
||||
&mux_data->idle_value) == 0;
|
||||
|
||||
return mux_data;
|
||||
|
@ -107,7 +107,7 @@ iicmux_gpio_get_bus_info(struct iicmux_bus * const bus)
|
|||
|
||||
bus_info = kmem_zalloc(sizeof(*bus_info), KM_SLEEP);
|
||||
|
||||
error = fdtbus_get_reg(bus->phandle, 0, &bus_info->value, NULL);
|
||||
error = fdtbus_get_reg(bus->handle, 0, &bus_info->value, NULL);
|
||||
if (error) {
|
||||
aprint_error_dev(sc->sc_dev,
|
||||
"unable to get reg property for bus %d\n", bus->busidx);
|
||||
|
@ -177,7 +177,7 @@ iicmux_pinctrl_get_mux_info(struct iicmux_softc * const sc)
|
|||
mux_info = kmem_alloc(sizeof(*mux_info), KM_SLEEP);
|
||||
|
||||
mux_info->has_idle_idx =
|
||||
fdtbus_get_index(sc->sc_phandle, "pinctrl-names", "idle",
|
||||
fdtbus_get_index(sc->sc_handle, "pinctrl-names", "idle",
|
||||
&mux_info->idle_idx) == 0;
|
||||
|
||||
return mux_info;
|
||||
|
@ -192,7 +192,7 @@ iicmux_pinctrl_get_bus_info(struct iicmux_bus * const bus)
|
|||
|
||||
bus_info = kmem_alloc(sizeof(*bus_info), KM_SLEEP);
|
||||
|
||||
error = fdtbus_get_reg(bus->phandle, 0, &bus_info->idx, NULL);
|
||||
error = fdtbus_get_reg(bus->handle, 0, &bus_info->idx, NULL);
|
||||
if (error) {
|
||||
aprint_error_dev(sc->sc_dev,
|
||||
"unable to get reg property for bus %d\n", bus->busidx);
|
||||
|
@ -210,7 +210,7 @@ iicmux_pinctrl_acquire_bus(struct iicmux_bus * const bus,
|
|||
struct iicmux_softc * const sc = bus->mux;
|
||||
struct bus_info_pinctrl * const bus_info = bus->bus_data;
|
||||
|
||||
return fdtbus_pinctrl_set_config_index(sc->sc_phandle, bus_info->idx);
|
||||
return fdtbus_pinctrl_set_config_index(sc->sc_handle, bus_info->idx);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -221,7 +221,7 @@ iicmux_pinctrl_release_bus(struct iicmux_bus * const bus,
|
|||
struct mux_info_pinctrl * const mux_info = sc->sc_mux_data;
|
||||
|
||||
if (mux_info->has_idle_idx) {
|
||||
(void) fdtbus_pinctrl_set_config_index(sc->sc_phandle,
|
||||
(void) fdtbus_pinctrl_set_config_index(sc->sc_handle,
|
||||
mux_info->idle_idx);
|
||||
}
|
||||
}
|
||||
|
@ -261,13 +261,13 @@ iicmux_fdt_attach(device_t const parent, device_t const self, void * const aux)
|
|||
struct fdt_attach_args * const faa = aux;
|
||||
|
||||
sc->sc_dev = self;
|
||||
sc->sc_phandle = faa->faa_phandle;
|
||||
sc->sc_config = of_search_compatible(sc->sc_phandle, compat_data)->data;
|
||||
sc->sc_handle = faa->faa_phandle;
|
||||
sc->sc_config = of_search_compatible(sc->sc_handle, compat_data)->data;
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": %s I2C mux\n", sc->sc_config->desc);
|
||||
|
||||
sc->sc_i2c_parent = fdtbus_i2c_acquire(sc->sc_phandle, "i2c-parent");
|
||||
sc->sc_i2c_parent = fdtbus_i2c_acquire(sc->sc_handle, "i2c-parent");
|
||||
if (sc->sc_i2c_parent == NULL) {
|
||||
aprint_error_dev(sc->sc_dev, "unable to acquire i2c-parent\n");
|
||||
return;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: i2c.c,v 1.76 2021/01/18 15:28:21 thorpej Exp $ */
|
||||
/* $NetBSD: i2c.c,v 1.77 2021/01/25 12:18:18 jmcneill Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Wasabi Systems, Inc.
|
||||
|
@ -40,7 +40,7 @@
|
|||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: i2c.c,v 1.76 2021/01/18 15:28:21 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: i2c.c,v 1.77 2021/01/25 12:18:18 jmcneill Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -439,6 +439,7 @@ iic_attach(device_t parent, device_t self, void *aux)
|
|||
prop_data_t cdata;
|
||||
uint32_t addr;
|
||||
uint64_t cookie;
|
||||
uint32_t cookietype;
|
||||
const char *name;
|
||||
struct i2c_attach_args ia;
|
||||
int loc[IICCF_NLOCS];
|
||||
|
@ -457,6 +458,9 @@ iic_attach(device_t parent, device_t self, void *aux)
|
|||
continue;
|
||||
if (!prop_dictionary_get_uint64(dev, "cookie", &cookie))
|
||||
cookie = 0;
|
||||
if (!prop_dictionary_get_uint32(dev, "cookietype",
|
||||
&cookietype))
|
||||
cookietype = I2C_COOKIE_NONE;
|
||||
loc[IICCF_ADDR] = addr;
|
||||
|
||||
memset(&ia, 0, sizeof ia);
|
||||
|
@ -464,6 +468,7 @@ iic_attach(device_t parent, device_t self, void *aux)
|
|||
ia.ia_tag = ic;
|
||||
ia.ia_name = name;
|
||||
ia.ia_cookie = cookie;
|
||||
ia.ia_cookietype = cookietype;
|
||||
ia.ia_prop = dev;
|
||||
|
||||
buf = NULL;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: i2cmux.c,v 1.2 2021/01/24 19:35:21 jmcneill Exp $ */
|
||||
/* $NetBSD: i2cmux.c,v 1.3 2021/01/25 12:18:18 jmcneill Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2020 The NetBSD Foundation, Inc.
|
||||
|
@ -29,8 +29,12 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__i386__) || defined(__amd64__) || defined(__aarch64__)
|
||||
#include "acpica.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: i2cmux.c,v 1.2 2021/01/24 19:35:21 jmcneill Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: i2cmux.c,v 1.3 2021/01/25 12:18:18 jmcneill Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/device.h>
|
||||
|
@ -41,6 +45,11 @@ __KERNEL_RCSID(0, "$NetBSD: i2cmux.c,v 1.2 2021/01/24 19:35:21 jmcneill Exp $");
|
|||
#include <dev/i2c/i2cvar.h>
|
||||
#include <dev/i2c/i2cmuxvar.h>
|
||||
|
||||
#if NACPICA > 0
|
||||
#include <dev/acpi/acpivar.h>
|
||||
#include <dev/acpi/acpi_i2c.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* i2c mux
|
||||
*
|
||||
|
@ -154,13 +163,14 @@ iicmux_print(void * const aux, const char * const pnp)
|
|||
|
||||
static void
|
||||
iicmux_attach_bus(struct iicmux_softc * const sc,
|
||||
int const phandle, int const busidx)
|
||||
uintptr_t const handle, enum i2c_cookie_type handletype, int const busidx)
|
||||
{
|
||||
struct iicmux_bus * const bus = &sc->sc_busses[busidx];
|
||||
|
||||
bus->mux = sc;
|
||||
bus->busidx = busidx;
|
||||
bus->phandle = phandle;
|
||||
bus->handle = handle;
|
||||
bus->handletype = handletype;
|
||||
|
||||
bus->bus_data = sc->sc_config->get_bus_info(bus);
|
||||
if (bus->bus_data == NULL) {
|
||||
|
@ -175,41 +185,41 @@ iicmux_attach_bus(struct iicmux_softc * const sc,
|
|||
bus->controller.ic_release_bus = iicmux_release_bus;
|
||||
bus->controller.ic_exec = iicmux_exec;
|
||||
|
||||
fdtbus_register_i2c_controller(&bus->controller, bus->phandle);
|
||||
switch (handletype) {
|
||||
case I2C_COOKIE_OF:
|
||||
fdtbus_register_i2c_controller(&bus->controller,
|
||||
(int)bus->handle);
|
||||
|
||||
fdtbus_attach_i2cbus(sc->sc_dev, bus->phandle, &bus->controller,
|
||||
iicmux_print);
|
||||
fdtbus_attach_i2cbus(sc->sc_dev, (int)bus->handle,
|
||||
&bus->controller, iicmux_print);
|
||||
break;
|
||||
#if NACPICA > 0
|
||||
case I2C_COOKIE_ACPI: {
|
||||
struct acpi_devnode *ad = acpi_match_node((ACPI_HANDLE)handle);
|
||||
KASSERT(ad != NULL);
|
||||
struct i2cbus_attach_args iba = {
|
||||
.iba_tag = &bus->controller,
|
||||
.iba_child_devices = acpi_enter_i2c_devs(ad)
|
||||
};
|
||||
config_found_ia(sc->sc_dev, "i2cbus", &iba, iicbus_print);
|
||||
} break;
|
||||
#endif
|
||||
default:
|
||||
aprint_error_dev(sc->sc_dev, "unknown handle type\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
iicmux_attach(struct iicmux_softc * const sc)
|
||||
static void
|
||||
iicmux_attach_fdt(struct iicmux_softc * const sc)
|
||||
{
|
||||
|
||||
/*
|
||||
* We expect sc->sc_phandle, sc->sc_config, and sc->sc_i2c_parent
|
||||
* to be initialized by the front-end.
|
||||
*/
|
||||
KASSERT(sc->sc_phandle > 0);
|
||||
KASSERT(sc->sc_config != NULL);
|
||||
KASSERT(sc->sc_i2c_parent != NULL);
|
||||
|
||||
/*
|
||||
* We start out assuming that the i2c bus nodes are children of
|
||||
* our own node. We'll adjust later if we encounter an "i2c-mux"
|
||||
* node when counting our children. If we encounter such a node,
|
||||
* then it's that node that is the parent of the i2c bus children.
|
||||
*/
|
||||
sc->sc_i2c_mux_phandle = sc->sc_phandle;
|
||||
|
||||
/*
|
||||
* Gather up all of the various bits of information needed
|
||||
* for this particular type of i2c mux.
|
||||
*/
|
||||
sc->sc_mux_data = sc->sc_config->get_mux_info(sc);
|
||||
if (sc->sc_mux_data == NULL) {
|
||||
aprint_error_dev(sc->sc_dev, "unable to get info for mux\n");
|
||||
return;
|
||||
}
|
||||
sc->sc_i2c_mux_phandle = (int)sc->sc_handle;
|
||||
|
||||
sc->sc_nbusses = iicmux_count_children(sc);
|
||||
if (sc->sc_nbusses == 0) {
|
||||
|
@ -223,6 +233,84 @@ iicmux_attach(struct iicmux_softc * const sc)
|
|||
for (child = OF_child(sc->sc_i2c_mux_phandle), idx = 0; child;
|
||||
child = OF_peer(child), idx++) {
|
||||
KASSERT(idx < sc->sc_nbusses);
|
||||
iicmux_attach_bus(sc, child, idx);
|
||||
iicmux_attach_bus(sc, child, I2C_COOKIE_OF, idx);
|
||||
}
|
||||
}
|
||||
|
||||
#if NACPICA > 0
|
||||
static void
|
||||
iicmux_attach_acpi(struct iicmux_softc * const sc)
|
||||
{
|
||||
ACPI_HANDLE hdl = (ACPI_HANDLE)sc->sc_handle;
|
||||
struct acpi_devnode *devnode, *ad;
|
||||
int idx;
|
||||
|
||||
devnode = acpi_match_node(hdl);
|
||||
KASSERT(devnode != NULL);
|
||||
|
||||
/* Count child busses */
|
||||
sc->sc_nbusses = 0;
|
||||
SIMPLEQ_FOREACH(ad, &devnode->ad_child_head, ad_child_list) {
|
||||
if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE ||
|
||||
!acpi_device_present(ad->ad_handle)) {
|
||||
continue;
|
||||
}
|
||||
sc->sc_nbusses++;
|
||||
}
|
||||
|
||||
sc->sc_busses = kmem_zalloc(sizeof(*sc->sc_busses) * sc->sc_nbusses,
|
||||
KM_SLEEP);
|
||||
|
||||
/* Attach child busses */
|
||||
idx = 0;
|
||||
SIMPLEQ_FOREACH(ad, &devnode->ad_child_head, ad_child_list) {
|
||||
if (ad->ad_devinfo->Type != ACPI_TYPE_DEVICE ||
|
||||
!acpi_device_present(ad->ad_handle)) {
|
||||
continue;
|
||||
}
|
||||
iicmux_attach_bus(sc, (uintptr_t)ad->ad_handle,
|
||||
I2C_COOKIE_ACPI, idx);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
iicmux_attach(struct iicmux_softc * const sc)
|
||||
{
|
||||
/*
|
||||
* We expect sc->sc_handle, sc->sc_config, and sc->sc_i2c_parent
|
||||
* to be initialized by the front-end.
|
||||
*/
|
||||
KASSERT(sc->sc_handle > 0);
|
||||
KASSERT(sc->sc_config != NULL);
|
||||
KASSERT(sc->sc_i2c_parent != NULL);
|
||||
|
||||
/*
|
||||
* Gather up all of the various bits of information needed
|
||||
* for this particular type of i2c mux.
|
||||
*/
|
||||
sc->sc_mux_data = sc->sc_config->get_mux_info(sc);
|
||||
if (sc->sc_mux_data == NULL) {
|
||||
aprint_error_dev(sc->sc_dev, "unable to get info for mux\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do configuration method (OF, ACPI) specific setup.
|
||||
*/
|
||||
switch (sc->sc_handletype) {
|
||||
case I2C_COOKIE_OF:
|
||||
iicmux_attach_fdt(sc);
|
||||
break;
|
||||
#if NACPICA > 0
|
||||
case I2C_COOKIE_ACPI:
|
||||
iicmux_attach_acpi(sc);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
aprint_error_dev(sc->sc_dev, "could not configure mux: "
|
||||
"handle type %u not supported\n", sc->sc_handletype);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: i2cmuxvar.h,v 1.2 2021/01/24 19:35:45 jmcneill Exp $ */
|
||||
/* $NetBSD: i2cmuxvar.h,v 1.3 2021/01/25 12:18:18 jmcneill Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2020 The NetBSD Foundation, Inc.
|
||||
|
@ -48,14 +48,16 @@ struct iicmux_config {
|
|||
struct iicmux_bus {
|
||||
struct i2c_controller controller;
|
||||
struct iicmux_softc *mux;
|
||||
int phandle;
|
||||
uintptr_t handle;
|
||||
enum i2c_cookie_type handletype;
|
||||
int busidx;
|
||||
void *bus_data;
|
||||
};
|
||||
|
||||
struct iicmux_softc {
|
||||
device_t sc_dev;
|
||||
int sc_phandle;
|
||||
enum i2c_cookie_type sc_handletype;
|
||||
uintptr_t sc_handle;
|
||||
int sc_i2c_mux_phandle;
|
||||
const struct iicmux_config * sc_config;
|
||||
i2c_tag_t sc_i2c_parent;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pcai2cmux.c,v 1.5 2021/01/24 19:38:49 jmcneill Exp $ */
|
||||
/* $NetBSD: pcai2cmux.c,v 1.6 2021/01/25 12:18:18 jmcneill Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2020 The NetBSD Foundation, Inc.
|
||||
|
@ -29,8 +29,12 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__i386__) || defined(__amd64__) || defined(__aarch64__)
|
||||
#include "acpica.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: pcai2cmux.c,v 1.5 2021/01/24 19:38:49 jmcneill Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: pcai2cmux.c,v 1.6 2021/01/25 12:18:18 jmcneill Exp $");
|
||||
|
||||
/*
|
||||
* Driver for NXP PCA954x / PCA984x I2C switches and multiplexers.
|
||||
|
@ -59,6 +63,10 @@ __KERNEL_RCSID(0, "$NetBSD: pcai2cmux.c,v 1.5 2021/01/24 19:38:49 jmcneill Exp $
|
|||
#include <dev/fdt/fdtvar.h>
|
||||
#include <dev/i2c/i2cmuxvar.h>
|
||||
|
||||
#if NACPICA > 0
|
||||
#include <dev/acpi/acpivar.h>
|
||||
#endif
|
||||
|
||||
/* There are a maximum of 8 busses supported. */
|
||||
#define PCAIICMUX_MAX_BUSSES 8
|
||||
|
||||
|
@ -210,10 +218,32 @@ pcaiicmux_get_bus_info(struct iicmux_bus * const bus)
|
|||
struct pcaiicmux_bus_info * const bus_info =
|
||||
&sc->sc_bus_info[bus->busidx];
|
||||
|
||||
error = fdtbus_get_reg(bus->phandle, 0, &addr, NULL);
|
||||
if (error) {
|
||||
aprint_error_dev(iicmux->sc_dev,
|
||||
"unable to get reg property for bus %d\n", bus->busidx);
|
||||
switch (bus->handletype) {
|
||||
case I2C_COOKIE_OF:
|
||||
error = fdtbus_get_reg(bus->handle, 0, &addr, NULL);
|
||||
if (error) {
|
||||
aprint_error_dev(iicmux->sc_dev,
|
||||
"unable to get reg property for bus %d\n",
|
||||
bus->busidx);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
#if NACPICA > 0
|
||||
case I2C_COOKIE_ACPI: {
|
||||
ACPI_INTEGER val;
|
||||
ACPI_STATUS rv;
|
||||
rv = acpi_eval_integer((ACPI_HANDLE)bus->handle, "_ADR", &val);
|
||||
if (ACPI_FAILURE(rv)) {
|
||||
aprint_error_dev(iicmux->sc_dev,
|
||||
"unable to evaluate _ADR for bus %d: %s\n",
|
||||
bus->busidx, AcpiFormatException(rv));
|
||||
return NULL;
|
||||
}
|
||||
addr = (bus_addr_t)val;
|
||||
} break;
|
||||
#endif
|
||||
default:
|
||||
aprint_error_dev(iicmux->sc_dev, "unsupported handle type\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -302,11 +332,11 @@ pcaiicmux_attach(device_t parent, device_t self, void *aux)
|
|||
{
|
||||
struct pcaiicmux_softc * const sc = device_private(self);
|
||||
struct i2c_attach_args * const ia = aux;
|
||||
const int phandle = (int)ia->ia_cookie;
|
||||
int error;
|
||||
|
||||
sc->sc_iicmux.sc_dev = self;
|
||||
sc->sc_iicmux.sc_phandle = phandle;
|
||||
sc->sc_iicmux.sc_handle = ia->ia_cookie;
|
||||
sc->sc_iicmux.sc_handletype = ia->ia_cookietype;
|
||||
sc->sc_iicmux.sc_config = &pcaiicmux_config;
|
||||
sc->sc_iicmux.sc_i2c_parent = ia->ia_tag;
|
||||
sc->sc_addr = ia->ia_addr;
|
||||
|
@ -318,18 +348,21 @@ pcaiicmux_attach(device_t parent, device_t self, void *aux)
|
|||
aprint_normal(": PCA954x I2C %s\n",
|
||||
sc->sc_type->enable_bit ? "mux" : "switch");
|
||||
|
||||
if (of_hasprop(phandle, "i2c-mux-idle-disconnect")) {
|
||||
sc->sc_idle_disconnect = true;
|
||||
}
|
||||
if (ia->ia_cookietype == I2C_COOKIE_OF) {
|
||||
const int phandle = (int)ia->ia_cookie;
|
||||
if (of_hasprop(phandle, "i2c-mux-idle-disconnect")) {
|
||||
sc->sc_idle_disconnect = true;
|
||||
}
|
||||
|
||||
/* Reset the mux if a reset GPIO is specified. */
|
||||
sc->sc_reset_gpio =
|
||||
fdtbus_gpio_acquire(phandle, "reset-gpios", GPIO_PIN_OUTPUT);
|
||||
if (sc->sc_reset_gpio) {
|
||||
fdtbus_gpio_write(sc->sc_reset_gpio, 1);
|
||||
delay(10);
|
||||
fdtbus_gpio_write(sc->sc_reset_gpio, 0);
|
||||
delay(10);
|
||||
/* Reset the mux if a reset GPIO is specified. */
|
||||
sc->sc_reset_gpio = fdtbus_gpio_acquire(phandle, "reset-gpios",
|
||||
GPIO_PIN_OUTPUT);
|
||||
if (sc->sc_reset_gpio) {
|
||||
fdtbus_gpio_write(sc->sc_reset_gpio, 1);
|
||||
delay(10);
|
||||
fdtbus_gpio_write(sc->sc_reset_gpio, 0);
|
||||
delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
/* Force the mux into a disconnected state. */
|
||||
|
|
Loading…
Reference in New Issue