7 #include <linux/module.h>
8 #include <linux/errno.h>
11 #include <linux/slab.h>
20 #include <asm/openprom.h>
21 #include <asm/oplib.h>
24 #include <asm/pgtable.h>
26 #define UCTRL_MINOR 174
30 #define dprintk(x) printk x
59 #define UCTRL_INTR_TXE_REQ 0x01
60 #define UCTRL_INTR_TXNF_REQ 0x02
61 #define UCTRL_INTR_RXNE_REQ 0x04
62 #define UCTRL_INTR_RXO_REQ 0x08
63 #define UCTRL_INTR_TXE_MSK 0x10
64 #define UCTRL_INTR_TXNF_MSK 0x20
65 #define UCTRL_INTR_RXNE_MSK 0x40
66 #define UCTRL_INTR_RXO_MSK 0x80
69 #define UCTRL_STAT_TXE_STA 0x01
70 #define UCTRL_STAT_TXNF_STA 0x02
71 #define UCTRL_STAT_RXNE_STA 0x04
72 #define UCTRL_STAT_RXO_STA 0x08
75 static const char *uctrl_extstatus[16] = {
76 "main power available",
77 "internal battery attached",
78 "external battery attached",
79 "external VGA attached",
80 "external keyboard attached",
81 "external mouse attached",
83 "internal battery currently charging",
84 "external battery currently charging",
85 "internal battery currently discharging",
86 "external battery currently discharging",
190 static struct uctrl_driver {
197 static void uctrl_get_event_status(
struct uctrl_driver *);
198 static void uctrl_get_external_status(
struct uctrl_driver *);
201 uctrl_ioctl(
struct file *
file,
unsigned int cmd,
unsigned long arg)
211 uctrl_open(
struct inode *
inode,
struct file *file)
214 uctrl_get_event_status(global_driver);
215 uctrl_get_external_status(global_driver);
228 .unlocked_ioctl = uctrl_ioctl,
239 #define WRITEUCTLDATA(value) \
242 for (i = 0; i < 10000; i++) { \
243 if (UCTRL_STAT_TXNF_STA & sbus_readl(&driver->regs->uctrl_stat)) \
246 dprintk(("write data 0x%02x\n", value)); \
247 sbus_writel(value, &driver->regs->uctrl_data); \
251 #define READUCTLDATA(value) \
255 for (i = 0; i < 10000; i++) { \
256 if ((UCTRL_STAT_RXNE_STA & sbus_readl(&driver->regs->uctrl_stat)) == 0) \
260 value = sbus_readl(&driver->regs->uctrl_data); \
261 dprintk(("read data 0x%02x\n", value)); \
262 sbus_writel(UCTRL_STAT_RXNE_STA, &driver->regs->uctrl_stat); \
265 static void uctrl_do_txn(
struct uctrl_driver *
driver,
struct uctrl_txn *txn)
274 dprintk((
"interrupt stat 0x%x int 0x%x\n", stat, intr));
278 byte = (txn->
opcode << 8);
291 dprintk((
"ack was %x\n", (byte >> 8)));
297 dprintk((
"set byte to %02x\n", byte));
303 static void uctrl_get_event_status(
struct uctrl_driver *
driver)
314 uctrl_do_txn(driver, &txn);
316 dprintk((
"bytes %x %x\n", (outbits[0] & 0xff), (outbits[1] & 0xff)));
317 driver->status.event_status =
318 ((outbits[0] & 0xff) << 8) | (outbits[1] & 0xff);
319 dprintk((
"ev is %x\n", driver->status.event_status));
322 static void uctrl_get_external_status(
struct uctrl_driver *driver)
334 uctrl_do_txn(driver, &txn);
336 dprintk((
"bytes %x %x\n", (outbits[0] & 0xff), (outbits[1] & 0xff)));
337 driver->status.external_status =
338 ((outbits[0] * 256) + (outbits[1]));
339 dprintk((
"ex is %x\n", driver->status.external_status));
340 v = driver->status.external_status;
341 for (i = 0; v != 0; i++, v >>= 1) {
343 dprintk((
"%s%s",
" ", uctrl_extstatus[i]));
352 struct uctrl_driver *
p;
370 err =
request_irq(p->irq, uctrl_interrupt, 0,
"uctrl", p);
384 op->
dev.of_node->full_name, p->regs, p->irq);
385 uctrl_get_event_status(p);
386 uctrl_get_external_status(p);
430 .of_match_table = uctrl_match,
432 .probe = uctrl_probe,