1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2015 - 2016 Xilinx, Inc.
4 * Copyright (C) 2017 National Instruments Corp
5 * Written by Michal Simek
13 #include <asm-generic/gpio.h>
15 DECLARE_GLOBAL_DATA_PTR
;
33 u32 addr
; /* I2C mux address */
34 u32 width
; /* I2C mux width - number of busses */
35 struct gpio_desc gpio_mux_reset
;
38 static const struct chip_desc chips
[] = {
41 .muxtype
= pca954x_ismux
,
46 .muxtype
= pca954x_ismux
,
51 .muxtype
= pca954x_isswi
,
56 static int pca954x_deselect(struct udevice
*mux
, struct udevice
*bus
,
59 struct pca954x_priv
*priv
= dev_get_priv(mux
);
62 return dm_i2c_write(mux
, priv
->addr
, &byte
, 1);
65 static int pca954x_select(struct udevice
*mux
, struct udevice
*bus
,
68 struct pca954x_priv
*priv
= dev_get_priv(mux
);
69 const struct chip_desc
*chip
= &chips
[dev_get_driver_data(mux
)];
72 if (chip
->muxtype
== pca954x_ismux
)
73 byte
= channel
| chip
->enable
;
77 return dm_i2c_write(mux
, priv
->addr
, &byte
, 1);
80 static const struct i2c_mux_ops pca954x_ops
= {
81 .select
= pca954x_select
,
82 .deselect
= pca954x_deselect
,
85 static const struct udevice_id pca954x_ids
[] = {
86 { .compatible
= "nxp,pca9544", .data
= PCA9544
},
87 { .compatible
= "nxp,pca9547", .data
= PCA9547
},
88 { .compatible
= "nxp,pca9548", .data
= PCA9548
},
92 static int pca954x_ofdata_to_platdata(struct udevice
*dev
)
94 struct pca954x_priv
*priv
= dev_get_priv(dev
);
95 const struct chip_desc
*chip
= &chips
[dev_get_driver_data(dev
)];
97 priv
->addr
= fdtdec_get_int(gd
->fdt_blob
, dev_of_offset(dev
), "reg", 0);
99 debug("MUX not found\n");
102 priv
->width
= chip
->width
;
105 debug("No I2C MUX width specified\n");
109 debug("Device %s at 0x%x with width %d\n",
110 dev
->name
, priv
->addr
, priv
->width
);
115 static int pca954x_probe(struct udevice
*dev
)
117 if (IS_ENABLED(CONFIG_DM_GPIO
)) {
118 struct pca954x_priv
*priv
= dev_get_priv(dev
);
121 err
= gpio_request_by_name(dev
, "reset-gpios", 0,
122 &priv
->gpio_mux_reset
, GPIOD_IS_OUT
);
124 /* it's optional so only bail if we get a real error */
125 if (err
&& (err
!= -ENOENT
))
128 /* dm will take care of polarity */
129 if (dm_gpio_is_valid(&priv
->gpio_mux_reset
))
130 dm_gpio_set_value(&priv
->gpio_mux_reset
, 0);
136 static int pca954x_remove(struct udevice
*dev
)
138 if (IS_ENABLED(CONFIG_DM_GPIO
)) {
139 struct pca954x_priv
*priv
= dev_get_priv(dev
);
141 if (dm_gpio_is_valid(&priv
->gpio_mux_reset
))
142 dm_gpio_free(dev
, &priv
->gpio_mux_reset
);
148 U_BOOT_DRIVER(pca954x
) = {
150 .id
= UCLASS_I2C_MUX
,
151 .of_match
= pca954x_ids
,
152 .probe
= pca954x_probe
,
153 .remove
= pca954x_remove
,
155 .ofdata_to_platdata
= pca954x_ofdata_to_platdata
,
156 .priv_auto_alloc_size
= sizeof(struct pca954x_priv
),