1448897d3SAndriy Gapon /*- 2448897d3SAndriy Gapon * Copyright (c) 2016 The FreeBSD Project. 3448897d3SAndriy Gapon * All rights reserved. 4448897d3SAndriy Gapon * 5448897d3SAndriy Gapon * Redistribution and use in source and binary forms, with or without 6448897d3SAndriy Gapon * modification, are permitted provided that the following conditions 7448897d3SAndriy Gapon * are met: 8448897d3SAndriy Gapon * 9448897d3SAndriy Gapon * 1. Redistributions of source code must retain the above copyright 10448897d3SAndriy Gapon * notice, this list of conditions and the following disclaimer. 11448897d3SAndriy Gapon * 2. Redistributions in binary form must reproduce the above copyright 12448897d3SAndriy Gapon * notice, this list of conditions and the following disclaimer in 13448897d3SAndriy Gapon * the documentation and/or other materials provided with the 14448897d3SAndriy Gapon * distribution. 15448897d3SAndriy Gapon * 16448897d3SAndriy Gapon * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17448897d3SAndriy Gapon * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18448897d3SAndriy Gapon * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 19448897d3SAndriy Gapon * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 20448897d3SAndriy Gapon * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 21448897d3SAndriy Gapon * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 22448897d3SAndriy Gapon * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23448897d3SAndriy Gapon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 24448897d3SAndriy Gapon * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25448897d3SAndriy Gapon * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 26448897d3SAndriy Gapon * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27448897d3SAndriy Gapon * SUCH DAMAGE. 28448897d3SAndriy Gapon */ 29448897d3SAndriy Gapon 30448897d3SAndriy Gapon #include <sys/param.h> 31448897d3SAndriy Gapon #include <sys/systm.h> 32448897d3SAndriy Gapon #include <sys/kernel.h> 33448897d3SAndriy Gapon #include <sys/module.h> 34448897d3SAndriy Gapon #include <sys/errno.h> 35448897d3SAndriy Gapon #include <sys/bus.h> 36448897d3SAndriy Gapon 37448897d3SAndriy Gapon #include <dev/pci/pcivar.h> 38448897d3SAndriy Gapon #include <dev/pci/pcireg.h> 39448897d3SAndriy Gapon #include <dev/iicbus/iicbus.h> 40448897d3SAndriy Gapon #include <dev/iicbus/iiconf.h> 41448897d3SAndriy Gapon 42448897d3SAndriy Gapon /* 43448897d3SAndriy Gapon * Driver that attaches I2C devices. 44448897d3SAndriy Gapon */ 45448897d3SAndriy Gapon static struct { 46448897d3SAndriy Gapon uint32_t pci_id; 47448897d3SAndriy Gapon const char *name; 48448897d3SAndriy Gapon uint8_t addr; 49448897d3SAndriy Gapon } slaves[] = { 50448897d3SAndriy Gapon { 0x9c628086, "isl", 0x88 }, 51448897d3SAndriy Gapon { 0x9c618086, "cyapa", 0xce }, 52448897d3SAndriy Gapon }; 53448897d3SAndriy Gapon 54448897d3SAndriy Gapon static void 55448897d3SAndriy Gapon chromebook_i2c_identify(driver_t *driver, device_t bus) 56448897d3SAndriy Gapon { 57448897d3SAndriy Gapon device_t controller; 58448897d3SAndriy Gapon device_t child; 59448897d3SAndriy Gapon int i; 60448897d3SAndriy Gapon 61448897d3SAndriy Gapon /* 62448897d3SAndriy Gapon * A stopgap approach to preserve the status quo. 63448897d3SAndriy Gapon * A more intelligent approach is required to correctly 64448897d3SAndriy Gapon * identify a machine model and hardware available on it. 65448897d3SAndriy Gapon * For instance, DMI could be used. 66448897d3SAndriy Gapon * See http://lxr.free-electrons.com/source/drivers/platform/chrome/chromeos_laptop.c 67448897d3SAndriy Gapon */ 68448897d3SAndriy Gapon controller = device_get_parent(bus); 69984ed3e4SVladimir Kondratyev if (strcmp(device_get_name(controller), "ig4iic") != 0) 70448897d3SAndriy Gapon return; 71448897d3SAndriy Gapon 72448897d3SAndriy Gapon for (i = 0; i < nitems(slaves); i++) { 73448897d3SAndriy Gapon if (device_find_child(bus, slaves[i].name, -1) != NULL) 74448897d3SAndriy Gapon continue; 75448897d3SAndriy Gapon if (slaves[i].pci_id != pci_get_devid(controller)) 76448897d3SAndriy Gapon continue; 77*a05a6804SWarner Losh child = BUS_ADD_CHILD(bus, 0, slaves[i].name, DEVICE_UNIT_ANY); 78448897d3SAndriy Gapon if (child != NULL) 79448897d3SAndriy Gapon iicbus_set_addr(child, slaves[i].addr); 80448897d3SAndriy Gapon } 81448897d3SAndriy Gapon } 82448897d3SAndriy Gapon 83448897d3SAndriy Gapon static device_method_t chromebook_i2c_methods[] = { 84448897d3SAndriy Gapon DEVMETHOD(device_identify, chromebook_i2c_identify), 85448897d3SAndriy Gapon { 0, 0 } 86448897d3SAndriy Gapon }; 87448897d3SAndriy Gapon 88448897d3SAndriy Gapon static driver_t chromebook_i2c_driver = { 89448897d3SAndriy Gapon "chromebook_i2c", 90448897d3SAndriy Gapon chromebook_i2c_methods, 91448897d3SAndriy Gapon 0 /* no softc */ 92448897d3SAndriy Gapon }; 93448897d3SAndriy Gapon 94950143ecSJohn Baldwin DRIVER_MODULE(chromebook_i2c, iicbus, chromebook_i2c_driver, 0, 0); 95448897d3SAndriy Gapon MODULE_VERSION(chromebook_i2c, 1); 96448897d3SAndriy Gapon 97