1 /* SPDX-License-Identifier: GPL-2.0 */
3 * For License see notice in hfc_multi.c
5 * special IO and init functions for the embedded XHFC board
12 /* Change this to the value used by your board */
14 #define IMAP_ADDR 0xFFF00000
18 #ifdef HFC_REGISTER_DEBUG
19 HFC_outb_embsd(struct hfc_multi
*hc
, u_char reg
, u_char val
,
20 const char *function
, int line
)
22 HFC_outb_embsd(struct hfc_multi
*hc
, u_char reg
, u_char val
)
25 hc
->immap
->im_ioport
.iop_padat
|= PA_XHFC_A0
;
26 writeb(reg
, hc
->xhfc_memaddr
);
27 hc
->immap
->im_ioport
.iop_padat
&= ~(PA_XHFC_A0
);
28 writeb(val
, hc
->xhfc_memdata
);
31 #ifdef HFC_REGISTER_DEBUG
32 HFC_inb_embsd(struct hfc_multi
*hc
, u_char reg
, const char *function
, int line
)
34 HFC_inb_embsd(struct hfc_multi
*hc
, u_char reg
)
37 hc
->immap
->im_ioport
.iop_padat
|= PA_XHFC_A0
;
38 writeb(reg
, hc
->xhfc_memaddr
);
39 hc
->immap
->im_ioport
.iop_padat
&= ~(PA_XHFC_A0
);
40 return readb(hc
->xhfc_memdata
);
43 #ifdef HFC_REGISTER_DEBUG
44 HFC_inw_embsd(struct hfc_multi
*hc
, u_char reg
, const char *function
, int line
)
46 HFC_inw_embsd(struct hfc_multi
*hc
, u_char reg
)
49 hc
->immap
->im_ioport
.iop_padat
|= PA_XHFC_A0
;
50 writeb(reg
, hc
->xhfc_memaddr
);
51 hc
->immap
->im_ioport
.iop_padat
&= ~(PA_XHFC_A0
);
52 return readb(hc
->xhfc_memdata
);
55 #ifdef HFC_REGISTER_DEBUG
56 HFC_wait_embsd(struct hfc_multi
*hc
, const char *function
, int line
)
58 HFC_wait_embsd(struct hfc_multi
*hc
)
61 hc
->immap
->im_ioport
.iop_padat
|= PA_XHFC_A0
;
62 writeb(R_STATUS
, hc
->xhfc_memaddr
);
63 hc
->immap
->im_ioport
.iop_padat
&= ~(PA_XHFC_A0
);
64 while (readb(hc
->xhfc_memdata
) & V_BUSY
)
68 /* write fifo data (EMBSD) */
70 write_fifo_embsd(struct hfc_multi
*hc
, u_char
*data
, int len
)
72 hc
->immap
->im_ioport
.iop_padat
|= PA_XHFC_A0
;
73 *hc
->xhfc_memaddr
= A_FIFO_DATA0
;
74 hc
->immap
->im_ioport
.iop_padat
&= ~(PA_XHFC_A0
);
76 *hc
->xhfc_memdata
= *data
;
82 /* read fifo data (EMBSD) */
84 read_fifo_embsd(struct hfc_multi
*hc
, u_char
*data
, int len
)
86 hc
->immap
->im_ioport
.iop_padat
|= PA_XHFC_A0
;
87 *hc
->xhfc_memaddr
= A_FIFO_DATA0
;
88 hc
->immap
->im_ioport
.iop_padat
&= ~(PA_XHFC_A0
);
90 *data
= (u_char
)(*hc
->xhfc_memdata
);
97 setup_embedded(struct hfc_multi
*hc
, struct hm_map
*m
)
100 "HFC-multi: card manufacturer: '%s' card name: '%s' clock: %s\n",
101 m
->vendor_name
, m
->card_name
, m
->clock2
? "double" : "normal");
105 test_and_set_bit(HFC_CHIP_CLOCK2
, &hc
->chip
);
108 hc
->ledstate
= 0xAFFEAFFE;
109 hc
->opticalsupport
= m
->opticalsupport
;
113 hc
->xhfc_membase
= NULL
;
114 hc
->xhfc_memaddr
= NULL
;
115 hc
->xhfc_memdata
= NULL
;
117 /* set memory access methods */
118 if (m
->io_mode
) /* use mode from card config */
119 hc
->io_mode
= m
->io_mode
;
120 switch (hc
->io_mode
) {
121 case HFC_IO_MODE_EMBSD
:
122 test_and_set_bit(HFC_CHIP_EMBSD
, &hc
->chip
);
123 hc
->slots
= 128; /* required */
125 hc
->HFC_outb
= HFC_outb_embsd
;
126 hc
->HFC_inb
= HFC_inb_embsd
;
127 hc
->HFC_inw
= HFC_inw_embsd
;
128 hc
->HFC_wait
= HFC_wait_embsd
;
129 hc
->read_fifo
= read_fifo_embsd
;
130 hc
->write_fifo
= write_fifo_embsd
;
131 hc
->xhfc_origmembase
= XHFC_MEMBASE
+ XHFC_OFFSET
* hc
->id
;
132 hc
->xhfc_membase
= (u_char
*)ioremap(hc
->xhfc_origmembase
,
134 if (!hc
->xhfc_membase
) {
136 "HFC-multi: failed to remap xhfc address space. "
137 "(internal error)\n");
140 hc
->xhfc_memaddr
= (u_long
*)(hc
->xhfc_membase
+ 4);
141 hc
->xhfc_memdata
= (u_long
*)(hc
->xhfc_membase
);
143 "HFC-multi: xhfc_membase:%#lx xhfc_origmembase:%#lx "
144 "xhfc_memaddr:%#lx xhfc_memdata:%#lx\n",
145 (u_long
)hc
->xhfc_membase
, hc
->xhfc_origmembase
,
146 (u_long
)hc
->xhfc_memaddr
, (u_long
)hc
->xhfc_memdata
);
149 printk(KERN_WARNING
"HFC-multi: Invalid IO mode.\n");
153 /* Prepare the MPC8XX PortA 10 as output (address/data selector) */
154 hc
->immap
= (struct immap
*)(IMAP_ADDR
);
155 hc
->immap
->im_ioport
.iop_papar
&= ~(PA_XHFC_A0
);
156 hc
->immap
->im_ioport
.iop_paodr
&= ~(PA_XHFC_A0
);
157 hc
->immap
->im_ioport
.iop_padir
|= PA_XHFC_A0
;
159 /* Prepare the MPC8xx PortB __X__ as input (ISDN__X__IRQ) */
160 hc
->pb_irqmsk
= (PB_XHFC_IRQ1
<< hc
->id
);
161 hc
->immap
->im_cpm
.cp_pbpar
&= ~(hc
->pb_irqmsk
);
162 hc
->immap
->im_cpm
.cp_pbodr
&= ~(hc
->pb_irqmsk
);
163 hc
->immap
->im_cpm
.cp_pbdir
&= ~(hc
->pb_irqmsk
);
165 /* At this point the needed config is done */
166 /* fifos are still not enabled */