1 /* $NetBSD: teliosio.c,v 1.2 2005/12/11 12:17:33 christos Exp $ */
4 * Copyright (c) 2005 Takeshi Nakayama.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * Sharp Telios machine dependent I/O (LCD backlight/Battery unit) driver
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: teliosio.c,v 1.2 2005/12/11 12:17:33 christos Exp $");
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/device.h>
41 #include <machine/bus.h>
42 #include <machine/config_hook.h>
44 #include <hpcmips/tx/tx39var.h>
45 #include <hpcmips/tx/txcsbusvar.h>
48 #include <dev/apm/apmbios.h>
49 #define __TX39IO_PRIVATE
50 #include <hpcmips/tx/tx39ioreg.h>
51 #include <hpcmips/tx/tx39timerreg.h>
54 #include <hpcmips/dev/teliosioreg.h>
56 struct teliosio_softc
{
58 tx_chipset_tag_t sc_tc
;
59 bus_space_tag_t sc_regt
;
60 bus_space_handle_t sc_regh
;
64 #define MAX_BRIGHTNESS 9
65 #define BRIGHTNESSVAL(n) \
66 ((n) <= 0 ? 0 : ((n) <= MAX_BRIGHTNESS ? (n) : MAX_BRIGHTNESS) * 9 - 1)
69 static int teliosio_match(struct device
*, struct cfdata
*, void *);
70 static void teliosio_attach(struct device
*, struct device
*, void *);
71 static int teliosio_event(void *, int, long, void *);
73 /* LCD backlight control */
74 static void teliosio_backlight(struct teliosio_softc
*, int);
75 static void teliosio_brightness(struct teliosio_softc
*, int);
77 /* Battery unit control */
79 static int teliosio_ac_state(struct teliosio_softc
*);
80 static int teliosio_mbu_state(struct teliosio_softc
*);
81 static void teliosio_mbu_write(tx_chipset_tag_t
, int);
82 static int teliosio_mbu_read(tx_chipset_tag_t
);
85 CFATTACH_DECL(teliosio
, sizeof(struct teliosio_softc
),
86 teliosio_match
, teliosio_attach
, NULL
, NULL
);
89 teliosio_match(struct device
*parent
, struct cfdata
*cf
, void *aux
)
92 return 2; /* attach before plumvideo */
96 teliosio_attach(struct device
*parent
, struct device
*self
, void *aux
)
98 struct cs_attach_args
*ca
= aux
;
99 struct teliosio_softc
*sc
= (void *)self
;
101 sc
->sc_tc
= ca
->ca_tc
;
102 sc
->sc_regt
= ca
->ca_csreg
.cstag
;
104 if (bus_space_map(sc
->sc_regt
, TELIOSIO_REGBASE
, TELIOSIO_REGSIZE
,
106 printf(": register map failed\n");
111 sc
->sc_backlight
= 1;
112 sc
->sc_brightness
= MAX_BRIGHTNESS
;
114 config_hook(CONFIG_HOOK_SET
, CONFIG_HOOK_POWER_LCDLIGHT
,
115 CONFIG_HOOK_SHARE
, teliosio_event
, sc
);
116 config_hook(CONFIG_HOOK_GET
, CONFIG_HOOK_POWER_LCDLIGHT
,
117 CONFIG_HOOK_SHARE
, teliosio_event
, sc
);
118 config_hook(CONFIG_HOOK_SET
, CONFIG_HOOK_BRIGHTNESS
,
119 CONFIG_HOOK_SHARE
, teliosio_event
, sc
);
120 config_hook(CONFIG_HOOK_GET
, CONFIG_HOOK_BRIGHTNESS
,
121 CONFIG_HOOK_SHARE
, teliosio_event
, sc
);
122 config_hook(CONFIG_HOOK_GET
, CONFIG_HOOK_BRIGHTNESS_MAX
,
123 CONFIG_HOOK_SHARE
, teliosio_event
, sc
);
125 config_hook(CONFIG_HOOK_GET
, CONFIG_HOOK_ACADAPTER
,
126 CONFIG_HOOK_SHARE
, teliosio_event
, sc
);
127 config_hook(CONFIG_HOOK_GET
, CONFIG_HOOK_BATTERYVAL
,
128 CONFIG_HOOK_SHARE
, teliosio_event
, sc
);
133 teliosio_event(void *ctx
, int type
, long id
, void *msg
)
135 struct teliosio_softc
*sc
= ctx
;
138 case CONFIG_HOOK_SET
:
140 case CONFIG_HOOK_POWER_LCDLIGHT
:
141 teliosio_backlight(sc
, (int)msg
);
143 case CONFIG_HOOK_BRIGHTNESS
:
144 teliosio_brightness(sc
, *(int *)msg
+ 1);
150 case CONFIG_HOOK_GET
:
152 case CONFIG_HOOK_POWER_LCDLIGHT
:
153 *(int *)msg
= sc
->sc_backlight
;
155 case CONFIG_HOOK_BRIGHTNESS
:
156 *(int *)msg
= sc
->sc_brightness
- 1;
158 case CONFIG_HOOK_BRIGHTNESS_MAX
:
159 *(int *)msg
= MAX_BRIGHTNESS
- 1;
162 case CONFIG_HOOK_ACADAPTER
:
163 *(int *)msg
= teliosio_ac_state(sc
);
165 case CONFIG_HOOK_BATTERYVAL
:
166 *(int *)msg
= teliosio_mbu_state(sc
) / 2;
181 * LCD backlight control
184 teliosio_backlight(struct teliosio_softc
*sc
, int on
)
188 sc
->sc_backlight
= on
;
190 teliosio_brightness(sc
, sc
->sc_brightness
);
192 brightness
= sc
->sc_brightness
;
193 teliosio_brightness(sc
, 0);
194 sc
->sc_brightness
= brightness
;
199 teliosio_brightness(struct teliosio_softc
*sc
, int val
)
201 bus_space_tag_t regt
= sc
->sc_regt
;
202 bus_space_handle_t regh
= sc
->sc_regh
;
207 else if (val
> MAX_BRIGHTNESS
)
208 val
= MAX_BRIGHTNESS
;
209 sc
->sc_brightness
= val
;
211 period
= bus_space_read_2(regt
, regh
, TELIOSIO_BACKLIGHT_PERIOD
);
213 period
|= TELIOSIO_BACKLIGHT_PERIOD_EN
;
215 period
&= ~TELIOSIO_BACKLIGHT_PERIOD_EN
;
216 bus_space_write_2(regt
, regh
, TELIOSIO_BACKLIGHT_PERIOD
, period
);
217 bus_space_write_2(regt
, regh
, TELIOSIO_BACKLIGHT_RESET
,
222 * Battery unit control
226 teliosio_ac_state(struct teliosio_softc
*sc
)
228 tx_chipset_tag_t tc
= sc
->sc_tc
;
231 reg
= tx_conf_read(tc
, TX392X_IODATAINOUT_REG
);
232 return (reg
& TELIOSIO_AC_STATE
) ? APM_AC_OFF
: APM_AC_ON
;
236 teliosio_mbu_state(struct teliosio_softc
*sc
)
238 tx_chipset_tag_t tc
= sc
->sc_tc
;
241 teliosio_mbu_write(tc
, 0x00);
243 val
= teliosio_mbu_read(tc
);
249 #define WAIT (1000000 / TELIOSIO_BMU_CLOCK_FREQ / 2)
252 teliosio_mbu_write(tx_chipset_tag_t tc
, int val
)
258 for (mask
= 0x80; mask
!= 0; mask
>>= 1) {
260 reg
= tx_conf_read(tc
, TX392X_IODATAINOUT_REG
);
261 reg
|= TELIOSIO_BMU_CLOCK
;
263 reg
|= TELIOSIO_BMU_DATAOUT
;
265 reg
&= ~TELIOSIO_BMU_DATAOUT
;
266 tx_conf_write(tc
, TX392X_IODATAINOUT_REG
, reg
);
271 reg
= tx_conf_read(tc
, TX392X_IODATAINOUT_REG
);
272 reg
&= ~TELIOSIO_BMU_CLOCK
;
273 tx_conf_write(tc
, TX392X_IODATAINOUT_REG
, reg
);
280 teliosio_mbu_read(tx_chipset_tag_t tc
)
287 for (mask
= 0x80; mask
!= 0; mask
>>= 1) {
289 reg
= tx_conf_read(tc
, TX392X_IODATAINOUT_REG
);
290 reg
|= TELIOSIO_BMU_CLOCK
;
291 tx_conf_write(tc
, TX392X_IODATAINOUT_REG
, reg
);
296 reg
= tx_conf_read(tc
, TX392X_IODATAINOUT_REG
);
297 if (!(reg
& TELIOSIO_BMU_DATAIN
))
299 reg
&= ~TELIOSIO_BMU_CLOCK
;
300 tx_conf_write(tc
, TX392X_IODATAINOUT_REG
, reg
);