1645194c7SYoshinori Sato /*
2645194c7SYoshinori Sato * Renesas Serial Communication Interface
3645194c7SYoshinori Sato *
4645194c7SYoshinori Sato * Datasheet: RX62N Group, RX621 Group User's Manual: Hardware
5645194c7SYoshinori Sato * (Rev.1.40 R01UH0033EJ0140)
6645194c7SYoshinori Sato *
7645194c7SYoshinori Sato * Copyright (c) 2019 Yoshinori Sato
8645194c7SYoshinori Sato *
9645194c7SYoshinori Sato * SPDX-License-Identifier: GPL-2.0-or-later
10645194c7SYoshinori Sato *
11645194c7SYoshinori Sato * This program is free software; you can redistribute it and/or modify it
12645194c7SYoshinori Sato * under the terms and conditions of the GNU General Public License,
13645194c7SYoshinori Sato * version 2 or later, as published by the Free Software Foundation.
14645194c7SYoshinori Sato *
15645194c7SYoshinori Sato * This program is distributed in the hope it will be useful, but WITHOUT
16645194c7SYoshinori Sato * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17645194c7SYoshinori Sato * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18645194c7SYoshinori Sato * more details.
19645194c7SYoshinori Sato *
20645194c7SYoshinori Sato * You should have received a copy of the GNU General Public License along with
21645194c7SYoshinori Sato * this program. If not, see <http://www.gnu.org/licenses/>.
22645194c7SYoshinori Sato */
23645194c7SYoshinori Sato
24645194c7SYoshinori Sato #include "qemu/osdep.h"
25645194c7SYoshinori Sato #include "qemu/log.h"
26645194c7SYoshinori Sato #include "hw/irq.h"
27645194c7SYoshinori Sato #include "hw/registerfields.h"
28645194c7SYoshinori Sato #include "hw/qdev-properties.h"
29ce35e229SEduardo Habkost #include "hw/qdev-properties-system.h"
30645194c7SYoshinori Sato #include "hw/char/renesas_sci.h"
31645194c7SYoshinori Sato #include "migration/vmstate.h"
32645194c7SYoshinori Sato
33645194c7SYoshinori Sato /* SCI register map */
34645194c7SYoshinori Sato REG8(SMR, 0)
35645194c7SYoshinori Sato FIELD(SMR, CKS, 0, 2)
36645194c7SYoshinori Sato FIELD(SMR, MP, 2, 1)
37645194c7SYoshinori Sato FIELD(SMR, STOP, 3, 1)
38645194c7SYoshinori Sato FIELD(SMR, PM, 4, 1)
39645194c7SYoshinori Sato FIELD(SMR, PE, 5, 1)
40645194c7SYoshinori Sato FIELD(SMR, CHR, 6, 1)
41645194c7SYoshinori Sato FIELD(SMR, CM, 7, 1)
42645194c7SYoshinori Sato REG8(BRR, 1)
43645194c7SYoshinori Sato REG8(SCR, 2)
44645194c7SYoshinori Sato FIELD(SCR, CKE, 0, 2)
45645194c7SYoshinori Sato FIELD(SCR, TEIE, 2, 1)
46645194c7SYoshinori Sato FIELD(SCR, MPIE, 3, 1)
47645194c7SYoshinori Sato FIELD(SCR, RE, 4, 1)
48645194c7SYoshinori Sato FIELD(SCR, TE, 5, 1)
49645194c7SYoshinori Sato FIELD(SCR, RIE, 6, 1)
50645194c7SYoshinori Sato FIELD(SCR, TIE, 7, 1)
51645194c7SYoshinori Sato REG8(TDR, 3)
52645194c7SYoshinori Sato REG8(SSR, 4)
53645194c7SYoshinori Sato FIELD(SSR, MPBT, 0, 1)
54645194c7SYoshinori Sato FIELD(SSR, MPB, 1, 1)
55645194c7SYoshinori Sato FIELD(SSR, TEND, 2, 1)
56645194c7SYoshinori Sato FIELD(SSR, ERR, 3, 3)
57645194c7SYoshinori Sato FIELD(SSR, PER, 3, 1)
58645194c7SYoshinori Sato FIELD(SSR, FER, 4, 1)
59645194c7SYoshinori Sato FIELD(SSR, ORER, 5, 1)
60645194c7SYoshinori Sato FIELD(SSR, RDRF, 6, 1)
61645194c7SYoshinori Sato FIELD(SSR, TDRE, 7, 1)
62645194c7SYoshinori Sato REG8(RDR, 5)
63645194c7SYoshinori Sato REG8(SCMR, 6)
64645194c7SYoshinori Sato FIELD(SCMR, SMIF, 0, 1)
65645194c7SYoshinori Sato FIELD(SCMR, SINV, 2, 1)
66645194c7SYoshinori Sato FIELD(SCMR, SDIR, 3, 1)
67645194c7SYoshinori Sato FIELD(SCMR, BCP2, 7, 1)
68645194c7SYoshinori Sato REG8(SEMR, 7)
69645194c7SYoshinori Sato FIELD(SEMR, ACS0, 0, 1)
70645194c7SYoshinori Sato FIELD(SEMR, ABCS, 4, 1)
71645194c7SYoshinori Sato
can_receive(void * opaque)72645194c7SYoshinori Sato static int can_receive(void *opaque)
73645194c7SYoshinori Sato {
74645194c7SYoshinori Sato RSCIState *sci = RSCI(opaque);
75645194c7SYoshinori Sato if (sci->rx_next > qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)) {
76645194c7SYoshinori Sato return 0;
77645194c7SYoshinori Sato } else {
78645194c7SYoshinori Sato return FIELD_EX8(sci->scr, SCR, RE);
79645194c7SYoshinori Sato }
80645194c7SYoshinori Sato }
81645194c7SYoshinori Sato
receive(void * opaque,const uint8_t * buf,int size)82645194c7SYoshinori Sato static void receive(void *opaque, const uint8_t *buf, int size)
83645194c7SYoshinori Sato {
84645194c7SYoshinori Sato RSCIState *sci = RSCI(opaque);
85645194c7SYoshinori Sato sci->rx_next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + sci->trtime;
86645194c7SYoshinori Sato if (FIELD_EX8(sci->ssr, SSR, RDRF) || size > 1) {
87645194c7SYoshinori Sato sci->ssr = FIELD_DP8(sci->ssr, SSR, ORER, 1);
88645194c7SYoshinori Sato if (FIELD_EX8(sci->scr, SCR, RIE)) {
89645194c7SYoshinori Sato qemu_set_irq(sci->irq[ERI], 1);
90645194c7SYoshinori Sato }
91645194c7SYoshinori Sato } else {
92645194c7SYoshinori Sato sci->rdr = buf[0];
93645194c7SYoshinori Sato sci->ssr = FIELD_DP8(sci->ssr, SSR, RDRF, 1);
94645194c7SYoshinori Sato if (FIELD_EX8(sci->scr, SCR, RIE)) {
95645194c7SYoshinori Sato qemu_irq_pulse(sci->irq[RXI]);
96645194c7SYoshinori Sato }
97645194c7SYoshinori Sato }
98645194c7SYoshinori Sato }
99645194c7SYoshinori Sato
send_byte(RSCIState * sci)100645194c7SYoshinori Sato static void send_byte(RSCIState *sci)
101645194c7SYoshinori Sato {
102645194c7SYoshinori Sato if (qemu_chr_fe_backend_connected(&sci->chr)) {
103645194c7SYoshinori Sato qemu_chr_fe_write_all(&sci->chr, &sci->tdr, 1);
104645194c7SYoshinori Sato }
105645194c7SYoshinori Sato timer_mod(&sci->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + sci->trtime);
106645194c7SYoshinori Sato sci->ssr = FIELD_DP8(sci->ssr, SSR, TEND, 0);
107645194c7SYoshinori Sato sci->ssr = FIELD_DP8(sci->ssr, SSR, TDRE, 1);
108645194c7SYoshinori Sato qemu_set_irq(sci->irq[TEI], 0);
109645194c7SYoshinori Sato if (FIELD_EX8(sci->scr, SCR, TIE)) {
110645194c7SYoshinori Sato qemu_irq_pulse(sci->irq[TXI]);
111645194c7SYoshinori Sato }
112645194c7SYoshinori Sato }
113645194c7SYoshinori Sato
txend(void * opaque)114645194c7SYoshinori Sato static void txend(void *opaque)
115645194c7SYoshinori Sato {
116645194c7SYoshinori Sato RSCIState *sci = RSCI(opaque);
117645194c7SYoshinori Sato if (!FIELD_EX8(sci->ssr, SSR, TDRE)) {
118645194c7SYoshinori Sato send_byte(sci);
119645194c7SYoshinori Sato } else {
120645194c7SYoshinori Sato sci->ssr = FIELD_DP8(sci->ssr, SSR, TEND, 1);
121645194c7SYoshinori Sato if (FIELD_EX8(sci->scr, SCR, TEIE)) {
122645194c7SYoshinori Sato qemu_set_irq(sci->irq[TEI], 1);
123645194c7SYoshinori Sato }
124645194c7SYoshinori Sato }
125645194c7SYoshinori Sato }
126645194c7SYoshinori Sato
update_trtime(RSCIState * sci)127645194c7SYoshinori Sato static void update_trtime(RSCIState *sci)
128645194c7SYoshinori Sato {
129645194c7SYoshinori Sato /* char per bits */
130645194c7SYoshinori Sato sci->trtime = 8 - FIELD_EX8(sci->smr, SMR, CHR);
131645194c7SYoshinori Sato sci->trtime += FIELD_EX8(sci->smr, SMR, PE);
132645194c7SYoshinori Sato sci->trtime += FIELD_EX8(sci->smr, SMR, STOP) + 1;
133645194c7SYoshinori Sato /* x bit transmit time (32 * divrate * brr) / base freq */
134645194c7SYoshinori Sato sci->trtime *= 32 * sci->brr;
135645194c7SYoshinori Sato sci->trtime *= 1 << (2 * FIELD_EX8(sci->smr, SMR, CKS));
136645194c7SYoshinori Sato sci->trtime *= NANOSECONDS_PER_SECOND;
137645194c7SYoshinori Sato sci->trtime /= sci->input_freq;
138645194c7SYoshinori Sato }
139645194c7SYoshinori Sato
sci_is_tr_enabled(RSCIState * sci)140645194c7SYoshinori Sato static bool sci_is_tr_enabled(RSCIState *sci)
141645194c7SYoshinori Sato {
142645194c7SYoshinori Sato return FIELD_EX8(sci->scr, SCR, TE) || FIELD_EX8(sci->scr, SCR, RE);
143645194c7SYoshinori Sato }
144645194c7SYoshinori Sato
sci_write(void * opaque,hwaddr offset,uint64_t val,unsigned size)145645194c7SYoshinori Sato static void sci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
146645194c7SYoshinori Sato {
147645194c7SYoshinori Sato RSCIState *sci = RSCI(opaque);
148645194c7SYoshinori Sato
149645194c7SYoshinori Sato switch (offset) {
150645194c7SYoshinori Sato case A_SMR:
151645194c7SYoshinori Sato if (!sci_is_tr_enabled(sci)) {
152645194c7SYoshinori Sato sci->smr = val;
153645194c7SYoshinori Sato update_trtime(sci);
154645194c7SYoshinori Sato }
155645194c7SYoshinori Sato break;
156645194c7SYoshinori Sato case A_BRR:
157645194c7SYoshinori Sato if (!sci_is_tr_enabled(sci)) {
158645194c7SYoshinori Sato sci->brr = val;
159645194c7SYoshinori Sato update_trtime(sci);
160645194c7SYoshinori Sato }
161645194c7SYoshinori Sato break;
162645194c7SYoshinori Sato case A_SCR:
163645194c7SYoshinori Sato sci->scr = val;
164645194c7SYoshinori Sato if (FIELD_EX8(sci->scr, SCR, TE)) {
165645194c7SYoshinori Sato sci->ssr = FIELD_DP8(sci->ssr, SSR, TDRE, 1);
166645194c7SYoshinori Sato sci->ssr = FIELD_DP8(sci->ssr, SSR, TEND, 1);
167645194c7SYoshinori Sato if (FIELD_EX8(sci->scr, SCR, TIE)) {
168645194c7SYoshinori Sato qemu_irq_pulse(sci->irq[TXI]);
169645194c7SYoshinori Sato }
170645194c7SYoshinori Sato }
171645194c7SYoshinori Sato if (!FIELD_EX8(sci->scr, SCR, TEIE)) {
172645194c7SYoshinori Sato qemu_set_irq(sci->irq[TEI], 0);
173645194c7SYoshinori Sato }
174645194c7SYoshinori Sato if (!FIELD_EX8(sci->scr, SCR, RIE)) {
175645194c7SYoshinori Sato qemu_set_irq(sci->irq[ERI], 0);
176645194c7SYoshinori Sato }
177645194c7SYoshinori Sato break;
178645194c7SYoshinori Sato case A_TDR:
179645194c7SYoshinori Sato sci->tdr = val;
180645194c7SYoshinori Sato if (FIELD_EX8(sci->ssr, SSR, TEND)) {
181645194c7SYoshinori Sato send_byte(sci);
182645194c7SYoshinori Sato } else {
183645194c7SYoshinori Sato sci->ssr = FIELD_DP8(sci->ssr, SSR, TDRE, 0);
184645194c7SYoshinori Sato }
185645194c7SYoshinori Sato break;
186645194c7SYoshinori Sato case A_SSR:
187645194c7SYoshinori Sato sci->ssr = FIELD_DP8(sci->ssr, SSR, MPBT,
188645194c7SYoshinori Sato FIELD_EX8(val, SSR, MPBT));
189645194c7SYoshinori Sato sci->ssr = FIELD_DP8(sci->ssr, SSR, ERR,
190645194c7SYoshinori Sato FIELD_EX8(val, SSR, ERR) & 0x07);
191645194c7SYoshinori Sato if (FIELD_EX8(sci->read_ssr, SSR, ERR) &&
192645194c7SYoshinori Sato FIELD_EX8(sci->ssr, SSR, ERR) == 0) {
193645194c7SYoshinori Sato qemu_set_irq(sci->irq[ERI], 0);
194645194c7SYoshinori Sato }
195645194c7SYoshinori Sato break;
196645194c7SYoshinori Sato case A_RDR:
197645194c7SYoshinori Sato qemu_log_mask(LOG_GUEST_ERROR, "reneas_sci: RDR is read only.\n");
198645194c7SYoshinori Sato break;
199645194c7SYoshinori Sato case A_SCMR:
200645194c7SYoshinori Sato sci->scmr = val; break;
201645194c7SYoshinori Sato case A_SEMR: /* SEMR */
202645194c7SYoshinori Sato sci->semr = val; break;
203645194c7SYoshinori Sato default:
204645194c7SYoshinori Sato qemu_log_mask(LOG_UNIMP, "renesas_sci: Register 0x%" HWADDR_PRIX " "
205645194c7SYoshinori Sato "not implemented\n",
206645194c7SYoshinori Sato offset);
207645194c7SYoshinori Sato }
208645194c7SYoshinori Sato }
209645194c7SYoshinori Sato
sci_read(void * opaque,hwaddr offset,unsigned size)210645194c7SYoshinori Sato static uint64_t sci_read(void *opaque, hwaddr offset, unsigned size)
211645194c7SYoshinori Sato {
212645194c7SYoshinori Sato RSCIState *sci = RSCI(opaque);
213645194c7SYoshinori Sato
214645194c7SYoshinori Sato switch (offset) {
215645194c7SYoshinori Sato case A_SMR:
216645194c7SYoshinori Sato return sci->smr;
217645194c7SYoshinori Sato case A_BRR:
218645194c7SYoshinori Sato return sci->brr;
219645194c7SYoshinori Sato case A_SCR:
220645194c7SYoshinori Sato return sci->scr;
221645194c7SYoshinori Sato case A_TDR:
222645194c7SYoshinori Sato return sci->tdr;
223645194c7SYoshinori Sato case A_SSR:
224645194c7SYoshinori Sato sci->read_ssr = sci->ssr;
225645194c7SYoshinori Sato return sci->ssr;
226645194c7SYoshinori Sato case A_RDR:
227645194c7SYoshinori Sato sci->ssr = FIELD_DP8(sci->ssr, SSR, RDRF, 0);
228645194c7SYoshinori Sato return sci->rdr;
229645194c7SYoshinori Sato case A_SCMR:
230645194c7SYoshinori Sato return sci->scmr;
231645194c7SYoshinori Sato case A_SEMR:
232645194c7SYoshinori Sato return sci->semr;
233645194c7SYoshinori Sato default:
234645194c7SYoshinori Sato qemu_log_mask(LOG_UNIMP, "renesas_sci: Register 0x%" HWADDR_PRIX
235645194c7SYoshinori Sato " not implemented.\n", offset);
236645194c7SYoshinori Sato }
237645194c7SYoshinori Sato return UINT64_MAX;
238645194c7SYoshinori Sato }
239645194c7SYoshinori Sato
240645194c7SYoshinori Sato static const MemoryRegionOps sci_ops = {
241645194c7SYoshinori Sato .write = sci_write,
242645194c7SYoshinori Sato .read = sci_read,
243645194c7SYoshinori Sato .endianness = DEVICE_NATIVE_ENDIAN,
244645194c7SYoshinori Sato .impl.max_access_size = 1,
245645194c7SYoshinori Sato .valid.max_access_size = 1,
246645194c7SYoshinori Sato };
247645194c7SYoshinori Sato
rsci_reset(DeviceState * dev)248645194c7SYoshinori Sato static void rsci_reset(DeviceState *dev)
249645194c7SYoshinori Sato {
250645194c7SYoshinori Sato RSCIState *sci = RSCI(dev);
251645194c7SYoshinori Sato sci->smr = sci->scr = 0x00;
252645194c7SYoshinori Sato sci->brr = 0xff;
253645194c7SYoshinori Sato sci->tdr = 0xff;
254645194c7SYoshinori Sato sci->rdr = 0x00;
255645194c7SYoshinori Sato sci->ssr = 0x84;
256645194c7SYoshinori Sato sci->scmr = 0x00;
257645194c7SYoshinori Sato sci->semr = 0x00;
258645194c7SYoshinori Sato sci->rx_next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
259645194c7SYoshinori Sato }
260645194c7SYoshinori Sato
sci_event(void * opaque,QEMUChrEvent event)261645194c7SYoshinori Sato static void sci_event(void *opaque, QEMUChrEvent event)
262645194c7SYoshinori Sato {
263645194c7SYoshinori Sato RSCIState *sci = RSCI(opaque);
264645194c7SYoshinori Sato if (event == CHR_EVENT_BREAK) {
265645194c7SYoshinori Sato sci->ssr = FIELD_DP8(sci->ssr, SSR, FER, 1);
266645194c7SYoshinori Sato if (FIELD_EX8(sci->scr, SCR, RIE)) {
267645194c7SYoshinori Sato qemu_set_irq(sci->irq[ERI], 1);
268645194c7SYoshinori Sato }
269645194c7SYoshinori Sato }
270645194c7SYoshinori Sato }
271645194c7SYoshinori Sato
rsci_realize(DeviceState * dev,Error ** errp)272645194c7SYoshinori Sato static void rsci_realize(DeviceState *dev, Error **errp)
273645194c7SYoshinori Sato {
274645194c7SYoshinori Sato RSCIState *sci = RSCI(dev);
275645194c7SYoshinori Sato
276645194c7SYoshinori Sato if (sci->input_freq == 0) {
277645194c7SYoshinori Sato qemu_log_mask(LOG_GUEST_ERROR,
278645194c7SYoshinori Sato "renesas_sci: input-freq property must be set.");
279645194c7SYoshinori Sato return;
280645194c7SYoshinori Sato }
281645194c7SYoshinori Sato qemu_chr_fe_set_handlers(&sci->chr, can_receive, receive,
282645194c7SYoshinori Sato sci_event, NULL, sci, NULL, true);
283645194c7SYoshinori Sato }
284645194c7SYoshinori Sato
rsci_init(Object * obj)285645194c7SYoshinori Sato static void rsci_init(Object *obj)
286645194c7SYoshinori Sato {
287645194c7SYoshinori Sato SysBusDevice *d = SYS_BUS_DEVICE(obj);
288645194c7SYoshinori Sato RSCIState *sci = RSCI(obj);
289645194c7SYoshinori Sato int i;
290645194c7SYoshinori Sato
291645194c7SYoshinori Sato memory_region_init_io(&sci->memory, OBJECT(sci), &sci_ops,
292645194c7SYoshinori Sato sci, "renesas-sci", 0x8);
293645194c7SYoshinori Sato sysbus_init_mmio(d, &sci->memory);
294645194c7SYoshinori Sato
295645194c7SYoshinori Sato for (i = 0; i < SCI_NR_IRQ; i++) {
296645194c7SYoshinori Sato sysbus_init_irq(d, &sci->irq[i]);
297645194c7SYoshinori Sato }
298645194c7SYoshinori Sato timer_init_ns(&sci->timer, QEMU_CLOCK_VIRTUAL, txend, sci);
299645194c7SYoshinori Sato }
300645194c7SYoshinori Sato
301645194c7SYoshinori Sato static const VMStateDescription vmstate_rsci = {
302645194c7SYoshinori Sato .name = "renesas-sci",
303645194c7SYoshinori Sato .version_id = 1,
304645194c7SYoshinori Sato .minimum_version_id = 1,
3052f6cab05SRichard Henderson .fields = (const VMStateField[]) {
306645194c7SYoshinori Sato VMSTATE_INT64(trtime, RSCIState),
307645194c7SYoshinori Sato VMSTATE_INT64(rx_next, RSCIState),
308645194c7SYoshinori Sato VMSTATE_UINT8(smr, RSCIState),
309645194c7SYoshinori Sato VMSTATE_UINT8(brr, RSCIState),
310645194c7SYoshinori Sato VMSTATE_UINT8(scr, RSCIState),
311645194c7SYoshinori Sato VMSTATE_UINT8(tdr, RSCIState),
312645194c7SYoshinori Sato VMSTATE_UINT8(ssr, RSCIState),
313645194c7SYoshinori Sato VMSTATE_UINT8(rdr, RSCIState),
314645194c7SYoshinori Sato VMSTATE_UINT8(scmr, RSCIState),
315645194c7SYoshinori Sato VMSTATE_UINT8(semr, RSCIState),
316645194c7SYoshinori Sato VMSTATE_UINT8(read_ssr, RSCIState),
317645194c7SYoshinori Sato VMSTATE_TIMER(timer, RSCIState),
318645194c7SYoshinori Sato VMSTATE_END_OF_LIST()
319645194c7SYoshinori Sato }
320645194c7SYoshinori Sato };
321645194c7SYoshinori Sato
322645194c7SYoshinori Sato static Property rsci_properties[] = {
323645194c7SYoshinori Sato DEFINE_PROP_UINT64("input-freq", RSCIState, input_freq, 0),
324645194c7SYoshinori Sato DEFINE_PROP_CHR("chardev", RSCIState, chr),
325645194c7SYoshinori Sato DEFINE_PROP_END_OF_LIST(),
326645194c7SYoshinori Sato };
327645194c7SYoshinori Sato
rsci_class_init(ObjectClass * klass,void * data)328645194c7SYoshinori Sato static void rsci_class_init(ObjectClass *klass, void *data)
329645194c7SYoshinori Sato {
330645194c7SYoshinori Sato DeviceClass *dc = DEVICE_CLASS(klass);
331645194c7SYoshinori Sato
332645194c7SYoshinori Sato dc->realize = rsci_realize;
333645194c7SYoshinori Sato dc->vmsd = &vmstate_rsci;
334*e3d08143SPeter Maydell device_class_set_legacy_reset(dc, rsci_reset);
335645194c7SYoshinori Sato device_class_set_props(dc, rsci_properties);
336645194c7SYoshinori Sato }
337645194c7SYoshinori Sato
338645194c7SYoshinori Sato static const TypeInfo rsci_info = {
339645194c7SYoshinori Sato .name = TYPE_RENESAS_SCI,
340645194c7SYoshinori Sato .parent = TYPE_SYS_BUS_DEVICE,
341645194c7SYoshinori Sato .instance_size = sizeof(RSCIState),
342645194c7SYoshinori Sato .instance_init = rsci_init,
343645194c7SYoshinori Sato .class_init = rsci_class_init,
344645194c7SYoshinori Sato };
345645194c7SYoshinori Sato
rsci_register_types(void)346645194c7SYoshinori Sato static void rsci_register_types(void)
347645194c7SYoshinori Sato {
348645194c7SYoshinori Sato type_register_static(&rsci_info);
349645194c7SYoshinori Sato }
350645194c7SYoshinori Sato
351645194c7SYoshinori Sato type_init(rsci_register_types)
352