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/pci/alpm.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) 1998, 1999, 2001 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 
   27 /*
   28  * Power Management support for the Acer M15x3 chipsets
   29  */
   30 
   31 #include <sys/cdefs.h>
   32 __FBSDID("$FreeBSD: releng/6.1/sys/pci/alpm.c 146734 2005-05-29 04:42:30Z nyan $");
   33 
   34 #include <sys/param.h>
   35 #include <sys/kernel.h>
   36 #include <sys/systm.h>
   37 #include <sys/module.h>
   38 #include <sys/bus.h>
   39 #include <sys/uio.h>
   40 
   41 #include <machine/bus.h>
   42 #include <machine/resource.h>
   43 #include <sys/rman.h>
   44 
   45 #include <dev/pci/pcivar.h>
   46 #include <dev/pci/pcireg.h>
   47 
   48 #include <dev/iicbus/iiconf.h>
   49 #include <dev/smbus/smbconf.h>
   50 #include "smbus_if.h"
   51 
   52 #define ALPM_DEBUG(x)   if (alpm_debug) (x)
   53 
   54 #ifdef DEBUG
   55 static int alpm_debug = 1;
   56 #else
   57 static int alpm_debug = 0;
   58 #endif
   59 
   60 #define ACER_M1543_PMU_ID       0x710110b9
   61 
   62 /* Uncomment this line to force another I/O base address for SMB */
   63 /* #define ALPM_SMBIO_BASE_ADDR 0x3a80 */
   64 
   65 /* I/O registers offsets - the base address is programmed via the
   66  * SMBBA PCI configuration register
   67  */
   68 #define SMBSTS          0x0     /* SMBus host/slave status register */
   69 #define SMBCMD          0x1     /* SMBus host/slave command register */
   70 #define SMBSTART        0x2     /* start to generate programmed cycle */
   71 #define SMBHADDR        0x3     /* host address register */
   72 #define SMBHDATA        0x4     /* data A register for host controller */
   73 #define SMBHDATB        0x5     /* data B register for host controller */
   74 #define SMBHBLOCK       0x6     /* block register for host controller */
   75 #define SMBHCMD         0x7     /* command register for host controller */
   76 
   77 /* SMBSTS masks */
   78 #define TERMINATE       0x80
   79 #define BUS_COLLI       0x40
   80 #define DEVICE_ERR      0x20
   81 #define SMI_I_STS       0x10
   82 #define HST_BSY         0x08
   83 #define IDL_STS         0x04
   84 #define HSTSLV_STS      0x02
   85 #define HSTSLV_BSY      0x01
   86 
   87 /* SMBCMD masks */
   88 #define SMB_BLK_CLR     0x80
   89 #define T_OUT_CMD       0x08
   90 #define ABORT_HOST      0x04
   91 
   92 /* SMBus commands */
   93 #define SMBQUICK        0x00
   94 #define SMBSRBYTE       0x10            /* send/receive byte */
   95 #define SMBWRBYTE       0x20            /* write/read byte */
   96 #define SMBWRWORD       0x30            /* write/read word */
   97 #define SMBWRBLOCK      0x40            /* write/read block */
   98 
   99 /* PCI configuration registers and masks
  100  */
  101 #define COM             0x4
  102 #define COM_ENABLE_IO   0x1
  103 
  104 #define SMBBA           0x14
  105 
  106 #define ATPC            0x5b
  107 #define ATPC_SMBCTRL    0x04            /* XX linux has this as 0x6 */
  108 
  109 #define SMBHSI          0xe0
  110 #define SMBHSI_SLAVE    0x2
  111 #define SMBHSI_HOST     0x1
  112 
  113 #define SMBHCBC         0xe2
  114 #define SMBHCBC_CLOCK   0x70
  115 
  116 #define SMBCLOCK_149K   0x0
  117 #define SMBCLOCK_74K    0x20
  118 #define SMBCLOCK_37K    0x40
  119 #define SMBCLOCK_223K   0x80
  120 #define SMBCLOCK_111K   0xa0
  121 #define SMBCLOCK_55K    0xc0
  122 
  123 struct alpm_softc {
  124         int base;
  125         struct resource *res;
  126         bus_space_tag_t smbst;
  127         bus_space_handle_t smbsh;
  128         device_t smbus;
  129 };
  130 
  131 #define ALPM_SMBINB(alpm,register) \
  132         (bus_space_read_1(alpm->smbst, alpm->smbsh, register))
  133 #define ALPM_SMBOUTB(alpm,register,value) \
  134         (bus_space_write_1(alpm->smbst, alpm->smbsh, register, value))
  135 
  136 static int
  137 alpm_probe(device_t dev)
  138 {
  139 #ifdef ALPM_SMBIO_BASE_ADDR
  140         u_int32_t l;
  141 #endif
  142 
  143         if (pci_get_devid(dev) == ACER_M1543_PMU_ID) {
  144                 device_set_desc(dev, "AcerLabs M15x3 Power Management Unit");
  145 
  146 #ifdef ALPM_SMBIO_BASE_ADDR
  147                 if (bootverbose || alpm_debug)
  148                         device_printf(dev, "forcing base I/O at 0x%x\n",
  149                                         ALPM_SMBIO_BASE_ADDR);
  150 
  151                 /* disable I/O */
  152                 l = pci_read_config(dev, COM, 2);
  153                 pci_write_config(dev, COM, l & ~COM_ENABLE_IO, 2);
  154 
  155                 /* set the I/O base address */
  156                 pci_write_config(dev, SMBBA, ALPM_SMBIO_BASE_ADDR | 0x1, 4);
  157 
  158                 /* enable I/O */
  159                 pci_write_config(dev, COM, l | COM_ENABLE_IO, 2);
  160 
  161                 if (bus_set_resource(dev, SYS_RES_IOPORT, SMBBA,
  162                                         ALPM_SMBIO_BASE_ADDR, 256)) {
  163                         device_printf(dev, "could not set bus resource\n");
  164                         return (ENXIO);
  165                 }
  166 #endif
  167                 return (BUS_PROBE_DEFAULT);
  168         }
  169 
  170         return (ENXIO);
  171 }
  172 
  173 static int
  174 alpm_attach(device_t dev)
  175 {
  176         int rid;
  177         u_int32_t l;
  178         struct alpm_softc *alpm;
  179 
  180         alpm = device_get_softc(dev);
  181 
  182         /* Unlock SMBIO base register access */
  183         l = pci_read_config(dev, ATPC, 1);
  184         pci_write_config(dev, ATPC, l & ~ATPC_SMBCTRL, 1);
  185 
  186         /*
  187          * XX linux sets clock to 74k, should we?
  188         l = pci_read_config(dev, SMBHCBC, 1);
  189         l &= 0x1f;
  190         l |= SMBCLOCK_74K;
  191         pci_write_config(dev, SMBHCBC, l, 1);
  192          */
  193 
  194         if (bootverbose || alpm_debug) {
  195                 l = pci_read_config(dev, SMBHSI, 1);
  196                 device_printf(dev, "%s/%s",
  197                         (l & SMBHSI_HOST) ? "host":"nohost",
  198                         (l & SMBHSI_SLAVE) ? "slave":"noslave");
  199 
  200                 l = pci_read_config(dev, SMBHCBC, 1);
  201                 switch (l & SMBHCBC_CLOCK) {
  202                 case SMBCLOCK_149K:
  203                         printf(" 149K");
  204                         break;
  205                 case SMBCLOCK_74K:
  206                         printf(" 74K");
  207                         break;
  208                 case SMBCLOCK_37K:
  209                         printf(" 37K");
  210                         break;
  211                 case SMBCLOCK_223K:
  212                         printf(" 223K");
  213                         break;
  214                 case SMBCLOCK_111K:
  215                         printf(" 111K");
  216                         break;
  217                 case SMBCLOCK_55K:
  218                         printf(" 55K");
  219                         break;
  220                 default:
  221                         printf("unkown");
  222                         break;
  223                 }
  224                 printf("\n");
  225         }
  226 
  227         rid = SMBBA;
  228         alpm->res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
  229             RF_ACTIVE);
  230 
  231         if (alpm->res == NULL) {
  232                 device_printf(dev,"Could not allocate Bus space\n");
  233                 return (ENXIO);
  234         }
  235         alpm->smbst = rman_get_bustag(alpm->res);
  236         alpm->smbsh = rman_get_bushandle(alpm->res);
  237 
  238         /* attach the smbus */
  239         alpm->smbus = device_add_child(dev, "smbus", -1);
  240         bus_generic_attach(dev);
  241 
  242         return (0);
  243 }
  244 
  245 static int
  246 alpm_detach(device_t dev)
  247 {
  248         struct alpm_softc *alpm = device_get_softc(dev);
  249 
  250         if (alpm->smbus) {
  251                 device_delete_child(dev, alpm->smbus);
  252                 alpm->smbus = NULL;
  253         }
  254 
  255         if (alpm->res)
  256                 bus_release_resource(dev, SYS_RES_IOPORT, SMBBA, alpm->res);
  257 
  258         return (0);
  259 }
  260 
  261 static int
  262 alpm_callback(device_t dev, int index, caddr_t *data)
  263 {
  264         int error = 0;
  265 
  266         switch (index) {
  267         case SMB_REQUEST_BUS:
  268         case SMB_RELEASE_BUS:
  269                 /* ok, bus allocation accepted */
  270                 break;
  271         default:
  272                 error = EINVAL;
  273         }
  274 
  275         return (error);
  276 }
  277 
  278 static int
  279 alpm_clear(struct alpm_softc *sc)
  280 {
  281         ALPM_SMBOUTB(sc, SMBSTS, 0xff);
  282         DELAY(10);
  283 
  284         return (0);
  285 }
  286 
  287 #if 0
  288 static int
  289 alpm_abort(struct alpm_softc *sc)
  290 {
  291         ALPM_SMBOUTB(sc, SMBCMD, T_OUT_CMD | ABORT_HOST);
  292 
  293         return (0);
  294 }
  295 #endif
  296 
  297 static int
  298 alpm_idle(struct alpm_softc *sc)
  299 {
  300         u_char sts;
  301 
  302         sts = ALPM_SMBINB(sc, SMBSTS);
  303 
  304         ALPM_DEBUG(printf("alpm: idle? STS=0x%x\n", sts));
  305 
  306         return (sts & IDL_STS);
  307 }
  308 
  309 /*
  310  * Poll the SMBus controller
  311  */
  312 static int
  313 alpm_wait(struct alpm_softc *sc)
  314 {
  315         int count = 10000;
  316         u_char sts = 0;
  317         int error;
  318 
  319         /* wait for command to complete and SMBus controller is idle */
  320         while(count--) {
  321                 DELAY(10);
  322                 sts = ALPM_SMBINB(sc, SMBSTS);
  323                 if (sts & SMI_I_STS)
  324                         break;
  325         }
  326 
  327         ALPM_DEBUG(printf("alpm: STS=0x%x\n", sts));
  328 
  329         error = SMB_ENOERR;
  330 
  331         if (!count)
  332                 error |= SMB_ETIMEOUT;
  333 
  334         if (sts & TERMINATE)
  335                 error |= SMB_EABORT;
  336 
  337         if (sts & BUS_COLLI)
  338                 error |= SMB_ENOACK;
  339 
  340         if (sts & DEVICE_ERR)
  341                 error |= SMB_EBUSERR;
  342 
  343         if (error != SMB_ENOERR)
  344                 alpm_clear(sc);
  345 
  346         return (error);
  347 }
  348 
  349 static int
  350 alpm_quick(device_t dev, u_char slave, int how)
  351 {
  352         struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
  353         int error;
  354 
  355         alpm_clear(sc);
  356         if (!alpm_idle(sc))
  357                 return (EBUSY);
  358 
  359         switch (how) {
  360         case SMB_QWRITE:
  361                 ALPM_DEBUG(printf("alpm: QWRITE to 0x%x", slave));
  362                 ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB);
  363                 break;
  364         case SMB_QREAD:
  365                 ALPM_DEBUG(printf("alpm: QREAD to 0x%x", slave));
  366                 ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB);
  367                 break;
  368         default:
  369                 panic("%s: unknown QUICK command (%x)!", __func__,
  370                         how);
  371         }
  372         ALPM_SMBOUTB(sc, SMBCMD, SMBQUICK);
  373         ALPM_SMBOUTB(sc, SMBSTART, 0xff);
  374 
  375         error = alpm_wait(sc);
  376 
  377         ALPM_DEBUG(printf(", error=0x%x\n", error));
  378 
  379         return (error);
  380 }
  381 
  382 static int
  383 alpm_sendb(device_t dev, u_char slave, char byte)
  384 {
  385         struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
  386         int error;
  387 
  388         alpm_clear(sc);
  389         if (!alpm_idle(sc))
  390                 return (SMB_EBUSY);
  391 
  392         ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB);
  393         ALPM_SMBOUTB(sc, SMBCMD, SMBSRBYTE);
  394         ALPM_SMBOUTB(sc, SMBHDATA, byte);
  395         ALPM_SMBOUTB(sc, SMBSTART, 0xff);
  396 
  397         error = alpm_wait(sc);
  398 
  399         ALPM_DEBUG(printf("alpm: SENDB to 0x%x, byte=0x%x, error=0x%x\n", slave, byte, error));
  400 
  401         return (error);
  402 }
  403 
  404 static int
  405 alpm_recvb(device_t dev, u_char slave, char *byte)
  406 {
  407         struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
  408         int error;
  409 
  410         alpm_clear(sc);
  411         if (!alpm_idle(sc))
  412                 return (SMB_EBUSY);
  413 
  414         ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB);
  415         ALPM_SMBOUTB(sc, SMBCMD, SMBSRBYTE);
  416         ALPM_SMBOUTB(sc, SMBSTART, 0xff);
  417 
  418         if ((error = alpm_wait(sc)) == SMB_ENOERR)
  419                 *byte = ALPM_SMBINB(sc, SMBHDATA);
  420 
  421         ALPM_DEBUG(printf("alpm: RECVB from 0x%x, byte=0x%x, error=0x%x\n", slave, *byte, error));
  422 
  423         return (error);
  424 }
  425 
  426 static int
  427 alpm_writeb(device_t dev, u_char slave, char cmd, char byte)
  428 {
  429         struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
  430         int error;
  431 
  432         alpm_clear(sc);
  433         if (!alpm_idle(sc))
  434                 return (SMB_EBUSY);
  435 
  436         ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB);
  437         ALPM_SMBOUTB(sc, SMBCMD, SMBWRBYTE);
  438         ALPM_SMBOUTB(sc, SMBHDATA, byte);
  439         ALPM_SMBOUTB(sc, SMBHCMD, cmd);
  440         ALPM_SMBOUTB(sc, SMBSTART, 0xff);
  441 
  442         error = alpm_wait(sc);
  443 
  444         ALPM_DEBUG(printf("alpm: WRITEB to 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, byte, error));
  445 
  446         return (error);
  447 }
  448 
  449 static int
  450 alpm_readb(device_t dev, u_char slave, char cmd, char *byte)
  451 {
  452         struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
  453         int error;
  454 
  455         alpm_clear(sc);
  456         if (!alpm_idle(sc))
  457                 return (SMB_EBUSY);
  458 
  459         ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB);
  460         ALPM_SMBOUTB(sc, SMBCMD, SMBWRBYTE);
  461         ALPM_SMBOUTB(sc, SMBHCMD, cmd);
  462         ALPM_SMBOUTB(sc, SMBSTART, 0xff);
  463 
  464         if ((error = alpm_wait(sc)) == SMB_ENOERR)
  465                 *byte = ALPM_SMBINB(sc, SMBHDATA);
  466 
  467         ALPM_DEBUG(printf("alpm: READB from 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, *byte, error));
  468 
  469         return (error);
  470 }
  471 
  472 static int
  473 alpm_writew(device_t dev, u_char slave, char cmd, short word)
  474 {
  475         struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
  476         int error;
  477 
  478         alpm_clear(sc);
  479         if (!alpm_idle(sc))
  480                 return (SMB_EBUSY);
  481 
  482         ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB);
  483         ALPM_SMBOUTB(sc, SMBCMD, SMBWRWORD);
  484         ALPM_SMBOUTB(sc, SMBHDATA, word & 0x00ff);
  485         ALPM_SMBOUTB(sc, SMBHDATB, (word & 0xff00) >> 8);
  486         ALPM_SMBOUTB(sc, SMBHCMD, cmd);
  487         ALPM_SMBOUTB(sc, SMBSTART, 0xff);
  488 
  489         error = alpm_wait(sc);
  490 
  491         ALPM_DEBUG(printf("alpm: WRITEW to 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, word, error));
  492 
  493         return (error);
  494 }
  495 
  496 static int
  497 alpm_readw(device_t dev, u_char slave, char cmd, short *word)
  498 {
  499         struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
  500         int error;
  501         u_char high, low;
  502 
  503         alpm_clear(sc);
  504         if (!alpm_idle(sc))
  505                 return (SMB_EBUSY);
  506 
  507         ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB);
  508         ALPM_SMBOUTB(sc, SMBCMD, SMBWRWORD);
  509         ALPM_SMBOUTB(sc, SMBHCMD, cmd);
  510         ALPM_SMBOUTB(sc, SMBSTART, 0xff);
  511 
  512         if ((error = alpm_wait(sc)) == SMB_ENOERR) {
  513                 low = ALPM_SMBINB(sc, SMBHDATA);
  514                 high = ALPM_SMBINB(sc, SMBHDATB);
  515 
  516                 *word = ((high & 0xff) << 8) | (low & 0xff);
  517         }
  518 
  519         ALPM_DEBUG(printf("alpm: READW from 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, *word, error));
  520 
  521         return (error);
  522 }
  523 
  524 static int
  525 alpm_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
  526 {
  527         struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
  528         u_char remain, len, i;
  529         int error = SMB_ENOERR;
  530 
  531         alpm_clear(sc);
  532         if(!alpm_idle(sc))
  533                 return (SMB_EBUSY);
  534 
  535         remain = count;
  536         while (remain) {
  537                 len = min(remain, 32);
  538 
  539                 ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB);
  540         
  541                 /* set the cmd and reset the
  542                  * 32-byte long internal buffer */
  543                 ALPM_SMBOUTB(sc, SMBCMD, SMBWRBLOCK | SMB_BLK_CLR);
  544 
  545                 ALPM_SMBOUTB(sc, SMBHDATA, len);
  546 
  547                 /* fill the 32-byte internal buffer */
  548                 for (i=0; i<len; i++) {
  549                         ALPM_SMBOUTB(sc, SMBHBLOCK, buf[count-remain+i]);
  550                         DELAY(2);
  551                 }
  552                 ALPM_SMBOUTB(sc, SMBHCMD, cmd);
  553                 ALPM_SMBOUTB(sc, SMBSTART, 0xff);
  554 
  555                 if ((error = alpm_wait(sc)) != SMB_ENOERR)
  556                         goto error;
  557 
  558                 remain -= len;
  559         }
  560 
  561 error:
  562         ALPM_DEBUG(printf("alpm: WRITEBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error));
  563 
  564         return (error);
  565 }
  566 
  567 static int
  568 alpm_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf)
  569 {
  570         struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
  571         u_char remain, len, i;
  572         int error = SMB_ENOERR;
  573 
  574         alpm_clear(sc);
  575         if (!alpm_idle(sc))
  576                 return (SMB_EBUSY);
  577 
  578         remain = count;
  579         while (remain) {
  580                 ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB);
  581         
  582                 /* set the cmd and reset the
  583                  * 32-byte long internal buffer */
  584                 ALPM_SMBOUTB(sc, SMBCMD, SMBWRBLOCK | SMB_BLK_CLR);
  585 
  586                 ALPM_SMBOUTB(sc, SMBHCMD, cmd);
  587                 ALPM_SMBOUTB(sc, SMBSTART, 0xff);
  588 
  589                 if ((error = alpm_wait(sc)) != SMB_ENOERR)
  590                         goto error;
  591 
  592                 len = ALPM_SMBINB(sc, SMBHDATA);
  593 
  594                 /* read the 32-byte internal buffer */
  595                 for (i=0; i<len; i++) {
  596                         buf[count-remain+i] = ALPM_SMBINB(sc, SMBHBLOCK);
  597                         DELAY(2);
  598                 }
  599 
  600                 remain -= len;
  601         }
  602 error:
  603         ALPM_DEBUG(printf("alpm: READBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error));
  604 
  605         return (error);
  606 }
  607 
  608 static devclass_t alpm_devclass;
  609 
  610 static device_method_t alpm_methods[] = {
  611         /* device interface */
  612         DEVMETHOD(device_probe,         alpm_probe),
  613         DEVMETHOD(device_attach,        alpm_attach),
  614         DEVMETHOD(device_detach,        alpm_detach),
  615         
  616         /* smbus interface */
  617         DEVMETHOD(smbus_callback,       alpm_callback),
  618         DEVMETHOD(smbus_quick,          alpm_quick),
  619         DEVMETHOD(smbus_sendb,          alpm_sendb),
  620         DEVMETHOD(smbus_recvb,          alpm_recvb),
  621         DEVMETHOD(smbus_writeb,         alpm_writeb),
  622         DEVMETHOD(smbus_readb,          alpm_readb),
  623         DEVMETHOD(smbus_writew,         alpm_writew),
  624         DEVMETHOD(smbus_readw,          alpm_readw),
  625         DEVMETHOD(smbus_bwrite,         alpm_bwrite),
  626         DEVMETHOD(smbus_bread,          alpm_bread),
  627         
  628         { 0, 0 }
  629 };
  630 
  631 static driver_t alpm_driver = {
  632         "alpm",
  633         alpm_methods,
  634         sizeof(struct alpm_softc)
  635 };
  636 
  637 DRIVER_MODULE(alpm, pci, alpm_driver, alpm_devclass, 0, 0);
  638 MODULE_DEPEND(alpm, pci, 1, 1, 1);
  639 MODULE_DEPEND(alpm, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
  640 MODULE_VERSION(alpm, 1);

Cache object: 219fae4640398e2efc88bacf7ca86e5f


[ 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.