1 #include <lunaix/device.h>
2 #include <lunaix/mm/valloc.h>
3 #include <lunaix/spike.h>
4 #include <lunaix/owloysius.h>
5 #include <lunaix/status.h>
6 #include <lunaix/syslog.h>
8 #include <asm/pagetable.h>
10 #include <hal/serial.h>
14 #define lock_sdev(sdev) device_lock((sdev)->dev)
15 #define unlock_sdev(sdev) device_unlock((sdev)->dev)
16 #define unlock_and_wait(sdev, wq) \
23 static DEFINE_LLIST(serial_devs);
24 static int serial_idx = 0;
26 static struct device_cat* serial_cat;
28 #define serial_device(dev) ((struct serial_dev*)(dev)->underlay)
31 serial_accept_one(struct serial_dev* sdev, u8_t val)
33 return !!rbuffer_put(&sdev->rxbuf, val);
37 serial_accept_buffer(struct serial_dev* sdev, void* val, size_t len)
39 return !!rbuffer_puts(&sdev->rxbuf, val, len);
43 serial_end_recv(struct serial_dev* sdev)
45 mark_device_done_read(sdev->dev);
47 pwake_one(&sdev->wq_rxdone);
49 term_notify_data_avaliable(sdev->tp_cap);
53 serial_end_xmit(struct serial_dev* sdev, size_t len)
55 mark_device_done_write(sdev->dev);
58 pwake_one(&sdev->wq_txdone);
62 serial_readone_nowait(struct serial_dev* sdev, u8_t* val)
66 int rd_len = rbuffer_get(&sdev->rxbuf, (char*)val);
74 serial_readone(struct serial_dev* sdev, u8_t* val)
78 mark_device_doing_read(sdev->dev);
80 while (!rbuffer_get(&sdev->rxbuf, (char*)val)) {
81 unlock_and_wait(sdev, wq_rxdone);
88 serial_readbuf(struct serial_dev* sdev, u8_t* buf, size_t len)
92 mark_device_doing_read(sdev->dev);
95 while (!(rdlen = rbuffer_gets(&sdev->rxbuf, (char*)buf, len))) {
96 unlock_and_wait(sdev, wq_rxdone);
105 serial_readbuf_nowait(struct serial_dev* sdev, u8_t* buf, size_t len)
109 mark_device_doing_read(sdev->dev);
111 int rdlen = rbuffer_gets(&sdev->rxbuf, (char*)buf, len);
119 serial_writebuf(struct serial_dev* sdev, u8_t* buf, size_t len)
123 mark_device_doing_write(sdev->dev);
125 if (sdev->write(sdev, buf, len) == RXTX_DONE) {
129 unlock_and_wait(sdev, wq_txdone);
132 int rdlen = sdev->wr_len;
139 serial_writebuf_nowait(struct serial_dev* sdev, u8_t* buf, size_t len)
143 mark_device_doing_write(sdev->dev);
145 sdev->write(sdev, buf, len);
146 int rdlen = sdev->wr_len;
154 __serial_read(struct device* dev, void* buf, off_t fpos, size_t len)
156 return serial_readbuf(serial_device(dev), (u8_t*)buf, len);
160 __serial_read_async(struct device* dev, void* buf, off_t fpos, size_t len)
162 return serial_readbuf_nowait(
163 serial_device(dev), (u8_t*)buf, len);
167 __serial_read_page(struct device* dev, void* buf, off_t fpos)
169 return serial_readbuf(serial_device(dev), (u8_t*)buf, PAGE_SIZE);
173 __serial_write(struct device* dev, void* buf, off_t fpos, size_t len)
175 return serial_writebuf(serial_device(dev), (u8_t*)buf, len);
179 __serial_write_async(struct device* dev, void* buf, off_t fpos, size_t len)
181 return serial_writebuf_nowait(
182 serial_device(dev), (u8_t*)buf, len);
186 __serial_write_page(struct device* dev, void* buf, off_t fpos)
188 return serial_writebuf(serial_device(dev), (u8_t*)buf, PAGE_SIZE);
192 __serial_exec_command(struct device* dev, u32_t req, va_list args)
194 struct serial_dev* sdev = serial_device(dev);
196 if (!sdev->exec_cmd) {
200 return sdev->exec_cmd(sdev, req, args);
204 __serial_poll_event(struct device* dev)
206 struct serial_dev* sdev = serial_device(dev);
208 return sdev->dev->poll_evflags;
211 static void sdev_execmd(struct serial_dev* sdev, u32_t req, ...)
216 sdev->exec_cmd(sdev, req, args);
222 __serial_set_speed(struct device* dev, speed_t speed)
224 struct serial_dev* sdev = serial_device(dev);
227 sdev_execmd(sdev, SERIO_SETBRDRATE, speed);
233 __serial_set_baseclk(struct device* dev, unsigned int base)
235 struct serial_dev* sdev = serial_device(dev);
238 sdev_execmd(sdev, SERIO_SETBRDBASE, base);
244 __serial_set_cntrl_mode(struct device* dev, tcflag_t cflag)
246 struct serial_dev* sdev = serial_device(dev);
249 sdev_execmd(sdev, SERIO_SETCNTRLMODE, cflag);
254 #define RXBUF_SIZE 512
256 static struct termport_pot_ops tppot_ops = {
257 .set_cntrl_mode = __serial_set_cntrl_mode,
258 .set_clkbase = __serial_set_baseclk,
259 .set_speed = __serial_set_speed
263 serial_create(struct devclass* class, char* if_ident)
265 struct serial_dev* sdev;
268 sdev = vzalloc(sizeof(struct serial_dev));
269 dev = device_allocseq(dev_meta(serial_cat), sdev);
271 dev->ops.read = __serial_read;
272 dev->ops.read_page = __serial_read_page;
273 dev->ops.read_async = __serial_read_async;
274 dev->ops.write_async = __serial_write_async;
275 dev->ops.write = __serial_write;
276 dev->ops.write_page = __serial_write_page;
277 dev->ops.exec_cmd = __serial_exec_command;
278 dev->ops.poll = __serial_poll_event;
281 dev->underlay = sdev;
283 waitq_init(&sdev->wq_rxdone);
284 waitq_init(&sdev->wq_txdone);
285 rbuffer_init(&sdev->rxbuf, valloc(RXBUF_SIZE), RXBUF_SIZE);
286 llist_append(&serial_devs, &sdev->sdev_list);
288 register_device_var(dev, class, "%s", if_ident);
290 INFO("interface: %s, %xh:%xh.%d", dev->name_val,
291 class->fn_grp, class->device, class->variant);
293 sdev->tp_cap = term_attach_potens(dev, &tppot_ops, if_ident);
299 serial_get_avilable()
301 struct serial_dev *pos, *n;
302 llist_for_each(pos, n, &serial_devs, sdev_list)
304 if (!device_locked(pos->dev)) {
315 serial_cat = device_addcat(NULL, "serial");
319 owloysius_fetch_init(init_serial_dev, on_earlyboot)