Home | History | Annotate | Line # | Download | only in i2c
      1  1.6   thorpej /* $NetBSD: act8846.c,v 1.6 2019/07/27 16:02:27 thorpej Exp $ */
      2  1.1  jmcneill 
      3  1.1  jmcneill /*-
      4  1.1  jmcneill  * Copyright (c) 2015 Jared D. McNeill <jmcneill (at) invisible.ca>
      5  1.1  jmcneill  * All rights reserved.
      6  1.1  jmcneill  *
      7  1.1  jmcneill  * Redistribution and use in source and binary forms, with or without
      8  1.1  jmcneill  * modification, are permitted provided that the following conditions
      9  1.1  jmcneill  * are met:
     10  1.1  jmcneill  * 1. Redistributions of source code must retain the above copyright
     11  1.1  jmcneill  *    notice, this list of conditions and the following disclaimer.
     12  1.1  jmcneill  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1  jmcneill  *    notice, this list of conditions and the following disclaimer in the
     14  1.1  jmcneill  *    documentation and/or other materials provided with the distribution.
     15  1.1  jmcneill  *
     16  1.1  jmcneill  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     17  1.1  jmcneill  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     18  1.1  jmcneill  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19  1.1  jmcneill  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     20  1.1  jmcneill  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  1.1  jmcneill  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  1.1  jmcneill  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     23  1.1  jmcneill  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     24  1.1  jmcneill  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25  1.1  jmcneill  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26  1.1  jmcneill  * POSSIBILITY OF SUCH DAMAGE.
     27  1.1  jmcneill  */
     28  1.1  jmcneill 
     29  1.3  jmcneill //#define ACT_DEBUG
     30  1.1  jmcneill 
     31  1.1  jmcneill #include <sys/cdefs.h>
     32  1.6   thorpej __KERNEL_RCSID(0, "$NetBSD: act8846.c,v 1.6 2019/07/27 16:02:27 thorpej Exp $");
     33  1.1  jmcneill 
     34  1.1  jmcneill #include <sys/param.h>
     35  1.1  jmcneill #include <sys/systm.h>
     36  1.1  jmcneill #include <sys/kernel.h>
     37  1.1  jmcneill #include <sys/device.h>
     38  1.1  jmcneill #include <sys/conf.h>
     39  1.1  jmcneill #include <sys/bus.h>
     40  1.1  jmcneill #include <sys/kmem.h>
     41  1.1  jmcneill 
     42  1.1  jmcneill #include <dev/i2c/i2cvar.h>
     43  1.1  jmcneill #include <dev/i2c/act8846.h>
     44  1.1  jmcneill 
     45  1.1  jmcneill #define ACT_BATTVOL_STATUS_REG		0x00
     46  1.1  jmcneill #define ACT_THERMAL_CTRL_REG		0x01
     47  1.1  jmcneill #define ACT_DCDC1_BASE_REG		0x10
     48  1.1  jmcneill #define ACT_DCDC2_BASE_REG		0x20
     49  1.1  jmcneill #define ACT_DCDC3_BASE_REG		0x30
     50  1.1  jmcneill #define ACT_DCDC4_BASE_REG		0x40
     51  1.1  jmcneill #define ACT_LDO1_BASE_REG		0x50
     52  1.1  jmcneill #define ACT_LDO2_BASE_REG		0x58
     53  1.1  jmcneill #define ACT_LDO3_BASE_REG		0x60
     54  1.1  jmcneill #define ACT_LDO4_BASE_REG		0x68
     55  1.1  jmcneill #define ACT_LDO5_BASE_REG		0x70
     56  1.1  jmcneill #define ACT_LDO6_BASE_REG		0x80
     57  1.1  jmcneill #define ACT_LDO7_BASE_REG		0x90
     58  1.1  jmcneill #define ACT_LDO8_BASE_REG		0xa0
     59  1.1  jmcneill #define ACT_LDO9_BASE_REG		0xb0
     60  1.1  jmcneill 
     61  1.1  jmcneill #define ACT_VSET0_OFFSET		0
     62  1.1  jmcneill #define ACT_VSET1_OFFSET		1
     63  1.1  jmcneill #define ACT_DCDC_CTRL_OFFSET		2
     64  1.1  jmcneill #define ACT_LDO_CTRL_OFFSET		1
     65  1.1  jmcneill 
     66  1.1  jmcneill #define ACT_VSET_VSET			__BITS(5,0)
     67  1.1  jmcneill 
     68  1.1  jmcneill #define ACT_DCDC_CTRL_ON		__BIT(7)
     69  1.1  jmcneill 
     70  1.1  jmcneill #define ACT_LDO_CTRL_ON			__BIT(7)
     71  1.1  jmcneill 
     72  1.1  jmcneill enum act8846_ctrl_type {
     73  1.1  jmcneill 	ACT_CTRL_DCDC,
     74  1.1  jmcneill 	ACT_CTRL_LDO,
     75  1.1  jmcneill };
     76  1.1  jmcneill 
     77  1.1  jmcneill #define ACT_VOLTAGE_MIN			600
     78  1.1  jmcneill #define ACT_VOLTAGE_MAX			3900
     79  1.1  jmcneill 
     80  1.1  jmcneill struct act8846_ctrl {
     81  1.1  jmcneill 	device_t	c_dev;
     82  1.1  jmcneill 
     83  1.1  jmcneill 	const char *	c_name;
     84  1.1  jmcneill 	u_int		c_min;
     85  1.1  jmcneill 	u_int		c_max;
     86  1.1  jmcneill 	uint8_t		c_base;
     87  1.1  jmcneill 	enum act8846_ctrl_type c_type;
     88  1.1  jmcneill };
     89  1.1  jmcneill 
     90  1.1  jmcneill #define ACT_CTRL(name, base, type)				\
     91  1.1  jmcneill 	{ .c_name = (name),					\
     92  1.1  jmcneill 	  .c_min = ACT_VOLTAGE_MIN, .c_max = ACT_VOLTAGE_MAX,	\
     93  1.1  jmcneill 	  .c_base = ACT_ ## base ## _BASE_REG, .c_type = (type) }
     94  1.1  jmcneill 
     95  1.1  jmcneill #define ACT_DCDC(name, base)	ACT_CTRL(name, base, ACT_CTRL_DCDC)
     96  1.1  jmcneill #define ACT_LDO(name, base)	ACT_CTRL(name, base, ACT_CTRL_LDO)
     97  1.1  jmcneill 
     98  1.1  jmcneill static const struct act8846_ctrl act8846_ctrls[] = {
     99  1.1  jmcneill 	ACT_DCDC("DCDC1", DCDC1),	/* VCC_DDR */
    100  1.1  jmcneill 	ACT_DCDC("DCDC2", DCDC2),	/* VDD_LOG */
    101  1.1  jmcneill 	ACT_DCDC("DCDC3", DCDC3),	/* VDD_ARM */
    102  1.1  jmcneill 	ACT_DCDC("DCDC4", DCDC4),	/* VCC_IO */
    103  1.1  jmcneill 	ACT_LDO("LDO1", LDO1),		/* VDD_10 */
    104  1.1  jmcneill 	ACT_LDO("LDO2", LDO2),		/* VCC_25 */
    105  1.1  jmcneill 	ACT_LDO("LDO3", LDO3),		/* VCC18_CIF */
    106  1.1  jmcneill 	ACT_LDO("LDO4", LDO4),		/* VCCA_33 */
    107  1.1  jmcneill 	ACT_LDO("LDO5", LDO5),		/* VCC_TOUCH */
    108  1.1  jmcneill 	ACT_LDO("LDO6", LDO6),		/* VCC33 */
    109  1.1  jmcneill 	ACT_LDO("LDO7", LDO7),		/* VCC18_IO */
    110  1.1  jmcneill 	ACT_LDO("LDO8", LDO8),		/* VCC28_CIF */
    111  1.1  jmcneill #if 0
    112  1.1  jmcneill 	ACT_LDO("LDO9", LDO9),		/* VDD_RTC (Always-ON) */
    113  1.1  jmcneill #endif
    114  1.1  jmcneill };
    115  1.1  jmcneill 
    116  1.1  jmcneill /* From datasheet, Table 5: REGx/VSET[] Output Voltage Setting */
    117  1.1  jmcneill static const u_int act8846_vset[] = {
    118  1.1  jmcneill 	600, 625, 650, 675, 700, 725, 750, 775,
    119  1.1  jmcneill 	800, 825, 850, 875, 900, 925, 950, 975,
    120  1.1  jmcneill 	1000, 1025, 1050, 1075, 1100, 1125, 1150, 1175,
    121  1.1  jmcneill 	1200, 1250, 1300, 1350, 1400, 1450, 1500, 1550,
    122  1.1  jmcneill 	1600, 1650, 1700, 1750, 1800, 1850, 1900, 1950,
    123  1.1  jmcneill 	2000, 2050, 2100, 2150, 2200, 2250, 2300, 2350,
    124  1.1  jmcneill 	2400, 2500, 2600, 2700, 2800, 2900, 3000, 3100,
    125  1.1  jmcneill 	3200, 3300, 3400, 3500, 3600, 3700, 3800, 3900
    126  1.1  jmcneill };
    127  1.1  jmcneill 
    128  1.1  jmcneill struct act8846_softc {
    129  1.1  jmcneill 	device_t	sc_dev;
    130  1.1  jmcneill 	i2c_tag_t	sc_i2c;
    131  1.1  jmcneill 	i2c_addr_t	sc_addr;
    132  1.1  jmcneill 
    133  1.1  jmcneill 	u_int		sc_nctrl;
    134  1.1  jmcneill 	struct act8846_ctrl *sc_ctrl;
    135  1.1  jmcneill };
    136  1.1  jmcneill 
    137  1.1  jmcneill static int	act8846_match(device_t, cfdata_t, void *);
    138  1.1  jmcneill static void	act8846_attach(device_t, device_t, void *);
    139  1.1  jmcneill 
    140  1.1  jmcneill static int	act8846_read(struct act8846_softc *, uint8_t, uint8_t *);
    141  1.1  jmcneill static int	act8846_write(struct act8846_softc *, uint8_t, uint8_t);
    142  1.1  jmcneill 
    143  1.1  jmcneill static void	act8846_print(struct act8846_ctrl *c);
    144  1.1  jmcneill 
    145  1.1  jmcneill CFATTACH_DECL_NEW(act8846pm, sizeof(struct act8846_softc),
    146  1.1  jmcneill     act8846_match, act8846_attach, NULL, NULL);
    147  1.1  jmcneill 
    148  1.1  jmcneill static int
    149  1.1  jmcneill act8846_match(device_t parent, cfdata_t match, void *aux)
    150  1.1  jmcneill {
    151  1.4  jmcneill 	struct i2c_attach_args *ia = aux;
    152  1.4  jmcneill 
    153  1.4  jmcneill 	if (ia->ia_addr == 0x5a)
    154  1.5   thorpej 		return I2C_MATCH_ADDRESS_ONLY;
    155  1.4  jmcneill 
    156  1.4  jmcneill 	return 0;
    157  1.1  jmcneill }
    158  1.1  jmcneill 
    159  1.1  jmcneill static void
    160  1.1  jmcneill act8846_attach(device_t parent, device_t self, void *aux)
    161  1.1  jmcneill {
    162  1.1  jmcneill 	struct act8846_softc *sc = device_private(self);
    163  1.1  jmcneill 	struct i2c_attach_args *ia = aux;
    164  1.1  jmcneill 	u_int n;
    165  1.1  jmcneill 
    166  1.1  jmcneill 	sc->sc_dev = self;
    167  1.1  jmcneill 	sc->sc_i2c = ia->ia_tag;
    168  1.1  jmcneill 	sc->sc_addr = ia->ia_addr;
    169  1.1  jmcneill 
    170  1.1  jmcneill 	aprint_naive("\n");
    171  1.1  jmcneill 	aprint_normal("\n");
    172  1.1  jmcneill 
    173  1.1  jmcneill 	sc->sc_nctrl = __arraycount(act8846_ctrls);
    174  1.1  jmcneill 	sc->sc_ctrl = kmem_alloc(sizeof(act8846_ctrls), KM_SLEEP);
    175  1.1  jmcneill 	memcpy(sc->sc_ctrl, act8846_ctrls, sizeof(act8846_ctrls));
    176  1.1  jmcneill 	for (n = 0; n < sc->sc_nctrl; n++) {
    177  1.1  jmcneill 		sc->sc_ctrl[n].c_dev = self;
    178  1.1  jmcneill 	}
    179  1.1  jmcneill 
    180  1.1  jmcneill 	for (n = 0; n < sc->sc_nctrl; n++) {
    181  1.1  jmcneill 		act8846_print(&sc->sc_ctrl[n]);
    182  1.1  jmcneill 	}
    183  1.1  jmcneill }
    184  1.1  jmcneill 
    185  1.1  jmcneill static int
    186  1.1  jmcneill act8846_read(struct act8846_softc *sc, uint8_t reg, uint8_t *val)
    187  1.1  jmcneill {
    188  1.6   thorpej 	return iic_smbus_read_byte(sc->sc_i2c, sc->sc_addr, reg, val, 0);
    189  1.1  jmcneill }
    190  1.1  jmcneill 
    191  1.1  jmcneill static int
    192  1.1  jmcneill act8846_write(struct act8846_softc *sc, uint8_t reg, uint8_t val)
    193  1.1  jmcneill {
    194  1.6   thorpej 	return iic_smbus_write_byte(sc->sc_i2c, sc->sc_addr, reg, val, 0);
    195  1.1  jmcneill }
    196  1.1  jmcneill 
    197  1.1  jmcneill static void
    198  1.1  jmcneill act8846_print(struct act8846_ctrl *c)
    199  1.1  jmcneill {
    200  1.1  jmcneill 	struct act8846_softc *sc = device_private(c->c_dev);
    201  1.1  jmcneill 	u_int voltage;
    202  1.1  jmcneill 	bool enabled;
    203  1.1  jmcneill 
    204  1.1  jmcneill 	device_printf(sc->sc_dev, "%s:", c->c_name);
    205  1.1  jmcneill 	if (act8846_get_voltage(c, &voltage)) {
    206  1.1  jmcneill 		printf(" [??? V]");
    207  1.1  jmcneill 	} else {
    208  1.1  jmcneill 		printf(" [%d.%03dV]", voltage / 1000,
    209  1.1  jmcneill 		    voltage % 1000);
    210  1.1  jmcneill 	}
    211  1.1  jmcneill 	if (act8846_is_enabled(c, &enabled)) {
    212  1.1  jmcneill 		printf(" [unknown state]");
    213  1.1  jmcneill 	} else {
    214  1.1  jmcneill 		printf(" [%s]", enabled ? "ON" : "OFF");
    215  1.1  jmcneill 	}
    216  1.1  jmcneill 	printf("\n");
    217  1.1  jmcneill }
    218  1.1  jmcneill 
    219  1.1  jmcneill struct act8846_ctrl *
    220  1.1  jmcneill act8846_lookup(device_t dev, const char *name)
    221  1.1  jmcneill {
    222  1.1  jmcneill 	struct act8846_softc *sc = device_private(dev);
    223  1.1  jmcneill 	struct act8846_ctrl *c;
    224  1.1  jmcneill 	u_int n;
    225  1.1  jmcneill 
    226  1.1  jmcneill 	for (n = 0; n < sc->sc_nctrl; n++) {
    227  1.1  jmcneill 		c = &sc->sc_ctrl[n];
    228  1.1  jmcneill 		if (strcmp(c->c_name, name) == 0) {
    229  1.1  jmcneill 			return c;
    230  1.1  jmcneill 		}
    231  1.1  jmcneill 	}
    232  1.1  jmcneill 
    233  1.1  jmcneill 	return NULL;
    234  1.1  jmcneill }
    235  1.1  jmcneill 
    236  1.1  jmcneill int
    237  1.1  jmcneill act8846_set_voltage(struct act8846_ctrl *c, u_int min, u_int max)
    238  1.1  jmcneill {
    239  1.1  jmcneill 	struct act8846_softc *sc = device_private(c->c_dev);
    240  1.1  jmcneill 	uint8_t val;
    241  1.1  jmcneill 	int error, n;
    242  1.1  jmcneill 
    243  1.1  jmcneill 	if (min < c->c_min || min > c->c_max || (min % 25) != 0)
    244  1.1  jmcneill 		return EINVAL;
    245  1.1  jmcneill 
    246  1.1  jmcneill 	for (n = 0; n < __arraycount(act8846_vset); n++) {
    247  1.1  jmcneill 		if (min >= act8846_vset[n] && max <= act8846_vset[n]) {
    248  1.1  jmcneill 			break;
    249  1.1  jmcneill 		}
    250  1.1  jmcneill 	}
    251  1.1  jmcneill 	if (n == __arraycount(act8846_vset))
    252  1.1  jmcneill 		return EINVAL;
    253  1.1  jmcneill 
    254  1.2  jmcneill 	val = __SHIFTIN(n, ACT_VSET_VSET);
    255  1.1  jmcneill 
    256  1.1  jmcneill 	iic_acquire_bus(sc->sc_i2c, 0);
    257  1.1  jmcneill 	error = act8846_write(sc, c->c_base + ACT_VSET0_OFFSET, val);
    258  1.1  jmcneill 	iic_release_bus(sc->sc_i2c, 0);
    259  1.1  jmcneill #ifdef ACT_DEBUG
    260  1.1  jmcneill 	if (error == 0)
    261  1.1  jmcneill 		act8846_print(c);
    262  1.1  jmcneill #endif
    263  1.1  jmcneill 	return error;
    264  1.1  jmcneill }
    265  1.1  jmcneill 
    266  1.1  jmcneill int
    267  1.1  jmcneill act8846_get_voltage(struct act8846_ctrl *c, u_int *pvol)
    268  1.1  jmcneill {
    269  1.1  jmcneill 	struct act8846_softc *sc = device_private(c->c_dev);
    270  1.1  jmcneill 	uint8_t val;
    271  1.1  jmcneill 	int error;
    272  1.1  jmcneill 
    273  1.1  jmcneill 	iic_acquire_bus(sc->sc_i2c, 0);
    274  1.1  jmcneill 	error = act8846_read(sc, c->c_base + ACT_VSET0_OFFSET, &val);
    275  1.1  jmcneill 	iic_release_bus(sc->sc_i2c, 0);
    276  1.1  jmcneill 	if (error)
    277  1.1  jmcneill 		return error;
    278  1.1  jmcneill 
    279  1.1  jmcneill 	*pvol = act8846_vset[__SHIFTOUT(val, ACT_VSET_VSET)];
    280  1.1  jmcneill 
    281  1.1  jmcneill 	return 0;
    282  1.1  jmcneill }
    283  1.1  jmcneill 
    284  1.1  jmcneill int
    285  1.1  jmcneill act8846_is_enabled(struct act8846_ctrl *c, bool *penabled)
    286  1.1  jmcneill {
    287  1.1  jmcneill 	struct act8846_softc *sc = device_private(c->c_dev);
    288  1.1  jmcneill 	uint8_t val, regoff, regmask;
    289  1.1  jmcneill 	int error;
    290  1.1  jmcneill 
    291  1.1  jmcneill 	if (c->c_type == ACT_CTRL_DCDC) {
    292  1.1  jmcneill 		regoff = ACT_DCDC_CTRL_OFFSET;
    293  1.1  jmcneill 		regmask = ACT_DCDC_CTRL_ON;
    294  1.1  jmcneill 	} else {
    295  1.1  jmcneill 		regoff = ACT_LDO_CTRL_OFFSET;
    296  1.1  jmcneill 		regmask = ACT_LDO_CTRL_ON;
    297  1.1  jmcneill 	}
    298  1.1  jmcneill 
    299  1.1  jmcneill 	iic_acquire_bus(sc->sc_i2c, 0);
    300  1.1  jmcneill 	error = act8846_read(sc, c->c_base + regoff, &val);
    301  1.1  jmcneill 	iic_release_bus(sc->sc_i2c, 0);
    302  1.1  jmcneill 	if (error)
    303  1.1  jmcneill 		return error;
    304  1.1  jmcneill 
    305  1.1  jmcneill 	*penabled = !!(val & regmask);
    306  1.1  jmcneill 	return 0;
    307  1.1  jmcneill }
    308  1.1  jmcneill 
    309  1.1  jmcneill int
    310  1.1  jmcneill act8846_enable(struct act8846_ctrl *c)
    311  1.1  jmcneill {
    312  1.1  jmcneill 	struct act8846_softc *sc = device_private(c->c_dev);
    313  1.1  jmcneill 	uint8_t val, regoff, regmask;
    314  1.1  jmcneill 	int error;
    315  1.1  jmcneill 
    316  1.1  jmcneill 	if (c->c_type == ACT_CTRL_DCDC) {
    317  1.1  jmcneill 		regoff = ACT_DCDC_CTRL_OFFSET;
    318  1.1  jmcneill 		regmask = ACT_DCDC_CTRL_ON;
    319  1.1  jmcneill 	} else {
    320  1.1  jmcneill 		regoff = ACT_LDO_CTRL_OFFSET;
    321  1.1  jmcneill 		regmask = ACT_LDO_CTRL_ON;
    322  1.1  jmcneill 	}
    323  1.1  jmcneill 
    324  1.1  jmcneill 	iic_acquire_bus(sc->sc_i2c, 0);
    325  1.1  jmcneill 	if ((error = act8846_read(sc, c->c_base + regoff, &val)) != 0)
    326  1.1  jmcneill 		goto done;
    327  1.1  jmcneill 	val |= regmask;
    328  1.1  jmcneill 	error = act8846_write(sc, c->c_base + regoff, val);
    329  1.1  jmcneill done:
    330  1.1  jmcneill 	iic_release_bus(sc->sc_i2c, 0);
    331  1.1  jmcneill #ifdef ACT_DEBUG
    332  1.1  jmcneill 	if (error == 0)
    333  1.1  jmcneill 		act8846_print(c);
    334  1.1  jmcneill #endif
    335  1.1  jmcneill 
    336  1.1  jmcneill 	return error;
    337  1.1  jmcneill }
    338  1.1  jmcneill 
    339  1.1  jmcneill int
    340  1.1  jmcneill act8846_disable(struct act8846_ctrl *c)
    341  1.1  jmcneill {
    342  1.1  jmcneill 	struct act8846_softc *sc = device_private(c->c_dev);
    343  1.1  jmcneill 	uint8_t val, regoff, regmask;
    344  1.1  jmcneill 	int error;
    345  1.1  jmcneill 
    346  1.1  jmcneill 	if (c->c_type == ACT_CTRL_DCDC) {
    347  1.1  jmcneill 		regoff = ACT_DCDC_CTRL_OFFSET;
    348  1.1  jmcneill 		regmask = ACT_DCDC_CTRL_ON;
    349  1.1  jmcneill 	} else {
    350  1.1  jmcneill 		regoff = ACT_LDO_CTRL_OFFSET;
    351  1.1  jmcneill 		regmask = ACT_LDO_CTRL_ON;
    352  1.1  jmcneill 	}
    353  1.1  jmcneill 
    354  1.1  jmcneill 	iic_acquire_bus(sc->sc_i2c, 0);
    355  1.1  jmcneill 	if ((error = act8846_read(sc, c->c_base + regoff, &val)) != 0)
    356  1.1  jmcneill 		goto done;
    357  1.1  jmcneill 	val &= ~regmask;
    358  1.1  jmcneill 	error = act8846_write(sc, c->c_base + regoff, val);
    359  1.1  jmcneill done:
    360  1.1  jmcneill 	iic_release_bus(sc->sc_i2c, 0);
    361  1.1  jmcneill #ifdef ACT_DEBUG
    362  1.1  jmcneill 	if (error == 0)
    363  1.1  jmcneill 		act8846_print(c);
    364  1.1  jmcneill #endif
    365  1.1  jmcneill 
    366  1.1  jmcneill 	return error;
    367  1.1  jmcneill }
    368