Module Name: src Committed By: khorben Date: Sun Apr 14 19:17:06 UTC 2013
Modified Files: src/sys/arch/evbarm/conf: N900 files.n900 Added Files: src/sys/arch/evbarm/n900: n900_acad.c Log Message: Imported n900acad(4), a driver for the Nokia N900 reporting the charging status through sysmon_envsys(9). XXX need a better way to locate the interrupt (documented) To generate a diff of this commit: cvs rdiff -u -r1.7 -r1.8 src/sys/arch/evbarm/conf/N900 cvs rdiff -u -r1.1 -r1.2 src/sys/arch/evbarm/conf/files.n900 cvs rdiff -u -r0 -r1.1 src/sys/arch/evbarm/n900/n900_acad.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/evbarm/conf/N900 diff -u src/sys/arch/evbarm/conf/N900:1.7 src/sys/arch/evbarm/conf/N900:1.8 --- src/sys/arch/evbarm/conf/N900:1.7 Wed Mar 13 03:08:18 2013 +++ src/sys/arch/evbarm/conf/N900 Sun Apr 14 19:17:06 2013 @@ -1,5 +1,5 @@ # -# $NetBSD: N900,v 1.7 2013/03/13 03:08:18 khorben Exp $ +# $NetBSD: N900,v 1.8 2013/04/14 19:17:06 khorben Exp $ # # N900 -- Nokia N900 Kernel # @@ -213,6 +213,10 @@ omapgpio4 at obio2 addr 0x49056000 size gpio* at omapgpio? +# GPIO devices +# Charging sensor +n900acad0 at gpio0 offset 7 mask 0x1 #intr 103 + # System Control Module omapscm0 at obio0 addr 0x48002000 size 0x1000 Index: src/sys/arch/evbarm/conf/files.n900 diff -u src/sys/arch/evbarm/conf/files.n900:1.1 src/sys/arch/evbarm/conf/files.n900:1.2 --- src/sys/arch/evbarm/conf/files.n900:1.1 Sun Apr 14 18:57:32 2013 +++ src/sys/arch/evbarm/conf/files.n900 Sun Apr 14 19:17:06 2013 @@ -1,4 +1,4 @@ -# $NetBSD: files.n900,v 1.1 2013/04/14 18:57:32 khorben Exp $ +# $NetBSD: files.n900,v 1.2 2013/04/14 19:17:06 khorben Exp $ # # Nokia N900 configuration info # @@ -19,3 +19,8 @@ include "arch/arm/omap/files.omap2" attach com at obio with obiouart file arch/arm/omap/obio_com.c obiouart defparam opt_com.h CONSADDR CONSPEED CONMODE + +# Charging sensor +device n900acad: sysmon_envsys +attach n900acad at gpio with n900acad +file arch/evbarm/n900/n900_acad.c n900acad Added files: Index: src/sys/arch/evbarm/n900/n900_acad.c diff -u /dev/null src/sys/arch/evbarm/n900/n900_acad.c:1.1 --- /dev/null Sun Apr 14 19:17:06 2013 +++ src/sys/arch/evbarm/n900/n900_acad.c Sun Apr 14 19:17:06 2013 @@ -0,0 +1,171 @@ +/* $NetBSD: n900_acad.c,v 1.1 2013/04/14 19:17:06 khorben Exp $ */ + +/* + * AC adapter driver for the Nokia N900. + * + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Pierre Pronchery (khor...@defora.org). + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: n900_acad.c,v 1.1 2013/04/14 19:17:06 khorben Exp $"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/device.h> +#include <sys/gpio.h> + +#include <dev/gpio/gpiovar.h> +#include <dev/sysmon/sysmonvar.h> + +#include <arm/omap/omap2_gpio.h> + + +/* The base interrupt for the corresponding GPIO device where this driver + * attaches. This is an ugly workaround the current limitations of gpio(4), + * which does not seem to allow a better way to locate the interrupt yet. */ +#define N900ACAD_GPIO_BASE 96 + +#define N900ACAD_PIN_INPUT 0 +#define N900ACAD_NPINS 1 + + +struct n900acad_softc +{ + device_t sc_dev; + void * sc_gpio; + void * sc_intr; + + struct gpio_pinmap sc_map; + int sc_map_pins[N900ACAD_NPINS]; + + struct sysmon_pswitch sc_smpsw; +}; + +static int n900acad_match(device_t, cfdata_t, void *); +static void n900acad_attach(device_t, device_t, void *); +static int n900acad_detach(device_t, int); + +CFATTACH_DECL_NEW(n900acad, sizeof(struct n900acad_softc), + n900acad_match, n900acad_attach, n900acad_detach, NULL); + +static int n900acad_intr(void *v); + + +static int +n900acad_match(device_t parent, cfdata_t cf, void * aux) +{ + struct gpio_attach_args *ga = aux; + + if (strcmp(ga->ga_dvname, cf->cf_name)) + return 0; + + if (ga->ga_offset == -1) + return 0; + + /* check that we have enough pins */ + if (gpio_npins(ga->ga_mask) != N900ACAD_NPINS) { + aprint_debug("%s: invalid pin mask 0x%02x\n", cf->cf_name, + ga->ga_mask); + return 0; + } + + return 1; +} + +static void +n900acad_attach(device_t parent, device_t self, void *aux) +{ + struct n900acad_softc *sc = device_private(self); + struct gpio_attach_args *ga = aux; + int caps; + + sc->sc_dev = self; + sc->sc_gpio = ga->ga_gpio; + + /* map pins */ + sc->sc_map.pm_map = sc->sc_map_pins; + if (gpio_pin_map(sc->sc_gpio, ga->ga_offset, ga->ga_mask, + &sc->sc_map)) { + aprint_error(": can't map pins\n"); + return; + } + + /* configure the input pin */ + caps = gpio_pin_caps(sc->sc_gpio, &sc->sc_map, N900ACAD_PIN_INPUT); + if (!(caps & GPIO_PIN_INPUT)) { + aprint_error(": pin is unable to read input\n"); + gpio_pin_unmap(sc->sc_gpio, &sc->sc_map); + return; + } + gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, N900ACAD_PIN_INPUT, + GPIO_PIN_INPUT); + + sc->sc_intr = intr_establish(N900ACAD_GPIO_BASE + ga->ga_offset, + IST_EDGE_BOTH, IPL_VM, n900acad_intr, sc); + if (sc->sc_intr == NULL) { + aprint_error(": could not establish interrupt\n"); + return; + } + + aprint_normal("N900 keyboard acad\n"); + aprint_naive("N900 keyboard acad\n"); + + if (!pmf_device_register(sc->sc_dev, NULL, NULL)) + aprint_error_dev(sc->sc_dev, + "could not establish power handler\n"); + + sc->sc_smpsw.smpsw_name = device_xname(self); + sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_ACADAPTER; + sysmon_pswitch_register(&sc->sc_smpsw); +} + +static int +n900acad_detach(device_t self, int flags) +{ + struct n900acad_softc *sc = device_private(self); + + if (sc->sc_intr != NULL) { + intr_disestablish(sc->sc_intr); + } + + gpio_pin_unmap(sc->sc_gpio, &sc->sc_map); + pmf_device_deregister(self); + return 0; +} + +static int +n900acad_intr(void *v) +{ + struct n900acad_softc *sc = v; + int i; + + i = gpio_pin_read(sc->sc_gpio, &sc->sc_map, N900ACAD_PIN_INPUT); + sysmon_pswitch_event(&sc->sc_smpsw, + i ? PSWITCH_EVENT_RELEASED : PSWITCH_EVENT_PRESSED); + return 1; +}