The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/powermng/viapm/viapm.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2001 Alcove - Nicolas Souchu
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  *
   26  * $FreeBSD: src/sys/pci/viapm.c,v 1.10.2.3 2006/09/22 19:19:16 jhb Exp $
   27  *
   28  */
   29 #include <sys/param.h>
   30 #include <sys/kernel.h>
   31 #include <sys/systm.h>
   32 #include <sys/module.h>
   33 #include <sys/bus.h>
   34 #include <sys/uio.h>
   35 #include <sys/rman.h>
   36 
   37 #include <machine/clock.h>              /* for DELAY */
   38 
   39 #include <bus/pci/pcivar.h>
   40 #include <bus/pci/pcireg.h>
   41 
   42 #include <bus/iicbus/iiconf.h>
   43 
   44 #include <bus/smbus/smbconf.h>
   45 
   46 #include "iicbb_if.h"
   47 #include "smbus_if.h"
   48 
   49 #define VIAPM_DEBUG(x)  if (viapm_debug) (x)
   50 
   51 #ifdef DEBUG
   52 static int viapm_debug = 1;
   53 #else
   54 static int viapm_debug = 0;
   55 #endif
   56 
   57 #define VIA_586B_PMU_ID         0x30401106
   58 #define VIA_596A_PMU_ID         0x30501106
   59 #define VIA_596B_PMU_ID         0x30511106
   60 #define VIA_686A_PMU_ID         0x30571106
   61 #define VIA_8233_PMU_ID         0x30741106
   62 #define VIA_8233A_PMU_ID        0x31471106
   63 #define VIA_8235_PMU_ID         0x31771106
   64 
   65 #define VIAPM_INB(port) \
   66         ((u_char)bus_space_read_1(viapm->st, viapm->sh, port))
   67 #define VIAPM_OUTB(port,val) \
   68         (bus_space_write_1(viapm->st, viapm->sh, port, (u_char)(val)))
   69 
   70 #define VIAPM_TYP_UNKNOWN       0
   71 #define VIAPM_TYP_586B_3040E    1
   72 #define VIAPM_TYP_586B_3040F    2
   73 #define VIAPM_TYP_596B          3
   74 #define VIAPM_TYP_686A          4
   75 #define VIAPM_TYP_8233          5
   76 
   77 struct viapm_softc {
   78         int type;
   79         u_int32_t base;
   80         bus_space_tag_t st;
   81         bus_space_handle_t sh;
   82         int iorid;
   83         int irqrid;
   84         struct resource *iores;
   85         struct resource *irqres;
   86         void *irqih;
   87 
   88         device_t iicbb;
   89         device_t smbus;
   90 };
   91 
   92 static devclass_t viapm_devclass;
   93 static devclass_t viapropm_devclass;
   94 
   95 /*
   96  * VT82C586B definitions
   97  */
   98 
   99 #define VIAPM_586B_REVID        0x08
  100 
  101 #define VIAPM_586B_3040E_BASE   0x20
  102 #define VIAPM_586B_3040E_ACTIV  0x4             /* 16 bits */
  103 
  104 #define VIAPM_586B_3040F_BASE   0x48
  105 #define VIAPM_586B_3040F_ACTIV  0x41            /* 8 bits */
  106 
  107 #define VIAPM_586B_OEM_REV_E    0x00
  108 #define VIAPM_586B_OEM_REV_F    0x01
  109 #define VIAPM_586B_PROD_REV_A   0x10
  110 
  111 #define VIAPM_586B_BA_MASK      0x0000ff00
  112 
  113 #define GPIO_DIR        0x40
  114 #define GPIO_VAL        0x42
  115 #define EXTSMI_VAL      0x44
  116 
  117 #define VIAPM_SCL       0x02                    /* GPIO1_VAL */
  118 #define VIAPM_SDA       0x04                    /* GPIO2_VAL */
  119 
  120 /*
  121  * VIAPRO common definitions
  122  */
  123 
  124 #define VIAPM_PRO_BA_MASK       0x0000fff0
  125 #define VIAPM_PRO_SMBCTRL       0xd2
  126 #define VIAPM_PRO_REVID         0xd6
  127 
  128 /*
  129  * VT82C686A definitions
  130  */
  131 
  132 #define VIAPM_PRO_BASE          0x90
  133 
  134 #define SMBHST                  0x0
  135 #define SMBHSL                  0x1
  136 #define SMBHCTRL                0x2
  137 #define SMBHCMD                 0x3
  138 #define SMBHADDR                0x4
  139 #define SMBHDATA0               0x5
  140 #define SMBHDATA1               0x6
  141 #define SMBHBLOCK               0x7
  142 
  143 #define SMBSST                  0x1
  144 #define SMBSCTRL                0x8
  145 #define SMBSSDWCMD              0x9
  146 #define SMBSEVENT               0xa
  147 #define SMBSDATA                0xc
  148 
  149 #define SMBHST_RESERVED         0xef    /* reserved bits */
  150 #define SMBHST_FAILED           0x10    /* failed bus transaction */
  151 #define SMBHST_COLLID           0x08    /* bus collision */
  152 #define SMBHST_ERROR            0x04    /* device error */
  153 #define SMBHST_INTR             0x02    /* command completed */
  154 #define SMBHST_BUSY             0x01    /* host busy */
  155 
  156 #define SMBHCTRL_START          0x40    /* start command */
  157 #define SMBHCTRL_PROTO          0x1c    /* command protocol mask */
  158 #define SMBHCTRL_QUICK          0x00
  159 #define SMBHCTRL_SENDRECV       0x04
  160 #define SMBHCTRL_BYTE           0x08
  161 #define SMBHCTRL_WORD           0x0c
  162 #define SMBHCTRL_BLOCK          0x14
  163 #define SMBHCTRL_KILL           0x02    /* stop the current transaction */
  164 #define SMBHCTRL_ENABLE         0x01    /* enable interrupts */
  165 
  166 #define SMBSCTRL_ENABLE         0x01    /* enable slave */
  167 
  168 
  169 /*
  170  * VIA8233 definitions
  171  */
  172 
  173 #define VIAPM_8233_BASE         0xD0
  174 
  175 static int
  176 viapm_586b_probe(device_t dev)
  177 {
  178         struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
  179         u_int32_t l;
  180         u_int16_t s;
  181         u_int8_t c;
  182 
  183         switch (pci_get_devid(dev)) {
  184         case VIA_586B_PMU_ID:
  185 
  186                 bzero(viapm, sizeof(struct viapm_softc));
  187 
  188                 l = pci_read_config(dev, VIAPM_586B_REVID, 1);
  189                 switch (l) {
  190                 case VIAPM_586B_OEM_REV_E:
  191                         viapm->type = VIAPM_TYP_586B_3040E;
  192                         viapm->iorid = VIAPM_586B_3040E_BASE;
  193 
  194                         /* Activate IO block access */
  195                         s = pci_read_config(dev, VIAPM_586B_3040E_ACTIV, 2);
  196                         pci_write_config(dev, VIAPM_586B_3040E_ACTIV, s | 0x1, 2);
  197                         break;
  198 
  199                 case VIAPM_586B_OEM_REV_F:
  200                 case VIAPM_586B_PROD_REV_A:
  201                 default:
  202                         viapm->type = VIAPM_TYP_586B_3040F;
  203                         viapm->iorid = VIAPM_586B_3040F_BASE;
  204 
  205                         /* Activate IO block access */
  206                         c = pci_read_config(dev, VIAPM_586B_3040F_ACTIV, 1);
  207                         pci_write_config(dev, VIAPM_586B_3040F_ACTIV, c | 0x80, 1);
  208                         break;
  209                 }
  210 
  211                 viapm->base = pci_read_config(dev, viapm->iorid, 4) &
  212                                 VIAPM_586B_BA_MASK;
  213 
  214                 /*
  215                  * We have to set the I/O resources by hand because it is
  216                  * described outside the viapmope of the traditional maps
  217                  */
  218                 if (bus_set_resource(dev, SYS_RES_IOPORT, viapm->iorid,
  219                     viapm->base, 256, -1)) {
  220                         device_printf(dev, "could not set bus resource\n");
  221                         return ENXIO;
  222                 }
  223                 device_set_desc(dev, "VIA VT82C586B Power Management Unit");
  224                 return (BUS_PROBE_DEFAULT);
  225 
  226         default:
  227                 break;
  228         }
  229 
  230         return ENXIO;
  231 }
  232 
  233 
  234 static int
  235 viapm_pro_probe(device_t dev)
  236 {
  237         struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
  238 #ifdef VIAPM_BASE_ADDR
  239         u_int32_t l;
  240 #endif
  241         u_int32_t base_cfgreg;
  242         char *desc;
  243 
  244         switch (pci_get_devid(dev)) {
  245         case VIA_596A_PMU_ID:
  246                 desc = "VIA VT82C596A Power Management Unit";
  247                 viapm->type = VIAPM_TYP_596B;
  248                 base_cfgreg = VIAPM_PRO_BASE;
  249                 goto viapro;
  250 
  251         case VIA_596B_PMU_ID:
  252                 desc = "VIA VT82C596B Power Management Unit";
  253                 viapm->type = VIAPM_TYP_596B;
  254                 base_cfgreg = VIAPM_PRO_BASE;
  255                 goto viapro;
  256 
  257         case VIA_686A_PMU_ID:
  258                 desc = "VIA VT82C686A Power Management Unit";
  259                 viapm->type = VIAPM_TYP_686A;
  260                 base_cfgreg = VIAPM_PRO_BASE;
  261                 goto viapro;
  262 
  263         case VIA_8233_PMU_ID:
  264         case VIA_8233A_PMU_ID:
  265                 desc = "VIA VT8233 Power Management Unit";
  266                 viapm->type = VIAPM_TYP_UNKNOWN;
  267                 base_cfgreg = VIAPM_8233_BASE;
  268                 goto viapro;
  269 
  270         case VIA_8235_PMU_ID:
  271                 desc = "VIA VT8235 Power Management Unit";
  272                 viapm->type = VIAPM_TYP_UNKNOWN;
  273                 base_cfgreg = VIAPM_8233_BASE;
  274                 goto viapro;
  275 
  276         viapro:
  277 
  278 #ifdef VIAPM_BASE_ADDR
  279                 /* force VIAPM I/O base address */
  280 
  281                 /* enable the SMBus controller function */
  282                 l = pci_read_config(dev, VIAPM_PRO_SMBCTRL, 1);
  283                 pci_write_config(dev, VIAPM_PRO_SMBCTRL, l | 1, 1);
  284 
  285                 /* write the base address */
  286                 pci_write_config(dev, base_cfgreg,
  287                                  VIAPM_BASE_ADDR & VIAPM_PRO_BA_MASK, 4);
  288 #endif
  289 
  290                 viapm->base = pci_read_config(dev, base_cfgreg, 4) & VIAPM_PRO_BA_MASK;
  291 
  292                 /*
  293                  * We have to set the I/O resources by hand because it is
  294                  * described outside the viapmope of the traditional maps
  295                  */
  296                 viapm->iorid = base_cfgreg;
  297                 if (bus_set_resource(dev, SYS_RES_IOPORT, viapm->iorid,
  298                                      viapm->base, 16, -1)) {
  299                         device_printf(dev, "could not set bus resource 0x%x\n",
  300                                         viapm->base);
  301                         return ENXIO;
  302                 }
  303 
  304                 if (1 || bootverbose) {
  305                         device_printf(dev, "SMBus I/O base at 0x%x\n", viapm->base);
  306                 }
  307 
  308                 device_set_desc(dev, desc);
  309                 return (BUS_PROBE_DEFAULT);
  310 
  311         default:
  312                 break;
  313         }
  314 
  315         return ENXIO;
  316 }
  317 
  318 static int
  319 viapm_pro_attach(device_t dev)
  320 {
  321         struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
  322         u_int32_t l;
  323 #ifdef  notyet
  324         int error;
  325 #endif
  326 
  327         if (!(viapm->iores = bus_alloc_resource(dev, SYS_RES_IOPORT,
  328                 &viapm->iorid, 0l, ~0l, 1, RF_ACTIVE))) {
  329                 device_printf(dev, "could not allocate bus space\n");
  330                 goto fail;
  331         }
  332         viapm->st = rman_get_bustag(viapm->iores);
  333         viapm->sh = rman_get_bushandle(viapm->iores);
  334 
  335 #ifdef notyet
  336         /* force irq 9 */
  337         l = pci_read_config(dev, VIAPM_PRO_SMBCTRL, 1);
  338         pci_write_config(dev, VIAPM_PRO_SMBCTRL, l | 0x80, 1);
  339 
  340         viapm->irqrid = 0;
  341         if (!(viapm->irqres = bus_alloc_resource(dev, SYS_RES_IRQ,
  342                                 &viapm->irqrid, 9, 9, 1,
  343                                 RF_SHAREABLE | RF_ACTIVE))) {
  344                 device_printf(dev, "could not allocate irq\n");
  345                 goto fail;
  346         }
  347 
  348         error = bus_setup_intr(dev, viapm->irqres, 0,
  349                                (driver_intr_t *) viasmb_intr, viapm,
  350                                &viapm->irqih, NULL);
  351         if (error) {
  352                 device_printf(dev, "could not setup irq\n");
  353                 goto fail;
  354         }
  355 #endif
  356 
  357         if (1 | bootverbose) {
  358                 l = pci_read_config(dev, VIAPM_PRO_REVID, 1);
  359                 device_printf(dev, "SMBus revision code 0x%x\n", l);
  360         }
  361 
  362         viapm->smbus = device_add_child(dev, "smbus", -1);
  363 
  364         /* probe and attach the smbus */
  365         bus_generic_attach(dev);
  366 
  367         /* disable slave function */
  368         VIAPM_OUTB(SMBSCTRL, VIAPM_INB(SMBSCTRL) & ~SMBSCTRL_ENABLE);
  369 
  370         /* enable the SMBus controller function */
  371         l = pci_read_config(dev, VIAPM_PRO_SMBCTRL, 1);
  372         pci_write_config(dev, VIAPM_PRO_SMBCTRL, l | 1, 1);
  373 
  374 #ifdef notyet
  375         /* enable interrupts */
  376         VIAPM_OUTB(SMBHCTRL, VIAPM_INB(SMBHCTRL) | SMBHCTRL_ENABLE);
  377 #endif
  378 
  379         return 0;
  380 
  381 fail:
  382         if (viapm->iores)
  383                 bus_release_resource(dev, SYS_RES_IOPORT, viapm->iorid, viapm->iores);
  384 #ifdef notyet
  385         if (viapm->irqres)
  386                 bus_release_resource(dev, SYS_RES_IRQ, viapm->irqrid, viapm->irqres);
  387 #endif
  388 
  389         return ENXIO;
  390 }
  391 
  392 static int
  393 viapm_586b_attach(device_t dev)
  394 {
  395         struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
  396 
  397         if (!(viapm->iores = bus_alloc_resource(dev, SYS_RES_IOPORT,
  398                 &viapm->iorid, 0ul, ~0ul, 1, RF_ACTIVE | RF_SHAREABLE))) {
  399                 device_printf(dev, "could not allocate bus resource\n");
  400                 return ENXIO;
  401         }
  402         viapm->st = rman_get_bustag(viapm->iores);
  403         viapm->sh = rman_get_bushandle(viapm->iores);
  404 
  405         VIAPM_OUTB(GPIO_DIR, VIAPM_INB(GPIO_DIR) | VIAPM_SCL | VIAPM_SDA);
  406 
  407         /* add generic bit-banging code */
  408         if (!(viapm->iicbb = device_add_child(dev, "iicbb", -1)))
  409                 goto error;
  410 
  411         bus_generic_attach(dev);
  412 
  413         return 0;
  414 
  415 error:
  416         if (viapm->iores)
  417                 bus_release_resource(dev, SYS_RES_IOPORT,
  418                                         viapm->iorid, viapm->iores);
  419         return ENXIO;
  420 }
  421 
  422 static int
  423 viapm_586b_detach(device_t dev)
  424 {
  425         struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
  426         int error;
  427 
  428         bus_generic_detach(dev);
  429         if (viapm->iicbb) {
  430                 device_delete_child(dev, viapm->iicbb);
  431         }
  432 
  433         if (viapm->iores && (error = bus_release_resource(dev, SYS_RES_IOPORT,
  434                                                 viapm->iorid, viapm->iores)))
  435                 return (error);
  436 
  437         return 0;
  438 }
  439 
  440 static int
  441 viapm_pro_detach(device_t dev)
  442 {
  443         struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
  444         int error;
  445 
  446         bus_generic_detach(dev);
  447         if (viapm->smbus) {
  448                 device_delete_child(dev, viapm->smbus);
  449         }
  450 
  451         if ((error = bus_release_resource(dev, SYS_RES_IOPORT,
  452                                 viapm->iorid, viapm->iores)))
  453                 return (error);
  454 
  455 #ifdef notyet
  456         if ((error = bus_release_resource(dev, SYS_RES_IRQ,
  457                                         viapm->irqrid, viapm->irqres)))
  458                 return (error);
  459 #endif
  460 
  461         return 0;
  462 }
  463 
  464 static int
  465 viabb_callback(device_t dev, int index, caddr_t *data)
  466 {
  467         return 0;
  468 }
  469 
  470 static void
  471 viabb_setscl(device_t dev, int ctrl)
  472 {
  473         struct viapm_softc *viapm = device_get_softc(dev);
  474         u_char val;
  475 
  476         val = VIAPM_INB(GPIO_VAL);
  477 
  478         if (ctrl)
  479                 val |= VIAPM_SCL;
  480         else
  481                 val &= ~VIAPM_SCL;
  482 
  483         VIAPM_OUTB(GPIO_VAL, val);
  484 
  485         return;
  486 }
  487 
  488 static void
  489 viabb_setsda(device_t dev, int data)
  490 {
  491         struct viapm_softc *viapm = device_get_softc(dev);
  492         u_char val;
  493 
  494         val = VIAPM_INB(GPIO_VAL);
  495 
  496         if (data)
  497                 val |= VIAPM_SDA;
  498         else
  499                 val &= ~VIAPM_SDA;
  500 
  501         VIAPM_OUTB(GPIO_VAL, val);
  502 
  503         return;
  504 }
  505 
  506 static int
  507 viabb_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
  508 {
  509         /* reset bus */
  510         viabb_setsda(dev, 1);
  511         viabb_setscl(dev, 1);
  512 
  513         return (IIC_ENOADDR);
  514 }
  515 
  516 static int
  517 viabb_getscl(device_t dev)
  518 {
  519         struct viapm_softc *viapm = device_get_softc(dev);
  520 
  521         return ((VIAPM_INB(EXTSMI_VAL) & VIAPM_SCL) != 0);
  522 }
  523 
  524 static int
  525 viabb_getsda(device_t dev)
  526 {
  527         struct viapm_softc *viapm = device_get_softc(dev);
  528 
  529         return ((VIAPM_INB(EXTSMI_VAL) & VIAPM_SDA) != 0);
  530 }
  531 
  532 static int
  533 viapm_abort(struct viapm_softc *viapm)
  534 {
  535         VIAPM_OUTB(SMBHCTRL, SMBHCTRL_KILL);
  536         DELAY(10);
  537 
  538         return (0);
  539 }
  540 
  541 static int
  542 viapm_clear(struct viapm_softc *viapm)
  543 {
  544         VIAPM_OUTB(SMBHST, SMBHST_FAILED | SMBHST_COLLID |
  545                 SMBHST_ERROR | SMBHST_INTR);
  546         DELAY(10);
  547 
  548         return (0);
  549 }
  550 
  551 static int
  552 viapm_busy(struct viapm_softc *viapm)
  553 {
  554         u_char sts;
  555 
  556         sts = VIAPM_INB(SMBHST);
  557 
  558         VIAPM_DEBUG(kprintf("viapm: idle? STS=0x%x\n", sts));
  559 
  560         return (sts & SMBHST_BUSY);
  561 }
  562 
  563 /*
  564  * Poll the SMBus controller
  565  */
  566 static int
  567 viapm_wait(struct viapm_softc *viapm)
  568 {
  569         int count = 10000;
  570         u_char sts = 0;
  571         int error;
  572 
  573         /* wait for command to complete and SMBus controller is idle */
  574         while(count--) {
  575                 DELAY(10);
  576                 sts = VIAPM_INB(SMBHST);
  577 
  578                 /* check if the controller is processing a command */
  579                 if (!(sts & SMBHST_BUSY) && (sts & SMBHST_INTR))
  580                         break;
  581         }
  582 
  583         VIAPM_DEBUG(kprintf("viapm: SMBHST=0x%x\n", sts));
  584 
  585         error = SMB_ENOERR;
  586 
  587         if (!count)
  588                 error |= SMB_ETIMEOUT;
  589 
  590         if (sts & SMBHST_FAILED)
  591                 error |= SMB_EABORT;
  592 
  593         if (sts & SMBHST_COLLID)
  594                 error |= SMB_ENOACK;
  595 
  596         if (sts & SMBHST_ERROR)
  597                 error |= SMB_EBUSERR;
  598 
  599         if (error != SMB_ENOERR)
  600                 viapm_abort(viapm);
  601 
  602         viapm_clear(viapm);
  603 
  604         return (error);
  605 }
  606 
  607 static int
  608 viasmb_callback(device_t dev, int index, caddr_t *data)
  609 {
  610         int error = 0;
  611 
  612         switch (index) {
  613         case SMB_REQUEST_BUS:
  614         case SMB_RELEASE_BUS:
  615                 /* ok, bus allocation accepted */
  616                 break;
  617         default:
  618                 error = EINVAL;
  619         }
  620 
  621         return (error);
  622 }
  623 
  624 static int
  625 viasmb_quick(device_t dev, u_char slave, int how)
  626 {
  627         struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
  628         int error;
  629 
  630         viapm_clear(viapm);
  631         if (viapm_busy(viapm))
  632                 return (SMB_EBUSY);
  633 
  634         switch (how) {
  635         case SMB_QWRITE:
  636                 VIAPM_DEBUG(kprintf("viapm: QWRITE to 0x%x", slave));
  637                 VIAPM_OUTB(SMBHADDR, slave & ~LSB);
  638                 break;
  639         case SMB_QREAD:
  640                 VIAPM_DEBUG(kprintf("viapm: QREAD to 0x%x", slave));
  641                 VIAPM_OUTB(SMBHADDR, slave | LSB);
  642                 break;
  643         default:
  644                 panic("%s: unknown QUICK command (%x)!", __func__, how);
  645         }
  646 
  647         VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_QUICK);
  648 
  649         error = viapm_wait(viapm);
  650 
  651         return (error);
  652 }
  653 
  654 static int
  655 viasmb_sendb(device_t dev, u_char slave, char byte)
  656 {
  657         struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
  658         int error;
  659 
  660         viapm_clear(viapm);
  661         if (viapm_busy(viapm))
  662                 return (SMB_EBUSY);
  663 
  664         VIAPM_OUTB(SMBHADDR, slave & ~ LSB);
  665         VIAPM_OUTB(SMBHCMD, byte);
  666 
  667         VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_SENDRECV);
  668 
  669         error = viapm_wait(viapm);
  670 
  671         VIAPM_DEBUG(kprintf("viapm: SENDB to 0x%x, byte=0x%x, error=0x%x\n", slave, byte, error));
  672 
  673         return (error);
  674 }
  675 
  676 static int
  677 viasmb_recvb(device_t dev, u_char slave, char *byte)
  678 {
  679         struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
  680         int error;
  681 
  682         viapm_clear(viapm);
  683         if (viapm_busy(viapm))
  684                 return (SMB_EBUSY);
  685 
  686         VIAPM_OUTB(SMBHADDR, slave | LSB);
  687 
  688         VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_SENDRECV);
  689 
  690         if ((error = viapm_wait(viapm)) == SMB_ENOERR)
  691                 *byte = VIAPM_INB(SMBHDATA0);
  692 
  693         VIAPM_DEBUG(kprintf("viapm: RECVB from 0x%x, byte=0x%x, error=0x%x\n", slave, *byte, error));
  694 
  695         return (error);
  696 }
  697 
  698 static int
  699 viasmb_writeb(device_t dev, u_char slave, char cmd, char byte)
  700 {
  701         struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
  702         int error;
  703 
  704         viapm_clear(viapm);
  705         if (viapm_busy(viapm))
  706                 return (SMB_EBUSY);
  707 
  708         VIAPM_OUTB(SMBHADDR, slave & ~ LSB);
  709         VIAPM_OUTB(SMBHCMD, cmd);
  710         VIAPM_OUTB(SMBHDATA0, byte);
  711 
  712         VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_BYTE);
  713 
  714         error = viapm_wait(viapm);
  715 
  716         VIAPM_DEBUG(kprintf("viapm: WRITEB to 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, byte, error));
  717 
  718         return (error);
  719 }
  720 
  721 static int
  722 viasmb_readb(device_t dev, u_char slave, char cmd, char *byte)
  723 {
  724         struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
  725         int error;
  726 
  727         viapm_clear(viapm);
  728         if (viapm_busy(viapm))
  729                 return (SMB_EBUSY);
  730 
  731         VIAPM_OUTB(SMBHADDR, slave | LSB);
  732         VIAPM_OUTB(SMBHCMD, cmd);
  733 
  734         VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_BYTE);
  735 
  736         if ((error = viapm_wait(viapm)) == SMB_ENOERR)
  737                 *byte = VIAPM_INB(SMBHDATA0);
  738 
  739         VIAPM_DEBUG(kprintf("viapm: READB from 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, *byte, error));
  740 
  741         return (error);
  742 }
  743 
  744 static int
  745 viasmb_writew(device_t dev, u_char slave, char cmd, short word)
  746 {
  747         struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
  748         int error;
  749 
  750         viapm_clear(viapm);
  751         if (viapm_busy(viapm))
  752                 return (SMB_EBUSY);
  753 
  754         VIAPM_OUTB(SMBHADDR, slave & ~ LSB);
  755         VIAPM_OUTB(SMBHCMD, cmd);
  756         VIAPM_OUTB(SMBHDATA0, word & 0x00ff);
  757         VIAPM_OUTB(SMBHDATA1, (word & 0xff00) >> 8);
  758 
  759         VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_WORD);
  760 
  761         error = viapm_wait(viapm);
  762 
  763         VIAPM_DEBUG(kprintf("viapm: WRITEW to 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, word, error));
  764 
  765         return (error);
  766 }
  767 
  768 static int
  769 viasmb_readw(device_t dev, u_char slave, char cmd, short *word)
  770 {
  771         struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
  772         int error;
  773         u_char high, low;
  774 
  775         viapm_clear(viapm);
  776         if (viapm_busy(viapm))
  777                 return (SMB_EBUSY);
  778 
  779         VIAPM_OUTB(SMBHADDR, slave | LSB);
  780         VIAPM_OUTB(SMBHCMD, cmd);
  781 
  782         VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_WORD);
  783 
  784         if ((error = viapm_wait(viapm)) == SMB_ENOERR) {
  785                 low = VIAPM_INB(SMBHDATA0);
  786                 high = VIAPM_INB(SMBHDATA1);
  787 
  788                 *word = ((high & 0xff) << 8) | (low & 0xff);
  789         }
  790 
  791         VIAPM_DEBUG(kprintf("viapm: READW from 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, *word, error));
  792 
  793         return (error);
  794 }
  795 
  796 static int
  797 viasmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
  798 {
  799         struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
  800         u_char i;
  801         int error;
  802 
  803         if (count < 1 || count > 32)
  804                 return (SMB_EINVAL);
  805 
  806         viapm_clear(viapm);
  807         if (viapm_busy(viapm))
  808                 return (SMB_EBUSY);
  809 
  810         VIAPM_OUTB(SMBHADDR, slave & ~LSB);
  811         VIAPM_OUTB(SMBHCMD, cmd);
  812         VIAPM_OUTB(SMBHDATA0, count);
  813         i = VIAPM_INB(SMBHCTRL);
  814 
  815         /* fill the 32-byte internal buffer */
  816         for (i = 0; i < count; i++) {
  817                 VIAPM_OUTB(SMBHBLOCK, buf[i]);
  818                 DELAY(2);
  819         }
  820         VIAPM_OUTB(SMBHCMD, cmd);
  821         VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_BLOCK);
  822 
  823         error = viapm_wait(viapm);
  824 
  825         VIAPM_DEBUG(kprintf("viapm: WRITEBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error));
  826 
  827         return (error);
  828 
  829 }
  830 
  831 static int
  832 viasmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf)
  833 {
  834         struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
  835         u_char data, len, i;
  836         int error;
  837 
  838         if (*count < 1 || *count > 32)
  839                 return (SMB_EINVAL);
  840 
  841         viapm_clear(viapm);
  842         if (viapm_busy(viapm))
  843                 return (SMB_EBUSY);
  844 
  845         VIAPM_OUTB(SMBHADDR, slave | LSB);
  846         VIAPM_OUTB(SMBHCMD, cmd);
  847         VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_BLOCK);
  848 
  849         if ((error = viapm_wait(viapm)) != SMB_ENOERR)
  850                 goto error;
  851 
  852         len = VIAPM_INB(SMBHDATA0);
  853         i = VIAPM_INB(SMBHCTRL);                /* reset counter */
  854 
  855         /* read the 32-byte internal buffer */
  856         for (i = 0; i < len; i++) {
  857                 data = VIAPM_INB(SMBHBLOCK);
  858                 if (i < *count)
  859                         buf[i] = data;
  860                 DELAY(2);
  861         }
  862         *count = len;
  863 
  864 error:
  865         VIAPM_DEBUG(kprintf("viapm: READBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, *count, cmd, error));
  866 
  867         return (error);
  868 }
  869 
  870 static device_method_t viapm_methods[] = {
  871         /* device interface */
  872         DEVMETHOD(device_probe,         viapm_586b_probe),
  873         DEVMETHOD(device_attach,        viapm_586b_attach),
  874         DEVMETHOD(device_detach,        viapm_586b_detach),
  875 
  876         /* iicbb interface */
  877         DEVMETHOD(iicbb_callback,       viabb_callback),
  878         DEVMETHOD(iicbb_setscl,         viabb_setscl),
  879         DEVMETHOD(iicbb_setsda,         viabb_setsda),
  880         DEVMETHOD(iicbb_getscl,         viabb_getscl),
  881         DEVMETHOD(iicbb_getsda,         viabb_getsda),
  882         DEVMETHOD(iicbb_reset,          viabb_reset),
  883 
  884         /* Bus interface */
  885         DEVMETHOD(bus_print_child,      bus_generic_print_child),
  886         DEVMETHOD(bus_alloc_resource,   bus_generic_alloc_resource),
  887         DEVMETHOD(bus_release_resource, bus_generic_release_resource),
  888         DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
  889         DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
  890         DEVMETHOD(bus_setup_intr,       bus_generic_setup_intr),
  891         DEVMETHOD(bus_teardown_intr,    bus_generic_teardown_intr),
  892 
  893         DEVMETHOD_END
  894 };
  895 
  896 static driver_t viapm_driver = {
  897         "viapm",
  898         viapm_methods,
  899         sizeof(struct viapm_softc),
  900 };
  901 
  902 static device_method_t viapropm_methods[] = {
  903         /* device interface */
  904         DEVMETHOD(device_probe,         viapm_pro_probe),
  905         DEVMETHOD(device_attach,        viapm_pro_attach),
  906         DEVMETHOD(device_detach,        viapm_pro_detach),
  907 
  908         /* smbus interface */
  909         DEVMETHOD(smbus_callback,       viasmb_callback),
  910         DEVMETHOD(smbus_quick,          viasmb_quick),
  911         DEVMETHOD(smbus_sendb,          viasmb_sendb),
  912         DEVMETHOD(smbus_recvb,          viasmb_recvb),
  913         DEVMETHOD(smbus_writeb,         viasmb_writeb),
  914         DEVMETHOD(smbus_readb,          viasmb_readb),
  915         DEVMETHOD(smbus_writew,         viasmb_writew),
  916         DEVMETHOD(smbus_readw,          viasmb_readw),
  917         DEVMETHOD(smbus_bwrite,         viasmb_bwrite),
  918         DEVMETHOD(smbus_bread,          viasmb_bread),
  919 
  920         /* Bus interface */
  921         DEVMETHOD(bus_print_child,      bus_generic_print_child),
  922         DEVMETHOD(bus_alloc_resource,   bus_generic_alloc_resource),
  923         DEVMETHOD(bus_release_resource, bus_generic_release_resource),
  924         DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
  925         DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
  926         DEVMETHOD(bus_setup_intr,       bus_generic_setup_intr),
  927         DEVMETHOD(bus_teardown_intr,    bus_generic_teardown_intr),
  928 
  929         DEVMETHOD_END
  930 };
  931 
  932 static driver_t viapropm_driver = {
  933         "viapropm",
  934         viapropm_methods,
  935         sizeof(struct viapm_softc),
  936 };
  937 
  938 DECLARE_DUMMY_MODULE(viapm);
  939 DRIVER_MODULE(viapm, pci, viapm_driver, viapm_devclass, NULL, NULL);
  940 DRIVER_MODULE(viapropm, pci, viapropm_driver, viapropm_devclass, NULL, NULL);
  941 DRIVER_MODULE(smbus, viapropm, smbus_driver, smbus_devclass, NULL, NULL);
  942 
  943 MODULE_DEPEND(viapm, pci, 1, 1, 1);
  944 MODULE_DEPEND(viapropm, pci, 1, 1, 1);
  945 MODULE_DEPEND(viapm, iicbb, IICBB_MINVER, IICBB_PREFVER, IICBB_MAXVER);
  946 MODULE_DEPEND(viapropm, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
  947 MODULE_VERSION(viapm, 1);

Cache object: d72adee69f8fe00b25ae72bc27546ca6


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.