| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: voodoofb.c,v 1.30 2012/01/17 07:48:48 macallan Exp $ */ | | 1 | /* $NetBSD: voodoofb.c,v 1.31 2012/01/17 19:13:22 macallan Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2005, 2006 Michael Lorenz | | 4 | * Copyright (c) 2005, 2006 Michael Lorenz |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -22,51 +22,56 @@ | | | @@ -22,51 +22,56 @@ |
22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
25 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 25 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | | 26 | */ |
27 | | | 27 | |
28 | /* | | 28 | /* |
29 | * A console driver for 3Dfx Voodoo3 graphics boards | | 29 | * A console driver for 3Dfx Voodoo3 graphics boards |
30 | * Thanks to Andreas Drewke (andreas_dr@gmx.de) for his Voodoo3 driver for BeOS | | 30 | * Thanks to Andreas Drewke (andreas_dr@gmx.de) for his Voodoo3 driver for BeOS |
31 | * which I used as reference / documentation | | 31 | * which I used as reference / documentation |
32 | */ | | 32 | */ |
33 | | | 33 | |
34 | #include <sys/cdefs.h> | | 34 | #include <sys/cdefs.h> |
35 | __KERNEL_RCSID(0, "$NetBSD: voodoofb.c,v 1.30 2012/01/17 07:48:48 macallan Exp $"); | | 35 | __KERNEL_RCSID(0, "$NetBSD: voodoofb.c,v 1.31 2012/01/17 19:13:22 macallan Exp $"); |
36 | | | 36 | |
37 | #include <sys/param.h> | | 37 | #include <sys/param.h> |
38 | #include <sys/systm.h> | | 38 | #include <sys/systm.h> |
39 | #include <sys/kernel.h> | | 39 | #include <sys/kernel.h> |
40 | #include <sys/device.h> | | 40 | #include <sys/device.h> |
41 | #include <sys/malloc.h> | | 41 | #include <sys/malloc.h> |
42 | #include <sys/callout.h> | | 42 | #include <sys/callout.h> |
43 | #include <sys/kauth.h> | | 43 | #include <sys/kauth.h> |
44 | | | 44 | |
45 | #include <dev/videomode/videomode.h> | | | |
46 | | | | |
47 | #include <dev/pci/pcivar.h> | | 45 | #include <dev/pci/pcivar.h> |
48 | #include <dev/pci/pcireg.h> | | 46 | #include <dev/pci/pcireg.h> |
49 | #include <dev/pci/pcidevs.h> | | 47 | #include <dev/pci/pcidevs.h> |
50 | #include <dev/pci/pciio.h> | | 48 | #include <dev/pci/pciio.h> |
51 | #include <dev/pci/voodoofbreg.h> | | 49 | #include <dev/pci/voodoofbreg.h> |
52 | | | 50 | |
53 | #include <dev/wscons/wsdisplayvar.h> | | 51 | #include <dev/wscons/wsdisplayvar.h> |
54 | #include <dev/wscons/wsconsio.h> | | 52 | #include <dev/wscons/wsconsio.h> |
55 | #include <dev/wsfont/wsfont.h> | | 53 | #include <dev/wsfont/wsfont.h> |
56 | #include <dev/rasops/rasops.h> | | 54 | #include <dev/rasops/rasops.h> |
57 | #include <dev/wscons/wsdisplay_vconsvar.h> | | 55 | #include <dev/wscons/wsdisplay_vconsvar.h> |
58 | #include <dev/pci/wsdisplay_pci.h> | | 56 | #include <dev/pci/wsdisplay_pci.h> |
59 | | | 57 | |
| | | 58 | #include <dev/i2c/i2cvar.h> |
| | | 59 | #include <dev/i2c/i2c_bitbang.h> |
| | | 60 | #include <dev/i2c/ddcvar.h> |
| | | 61 | #include <dev/videomode/videomode.h> |
| | | 62 | #include <dev/videomode/edidvar.h> |
| | | 63 | #include <dev/videomode/edidreg.h> |
| | | 64 | |
60 | #include "opt_wsemul.h" | | 65 | #include "opt_wsemul.h" |
61 | | | 66 | |
62 | struct voodoofb_softc { | | 67 | struct voodoofb_softc { |
63 | device_t sc_dev; | | 68 | device_t sc_dev; |
64 | pci_chipset_tag_t sc_pc; | | 69 | pci_chipset_tag_t sc_pc; |
65 | pcitag_t sc_pcitag; | | 70 | pcitag_t sc_pcitag; |
66 | struct pci_attach_args sc_pa; | | 71 | struct pci_attach_args sc_pa; |
67 | | | 72 | |
68 | bus_space_tag_t sc_memt; | | 73 | bus_space_tag_t sc_memt; |
69 | bus_space_tag_t sc_iot; | | 74 | bus_space_tag_t sc_iot; |
70 | bus_space_handle_t sc_memh; | | 75 | bus_space_handle_t sc_memh; |
71 | | | 76 | |
72 | bus_space_tag_t sc_regt; | | 77 | bus_space_tag_t sc_regt; |
| @@ -77,26 +82,32 @@ struct voodoofb_softc { | | | @@ -77,26 +82,32 @@ struct voodoofb_softc { |
77 | bus_space_handle_t sc_ioregh; | | 82 | bus_space_handle_t sc_ioregh; |
78 | bus_addr_t sc_regs, sc_fb, sc_ioreg; | | 83 | bus_addr_t sc_regs, sc_fb, sc_ioreg; |
79 | bus_size_t sc_regsize, sc_fbsize, sc_ioregsize; | | 84 | bus_size_t sc_regsize, sc_fbsize, sc_ioregsize; |
80 | | | 85 | |
81 | void *sc_ih; | | 86 | void *sc_ih; |
82 | | | 87 | |
83 | size_t memsize; | | 88 | size_t memsize; |
84 | int memtype; | | 89 | int memtype; |
85 | | | 90 | |
86 | int bits_per_pixel; | | 91 | int bits_per_pixel; |
87 | int width, height, linebytes; | | 92 | int width, height, linebytes; |
88 | const struct videomode *sc_videomode; | | 93 | const struct videomode *sc_videomode; |
89 | | | 94 | |
| | | 95 | /* i2c stuff */ |
| | | 96 | struct i2c_controller sc_i2c; |
| | | 97 | uint8_t sc_edid_data[128]; |
| | | 98 | struct edid_info sc_edid_info; |
| | | 99 | uint32_t sc_i2creg; |
| | | 100 | |
90 | int sc_mode; | | 101 | int sc_mode; |
91 | uint32_t sc_bg; | | 102 | uint32_t sc_bg; |
92 | | | 103 | |
93 | u_char sc_cmap_red[256]; | | 104 | u_char sc_cmap_red[256]; |
94 | u_char sc_cmap_green[256]; | | 105 | u_char sc_cmap_green[256]; |
95 | u_char sc_cmap_blue[256]; | | 106 | u_char sc_cmap_blue[256]; |
96 | int sc_dacw; | | 107 | int sc_dacw; |
97 | | | 108 | |
98 | struct vcons_data vd; | | 109 | struct vcons_data vd; |
99 | }; | | 110 | }; |
100 | | | 111 | |
101 | struct voodoo_regs { | | 112 | struct voodoo_regs { |
102 | uint8_t vr_crtc[31]; | | 113 | uint8_t vr_crtc[31]; |
| @@ -188,26 +199,54 @@ static void voodoofb_init_screen(void *, | | | @@ -188,26 +199,54 @@ static void voodoofb_init_screen(void *, |
188 | | | 199 | |
189 | | | 200 | |
190 | struct wsdisplay_accessops voodoofb_accessops = { | | 201 | struct wsdisplay_accessops voodoofb_accessops = { |
191 | voodoofb_ioctl, | | 202 | voodoofb_ioctl, |
192 | voodoofb_mmap, | | 203 | voodoofb_mmap, |
193 | NULL, | | 204 | NULL, |
194 | NULL, | | 205 | NULL, |
195 | NULL, | | 206 | NULL, |
196 | NULL, /* load_font */ | | 207 | NULL, /* load_font */ |
197 | NULL, /* polls */ | | 208 | NULL, /* polls */ |
198 | NULL, /* scroll */ | | 209 | NULL, /* scroll */ |
199 | }; | | 210 | }; |
200 | | | 211 | |
| | | 212 | /* I2C glue */ |
| | | 213 | static int voodoofb_i2c_acquire_bus(void *, int); |
| | | 214 | static void voodoofb_i2c_release_bus(void *, int); |
| | | 215 | static int voodoofb_i2c_send_start(void *, int); |
| | | 216 | static int voodoofb_i2c_send_stop(void *, int); |
| | | 217 | static int voodoofb_i2c_initiate_xfer(void *, i2c_addr_t, int); |
| | | 218 | static int voodoofb_i2c_read_byte(void *, uint8_t *, int); |
| | | 219 | static int voodoofb_i2c_write_byte(void *, uint8_t, int); |
| | | 220 | |
| | | 221 | /* I2C bitbang glue */ |
| | | 222 | static void voodoofb_i2cbb_set_bits(void *, uint32_t); |
| | | 223 | static void voodoofb_i2cbb_set_dir(void *, uint32_t); |
| | | 224 | static uint32_t voodoofb_i2cbb_read(void *); |
| | | 225 | |
| | | 226 | static void voodoofb_setup_i2c(struct voodoofb_softc *); |
| | | 227 | |
| | | 228 | static const struct i2c_bitbang_ops voodoofb_i2cbb_ops = { |
| | | 229 | voodoofb_i2cbb_set_bits, |
| | | 230 | voodoofb_i2cbb_set_dir, |
| | | 231 | voodoofb_i2cbb_read, |
| | | 232 | { |
| | | 233 | VSP_SDA0_IN, |
| | | 234 | VSP_SCL0_IN, |
| | | 235 | 0, |
| | | 236 | 0 |
| | | 237 | } |
| | | 238 | }; |
| | | 239 | |
201 | /* | | 240 | /* |
202 | * Inline functions for getting access to register aperture. | | 241 | * Inline functions for getting access to register aperture. |
203 | */ | | 242 | */ |
204 | static inline void | | 243 | static inline void |
205 | voodoo3_write32(struct voodoofb_softc *sc, uint32_t reg, uint32_t val) | | 244 | voodoo3_write32(struct voodoofb_softc *sc, uint32_t reg, uint32_t val) |
206 | { | | 245 | { |
207 | bus_space_write_4(sc->sc_regt, sc->sc_regh, reg, val); | | 246 | bus_space_write_4(sc->sc_regt, sc->sc_regh, reg, val); |
208 | } | | 247 | } |
209 | | | 248 | |
210 | static inline uint32_t | | 249 | static inline uint32_t |
211 | voodoo3_read32(struct voodoofb_softc *sc, uint32_t reg) | | 250 | voodoo3_read32(struct voodoofb_softc *sc, uint32_t reg) |
212 | { | | 251 | { |
213 | return bus_space_read_4(sc->sc_regt, sc->sc_regh, reg); | | 252 | return bus_space_read_4(sc->sc_regt, sc->sc_regh, reg); |
| @@ -359,29 +398,35 @@ voodoofb_attach(device_t parent, device_ | | | @@ -359,29 +398,35 @@ voodoofb_attach(device_t parent, device_ |
359 | } | | 398 | } |
360 | linebytes = width; /* XXX */ | | 399 | linebytes = width; /* XXX */ |
361 | | | 400 | |
362 | if (width == -1 || height == -1) | | 401 | if (width == -1 || height == -1) |
363 | return; | | 402 | return; |
364 | | | 403 | |
365 | sc->width = width; | | 404 | sc->width = width; |
366 | sc->height = height; | | 405 | sc->height = height; |
367 | sc->bits_per_pixel = depth; | | 406 | sc->bits_per_pixel = depth; |
368 | sc->linebytes = linebytes; | | 407 | sc->linebytes = linebytes; |
369 | printf("%s: initial resolution %dx%d, %d bit\n", device_xname(self), | | 408 | printf("%s: initial resolution %dx%d, %d bit\n", device_xname(self), |
370 | sc->width, sc->height, sc->bits_per_pixel); | | 409 | sc->width, sc->height, sc->bits_per_pixel); |
371 | | | 410 | |
| | | 411 | sc->sc_videomode = NULL; |
| | | 412 | voodoofb_setup_i2c(sc); |
| | | 413 | |
372 | /* XXX this should at least be configurable via kernel config */ | | 414 | /* XXX this should at least be configurable via kernel config */ |
373 | if ((sc->sc_videomode = pick_mode_by_ref(1024, 768, 60)) != NULL) | | 415 | if (sc->sc_videomode == NULL) { |
374 | voodoofb_set_videomode(sc, sc->sc_videomode); | | 416 | sc->sc_videomode = pick_mode_by_ref(width, height, 60); |
| | | 417 | } |
| | | 418 | |
| | | 419 | voodoofb_set_videomode(sc, sc->sc_videomode); |
375 | | | 420 | |
376 | vcons_init(&sc->vd, sc, &voodoofb_defaultscreen, &voodoofb_accessops); | | 421 | vcons_init(&sc->vd, sc, &voodoofb_defaultscreen, &voodoofb_accessops); |
377 | sc->vd.init_screen = voodoofb_init_screen; | | 422 | sc->vd.init_screen = voodoofb_init_screen; |
378 | | | 423 | |
379 | console = voodoofb_is_console(sc); | | 424 | console = voodoofb_is_console(sc); |
380 | | | 425 | |
381 | ri = &voodoofb_console_screen.scr_ri; | | 426 | ri = &voodoofb_console_screen.scr_ri; |
382 | if (console) { | | 427 | if (console) { |
383 | vcons_init_screen(&sc->vd, &voodoofb_console_screen, 1, | | 428 | vcons_init_screen(&sc->vd, &voodoofb_console_screen, 1, |
384 | &defattr); | | 429 | &defattr); |
385 | voodoofb_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; | | 430 | voodoofb_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; |
386 | | | 431 | |
387 | voodoofb_defaultscreen.textops = &ri->ri_ops; | | 432 | voodoofb_defaultscreen.textops = &ri->ri_ops; |
| @@ -1402,13 +1447,150 @@ voodoofb_init(struct voodoofb_softc *sc) | | | @@ -1402,13 +1447,150 @@ voodoofb_init(struct voodoofb_softc *sc) |
1402 | | | 1447 | |
1403 | voodoo3_make_room(sc, 8); | | 1448 | voodoo3_make_room(sc, 8); |
1404 | voodoo3_write32(sc, SRCBASE, 0); | | 1449 | voodoo3_write32(sc, SRCBASE, 0); |
1405 | voodoo3_write32(sc, DSTBASE, 0); | | 1450 | voodoo3_write32(sc, DSTBASE, 0); |
1406 | voodoo3_write32(sc, COMMANDEXTRA_2D, 0); | | 1451 | voodoo3_write32(sc, COMMANDEXTRA_2D, 0); |
1407 | voodoo3_write32(sc, CLIP0MIN, 0); | | 1452 | voodoo3_write32(sc, CLIP0MIN, 0); |
1408 | voodoo3_write32(sc, CLIP0MAX, 0x1fff1fff); | | 1453 | voodoo3_write32(sc, CLIP0MAX, 0x1fff1fff); |
1409 | voodoo3_write32(sc, CLIP1MIN, 0); | | 1454 | voodoo3_write32(sc, CLIP1MIN, 0); |
1410 | voodoo3_write32(sc, CLIP1MAX, 0x1fff1fff); | | 1455 | voodoo3_write32(sc, CLIP1MAX, 0x1fff1fff); |
1411 | voodoo3_write32(sc, SRCXY, 0); | | 1456 | voodoo3_write32(sc, SRCXY, 0); |
1412 | | | 1457 | |
1413 | voodoofb_wait_idle(sc); | | 1458 | voodoofb_wait_idle(sc); |
1414 | } | | 1459 | } |
| | | 1460 | |
| | | 1461 | static void |
| | | 1462 | voodoofb_setup_i2c(struct voodoofb_softc *sc) |
| | | 1463 | { |
| | | 1464 | int i; |
| | | 1465 | |
| | | 1466 | /* Fill in the i2c tag */ |
| | | 1467 | sc->sc_i2c.ic_cookie = sc; |
| | | 1468 | sc->sc_i2c.ic_acquire_bus = voodoofb_i2c_acquire_bus; |
| | | 1469 | sc->sc_i2c.ic_release_bus = voodoofb_i2c_release_bus; |
| | | 1470 | sc->sc_i2c.ic_send_start = voodoofb_i2c_send_start; |
| | | 1471 | sc->sc_i2c.ic_send_stop = voodoofb_i2c_send_stop; |
| | | 1472 | sc->sc_i2c.ic_initiate_xfer = voodoofb_i2c_initiate_xfer; |
| | | 1473 | sc->sc_i2c.ic_read_byte = voodoofb_i2c_read_byte; |
| | | 1474 | sc->sc_i2c.ic_write_byte = voodoofb_i2c_write_byte; |
| | | 1475 | sc->sc_i2c.ic_exec = NULL; |
| | | 1476 | |
| | | 1477 | sc->sc_i2creg = voodoo3_read32(sc, VIDSERPARPORT); |
| | | 1478 | #ifdef VOODOOFB_DEBUG |
| | | 1479 | printf("data: %08x\n", sc->sc_i2creg); |
| | | 1480 | #endif |
| | | 1481 | sc->sc_i2creg |= VSP_ENABLE_IIC0; |
| | | 1482 | sc->sc_i2creg &= ~(VSP_SDA0_OUT | VSP_SCL0_OUT); |
| | | 1483 | voodoo3_write32(sc, VIDSERPARPORT, sc->sc_i2creg); |
| | | 1484 | |
| | | 1485 | /* zero out the EDID buffer */ |
| | | 1486 | memset(sc->sc_edid_data, 0, 128); |
| | | 1487 | |
| | | 1488 | /* Some monitors don't respond first time */ |
| | | 1489 | i = 0; |
| | | 1490 | while (sc->sc_edid_data[1] == 0 && i++ < 3) |
| | | 1491 | ddc_read_edid(&sc->sc_i2c, sc->sc_edid_data, 128); |
| | | 1492 | if (i < 3) { |
| | | 1493 | if (edid_parse(sc->sc_edid_data, &sc->sc_edid_info) != -1) { |
| | | 1494 | #ifdef VOODOOFB_DEBUG |
| | | 1495 | edid_print(&sc->sc_edid_info); |
| | | 1496 | #endif |
| | | 1497 | /* |
| | | 1498 | * Now pick a mode. |
| | | 1499 | * How do we know our max. pixel clock? |
| | | 1500 | * All Voodoo3 should support at least 250MHz. |
| | | 1501 | * All Voodoo3 I've seen so far have at least 8MB |
| | | 1502 | * which we're not going to exhaust either in 8bit. |
| | | 1503 | */ |
| | | 1504 | if ((sc->sc_edid_info.edid_preferred_mode != NULL)) { |
| | | 1505 | sc->sc_videomode = |
| | | 1506 | sc->sc_edid_info.edid_preferred_mode; |
| | | 1507 | } else { |
| | | 1508 | int n; |
| | | 1509 | struct videomode *m = sc->sc_edid_info.edid_modes; |
| | | 1510 | |
| | | 1511 | sort_modes(sc->sc_edid_info.edid_modes, |
| | | 1512 | &sc->sc_edid_info.edid_preferred_mode, |
| | | 1513 | sc->sc_edid_info.edid_nmodes); |
| | | 1514 | while ((sc->sc_videomode == NULL) && |
| | | 1515 | (n < sc->sc_edid_info.edid_nmodes)) { |
| | | 1516 | if (m[n].dot_clock <= 250000) { |
| | | 1517 | sc->sc_videomode = &m[n]; |
| | | 1518 | } |
| | | 1519 | } |
| | | 1520 | } |
| | | 1521 | } |
| | | 1522 | } |
| | | 1523 | } |
| | | 1524 | |
| | | 1525 | /* I2C bitbanging */ |
| | | 1526 | static void voodoofb_i2cbb_set_bits(void *cookie, uint32_t bits) |
| | | 1527 | { |
| | | 1528 | struct voodoofb_softc *sc = cookie; |
| | | 1529 | uint32_t out; |
| | | 1530 | |
| | | 1531 | out = bits >> 2; /* bitmasks match the IN bits */ |
| | | 1532 | |
| | | 1533 | voodoo3_write32(sc, VIDSERPARPORT, sc->sc_i2creg | out); |
| | | 1534 | } |
| | | 1535 | |
| | | 1536 | static void voodoofb_i2cbb_set_dir(void *cookie, uint32_t dir) |
| | | 1537 | { |
| | | 1538 | /* Nothing to do */ |
| | | 1539 | } |
| | | 1540 | |
| | | 1541 | static uint32_t voodoofb_i2cbb_read(void *cookie) |
| | | 1542 | { |
| | | 1543 | struct voodoofb_softc *sc = cookie; |
| | | 1544 | uint32_t bits; |
| | | 1545 | |
| | | 1546 | bits = voodoo3_read32(sc, VIDSERPARPORT); |
| | | 1547 | |
| | | 1548 | return bits; |
| | | 1549 | } |
| | | 1550 | |
| | | 1551 | /* higher level I2C stuff */ |
| | | 1552 | static int |
| | | 1553 | voodoofb_i2c_acquire_bus(void *cookie, int flags) |
| | | 1554 | { |
| | | 1555 | /* private bus */ |
| | | 1556 | return (0); |
| | | 1557 | } |
| | | 1558 | |
| | | 1559 | static void |
| | | 1560 | voodoofb_i2c_release_bus(void *cookie, int flags) |
| | | 1561 | { |
| | | 1562 | /* private bus */ |
| | | 1563 | } |
| | | 1564 | |
| | | 1565 | static int |
| | | 1566 | voodoofb_i2c_send_start(void *cookie, int flags) |
| | | 1567 | { |
| | | 1568 | return (i2c_bitbang_send_start(cookie, flags, &voodoofb_i2cbb_ops)); |
| | | 1569 | } |
| | | 1570 | |
| | | 1571 | static int |
| | | 1572 | voodoofb_i2c_send_stop(void *cookie, int flags) |
| | | 1573 | { |
| | | 1574 | |
| | | 1575 | return (i2c_bitbang_send_stop(cookie, flags, &voodoofb_i2cbb_ops)); |
| | | 1576 | } |
| | | 1577 | |
| | | 1578 | static int |
| | | 1579 | voodoofb_i2c_initiate_xfer(void *cookie, i2c_addr_t addr, int flags) |
| | | 1580 | { |
| | | 1581 | |
| | | 1582 | return (i2c_bitbang_initiate_xfer(cookie, addr, flags, |
| | | 1583 | &voodoofb_i2cbb_ops)); |
| | | 1584 | } |
| | | 1585 | |
| | | 1586 | static int |
| | | 1587 | voodoofb_i2c_read_byte(void *cookie, uint8_t *valp, int flags) |
| | | 1588 | { |
| | | 1589 | return (i2c_bitbang_read_byte(cookie, valp, flags, &voodoofb_i2cbb_ops)); |
| | | 1590 | } |
| | | 1591 | |
| | | 1592 | static int |
| | | 1593 | voodoofb_i2c_write_byte(void *cookie, uint8_t val, int flags) |
| | | 1594 | { |
| | | 1595 | return (i2c_bitbang_write_byte(cookie, val, flags, &voodoofb_i2cbb_ops)); |
| | | 1596 | } |