Lines Matching +full:bcm2835 +full:- +full:i2c
6 * SPDX-License-Identifier: MIT
29 #include "hw/i2c/bcm2835_i2c.h"
37 if (s->c & BCM2835_I2C_C_INTR && s->s & BCM2835_I2C_S_RXR) { in bcm2835_i2c_update_interrupt()
42 if (s->c & BCM2835_I2C_C_INTT && s->s & BCM2835_I2C_S_TXW) { in bcm2835_i2c_update_interrupt()
47 if (s->c & BCM2835_I2C_C_INTD && s->s & BCM2835_I2C_S_DONE) { in bcm2835_i2c_update_interrupt()
50 qemu_set_irq(s->irq, do_interrupt); in bcm2835_i2c_update_interrupt()
55 int direction = s->c & BCM2835_I2C_C_READ; in bcm2835_i2c_begin_transfer()
56 if (i2c_start_transfer(s->bus, s->a, direction)) { in bcm2835_i2c_begin_transfer()
57 s->s |= BCM2835_I2C_S_ERR; in bcm2835_i2c_begin_transfer()
59 s->s |= BCM2835_I2C_S_TA; in bcm2835_i2c_begin_transfer()
62 s->s |= BCM2835_I2C_S_RXR | BCM2835_I2C_S_RXD; in bcm2835_i2c_begin_transfer()
64 s->s |= BCM2835_I2C_S_TXW; in bcm2835_i2c_begin_transfer()
73 * https://github.com/torvalds/linux/blob/v6.7/drivers/i2c/busses/i2c-bcm2835.c#L223-L261 in bcm2835_i2c_finish_transfer()
80 i2c_end_transfer(s->bus); in bcm2835_i2c_finish_transfer()
81 s->s |= BCM2835_I2C_S_DONE; in bcm2835_i2c_finish_transfer()
84 s->s &= ~(BCM2835_I2C_S_TA | BCM2835_I2C_S_RXR | in bcm2835_i2c_finish_transfer()
95 readval = s->c; in bcm2835_i2c_read()
98 readval = s->s; in bcm2835_i2c_read()
101 readval = s->dlen; in bcm2835_i2c_read()
104 readval = s->a; in bcm2835_i2c_read()
107 /* We receive I2C messages directly instead of using FIFOs */ in bcm2835_i2c_read()
108 if (s->s & BCM2835_I2C_S_TA) { in bcm2835_i2c_read()
109 readval = i2c_recv(s->bus); in bcm2835_i2c_read()
110 s->dlen -= 1; in bcm2835_i2c_read()
112 if (s->dlen == 0) { in bcm2835_i2c_read()
119 readval = s->div; in bcm2835_i2c_read()
122 readval = s->del; in bcm2835_i2c_read()
125 readval = s->clkt; in bcm2835_i2c_read()
143 /* ST is a one-shot operation; it must read back as 0 */ in bcm2835_i2c_write()
144 s->c = writeval & ~BCM2835_I2C_C_ST; in bcm2835_i2c_write()
151 * Required for zero length i2c quick messages to work. in bcm2835_i2c_write()
153 if (s->dlen == 0) { in bcm2835_i2c_write()
161 if (writeval & BCM2835_I2C_S_DONE && s->s & BCM2835_I2C_S_DONE) { in bcm2835_i2c_write()
163 s->dlen = s->last_dlen; in bcm2835_i2c_write()
167 s->s &= ~(writeval & (BCM2835_I2C_S_DONE | in bcm2835_i2c_write()
171 s->dlen = writeval; in bcm2835_i2c_write()
172 s->last_dlen = writeval; in bcm2835_i2c_write()
175 s->a = writeval; in bcm2835_i2c_write()
178 /* We send I2C messages directly instead of using FIFOs */ in bcm2835_i2c_write()
179 if (s->s & BCM2835_I2C_S_TA) { in bcm2835_i2c_write()
180 if (s->s & BCM2835_I2C_S_TXD) { in bcm2835_i2c_write()
181 if (!i2c_send(s->bus, writeval & 0xff)) { in bcm2835_i2c_write()
182 s->dlen -= 1; in bcm2835_i2c_write()
184 s->s |= BCM2835_I2C_S_ERR; in bcm2835_i2c_write()
188 if (s->dlen == 0) { in bcm2835_i2c_write()
195 s->div = writeval; in bcm2835_i2c_write()
198 s->del = writeval; in bcm2835_i2c_write()
201 s->clkt = writeval; in bcm2835_i2c_write()
222 s->bus = i2c_init_bus(dev, NULL); in bcm2835_i2c_realize()
224 memory_region_init_io(&s->iomem, OBJECT(dev), &bcm2835_i2c_ops, s, in bcm2835_i2c_realize()
226 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem); in bcm2835_i2c_realize()
227 sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq); in bcm2835_i2c_realize()
234 /* Reset values according to BCM2835 Peripheral Documentation */ in bcm2835_i2c_reset()
235 s->c = 0x0; in bcm2835_i2c_reset()
236 s->s = BCM2835_I2C_S_TXD | BCM2835_I2C_S_TXE; in bcm2835_i2c_reset()
237 s->dlen = 0x0; in bcm2835_i2c_reset()
238 s->a = 0x0; in bcm2835_i2c_reset()
239 s->div = 0x5dc; in bcm2835_i2c_reset()
240 s->del = 0x00300030; in bcm2835_i2c_reset()
241 s->clkt = 0x40; in bcm2835_i2c_reset()
266 dc->realize = bcm2835_i2c_realize; in bcm2835_i2c_class_init()
267 dc->vmsd = &vmstate_bcm2835_i2c; in bcm2835_i2c_class_init()