/* * L3 SA1111 algorithm/adapter module. * * By Russell King, * gratuitously ripped from sa1111-uda1341.c by John Dorsey. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include static inline unsigned char l3_sa1111_recv_byte(unsigned char addr) { unsigned char dat; L3_CAR = addr; while ((SASR0 & SASR0_L3RD) == 0) mdelay(1); dat = L3_CDR; SASCR = SASCR_RDD; return dat; } static void l3_sa1111_recv_msg(struct l3_msg *msg) { int len = msg->len; char *p = msg->buf; if (len > 1) { SACR1 |= SACR1_L3MB; while ((len--) > 1) *p++ = l3_sa1111_recv_byte(msg->addr); } SACR1 &= ~SACR1_L3MB; *p = l3_sa1111_recv_byte(msg->addr); } static inline void l3_sa1111_send_byte(unsigned char addr, unsigned char dat) { L3_CAR = addr; L3_CDR = dat; while ((SASR0 & SASR0_L3WD) == 0) mdelay(1); SASCR = SASCR_DTS; } static void l3_sa1111_send_msg(struct l3_msg *msg) { int len = msg->len; char *p = msg->buf; if (len > 1) { SACR1 |= SACR1_L3MB; while ((len--) > 1) l3_sa1111_send_byte(msg->addr, *p++); } SACR1 &= ~SACR1_L3MB; l3_sa1111_send_byte(msg->addr, *p); } static int l3_sa1111_xfer(struct l3_adapter *adap, struct l3_msg msgs[], int num) { int i; for (i = 0; i < num; i++) { struct l3_msg *pmsg = &msgs[i]; if (pmsg->flags & L3_M_RD) l3_sa1111_recv_msg(pmsg); else l3_sa1111_send_msg(pmsg); } return num; } static struct l3_algorithm l3_sa1111_algo = { name: "L3 SA1111 algorithm", xfer: l3_sa1111_xfer, }; static DECLARE_MUTEX(sa1111_lock); static struct l3_adapter l3_sa1111_adapter = { owner: THIS_MODULE, name: "l3-sa1111", algo: &l3_sa1111_algo, lock: &sa1111_lock, }; static int __init l3_sa1111_init(void) { int ret = -ENODEV; if ((machine_is_assabet() && machine_has_neponset()) || machine_is_jornada720()) ret = l3_add_adapter(&l3_sa1111_adapter); return ret; } static void __exit l3_sa1111_exit(void) { l3_del_adapter(&l3_sa1111_adapter); } module_init(l3_sa1111_init); module_exit(l3_sa1111_exit);