2 * I2C multiplexer for PCA954x series of I2C multiplexer/switch chips.
4 * Copyright 2021 Google LLC
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 #include "qemu/osdep.h"
18 #include "qapi/error.h"
19 #include "hw/i2c/i2c.h"
20 #include "hw/i2c/i2c_mux_pca954x.h"
21 #include "hw/i2c/smbus_slave.h"
22 #include "hw/qdev-core.h"
23 #include "hw/sysbus.h"
25 #include "qemu/module.h"
26 #include "qemu/queue.h"
27 #include "qom/object.h"
30 #define PCA9548_CHANNEL_COUNT 8
31 #define PCA9546_CHANNEL_COUNT 4
34 * struct Pca954xChannel - The i2c mux device will have N of these states
35 * that own the i2c channel bus.
36 * @bus: The owned channel bus.
37 * @enabled: Is this channel active?
39 typedef struct Pca954xChannel
{
47 #define TYPE_PCA954X_CHANNEL "pca954x-channel"
48 #define PCA954X_CHANNEL(obj) \
49 OBJECT_CHECK(Pca954xChannel, (obj), TYPE_PCA954X_CHANNEL)
52 * struct Pca954xState - The pca954x state object.
53 * @control: The value written to the mux control.
54 * @channel: The set of i2c channel buses that act as channels which own the
57 typedef struct Pca954xState
{
62 /* The channel i2c buses. */
63 Pca954xChannel channel
[PCA9548_CHANNEL_COUNT
];
67 * struct Pca954xClass - The pca954x class object.
68 * @nchans: The number of i2c channels this device has.
70 typedef struct Pca954xClass
{
71 SMBusDeviceClass parent
;
76 #define TYPE_PCA954X "pca954x"
77 OBJECT_DECLARE_TYPE(Pca954xState
, Pca954xClass
, PCA954X
)
80 * For each channel, if it's enabled, recursively call match on those children.
82 static bool pca954x_match(I2CSlave
*candidate
, uint8_t address
,
84 I2CNodeList
*current_devs
)
86 Pca954xState
*mux
= PCA954X(candidate
);
87 Pca954xClass
*mc
= PCA954X_GET_CLASS(mux
);
90 /* They are talking to the mux itself (or all devices enabled). */
91 if ((candidate
->address
== address
) || broadcast
) {
92 I2CNode
*node
= g_malloc(sizeof(struct I2CNode
));
93 node
->elt
= candidate
;
94 QLIST_INSERT_HEAD(current_devs
, node
, next
);
100 for (i
= 0; i
< mc
->nchans
; i
++) {
101 if (!mux
->channel
[i
].enabled
) {
105 if (i2c_scan_bus(mux
->channel
[i
].bus
, address
, broadcast
,
113 /* If we arrived here we didn't find a match, return broadcast. */
117 static void pca954x_enable_channel(Pca954xState
*s
, uint8_t enable_mask
)
119 Pca954xClass
*mc
= PCA954X_GET_CLASS(s
);
123 * For each channel, check if their bit is set in enable_mask and if yes,
124 * enable it, otherwise disable, hide it.
126 for (i
= 0; i
< mc
->nchans
; i
++) {
127 if (enable_mask
& (1 << i
)) {
128 s
->channel
[i
].enabled
= true;
130 s
->channel
[i
].enabled
= false;
135 static void pca954x_write(Pca954xState
*s
, uint8_t data
)
138 pca954x_enable_channel(s
, data
);
140 trace_pca954x_write_bytes(data
);
143 static int pca954x_write_data(SMBusDevice
*d
, uint8_t *buf
, uint8_t len
)
145 Pca954xState
*s
= PCA954X(d
);
148 qemu_log_mask(LOG_GUEST_ERROR
, "%s: writing empty data\n", __func__
);
153 * len should be 1, because they write one byte to enable/disable channels.
156 qemu_log_mask(LOG_GUEST_ERROR
,
157 "%s: extra data after channel selection mask\n",
162 pca954x_write(s
, buf
[0]);
166 static uint8_t pca954x_read_byte(SMBusDevice
*d
)
168 Pca954xState
*s
= PCA954X(d
);
169 uint8_t data
= s
->control
;
170 trace_pca954x_read_data(data
);
174 static void pca954x_enter_reset(Object
*obj
, ResetType type
)
176 Pca954xState
*s
= PCA954X(obj
);
177 /* Reset will disable all channels. */
181 I2CBus
*pca954x_i2c_get_bus(I2CSlave
*mux
, uint8_t channel
)
183 Pca954xClass
*pc
= PCA954X_GET_CLASS(mux
);
184 Pca954xState
*pca954x
= PCA954X(mux
);
186 g_assert(channel
< pc
->nchans
);
187 return I2C_BUS(qdev_get_child_bus(DEVICE(&pca954x
->channel
[channel
]),
191 static void pca954x_channel_init(Object
*obj
)
193 Pca954xChannel
*s
= PCA954X_CHANNEL(obj
);
194 s
->bus
= i2c_init_bus(DEVICE(s
), "i2c-bus");
196 /* Start all channels as disabled. */
200 static void pca954x_channel_class_init(ObjectClass
*klass
, void *data
)
202 DeviceClass
*dc
= DEVICE_CLASS(klass
);
203 dc
->desc
= "Pca954x Channel";
206 static void pca9546_class_init(ObjectClass
*klass
, void *data
)
208 Pca954xClass
*s
= PCA954X_CLASS(klass
);
209 s
->nchans
= PCA9546_CHANNEL_COUNT
;
212 static void pca9548_class_init(ObjectClass
*klass
, void *data
)
214 Pca954xClass
*s
= PCA954X_CLASS(klass
);
215 s
->nchans
= PCA9548_CHANNEL_COUNT
;
218 static void pca954x_realize(DeviceState
*dev
, Error
**errp
)
220 Pca954xState
*s
= PCA954X(dev
);
221 Pca954xClass
*c
= PCA954X_GET_CLASS(s
);
224 /* SMBus modules. Cannot fail. */
225 for (i
= 0; i
< c
->nchans
; i
++) {
226 sysbus_realize(SYS_BUS_DEVICE(&s
->channel
[i
]), &error_abort
);
230 static void pca954x_init(Object
*obj
)
232 Pca954xState
*s
= PCA954X(obj
);
233 Pca954xClass
*c
= PCA954X_GET_CLASS(obj
);
236 /* Only initialize the children we expect. */
237 for (i
= 0; i
< c
->nchans
; i
++) {
238 object_initialize_child(obj
, "channel[*]", &s
->channel
[i
],
239 TYPE_PCA954X_CHANNEL
);
243 static void pca954x_class_init(ObjectClass
*klass
, void *data
)
245 I2CSlaveClass
*sc
= I2C_SLAVE_CLASS(klass
);
246 ResettableClass
*rc
= RESETTABLE_CLASS(klass
);
247 DeviceClass
*dc
= DEVICE_CLASS(klass
);
248 SMBusDeviceClass
*k
= SMBUS_DEVICE_CLASS(klass
);
250 sc
->match_and_add
= pca954x_match
;
252 rc
->phases
.enter
= pca954x_enter_reset
;
254 dc
->desc
= "Pca954x i2c-mux";
255 dc
->realize
= pca954x_realize
;
257 k
->write_data
= pca954x_write_data
;
258 k
->receive_byte
= pca954x_read_byte
;
261 static const TypeInfo pca954x_info
[] = {
263 .name
= TYPE_PCA954X
,
264 .parent
= TYPE_SMBUS_DEVICE
,
265 .instance_size
= sizeof(Pca954xState
),
266 .instance_init
= pca954x_init
,
267 .class_size
= sizeof(Pca954xClass
),
268 .class_init
= pca954x_class_init
,
272 .name
= TYPE_PCA9546
,
273 .parent
= TYPE_PCA954X
,
274 .class_init
= pca9546_class_init
,
277 .name
= TYPE_PCA9548
,
278 .parent
= TYPE_PCA954X
,
279 .class_init
= pca9548_class_init
,
282 .name
= TYPE_PCA954X_CHANNEL
,
283 .parent
= TYPE_SYS_BUS_DEVICE
,
284 .class_init
= pca954x_channel_class_init
,
285 .instance_size
= sizeof(Pca954xChannel
),
286 .instance_init
= pca954x_channel_init
,
290 DEFINE_TYPES(pca954x_info
)