summaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/ricoh.h
blob: 8ac7b138c094865f3f94cc41ba8824f430b76a22 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
/*
 * ricoh.h 1.9 1999/10/25 20:03:34
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License
 * at http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and
 * limitations under the License. 
 *
 * The initial developer of the original code is David A. Hinds
 * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
 * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
 *
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License version 2 (the "GPL"), in which
 * case the provisions of the GPL are applicable instead of the
 * above.  If you wish to allow the use of your version of this file
 * only under the terms of the GPL and not to allow others to use
 * your version of this file under the MPL, indicate your decision by
 * deleting the provisions above and replace them with the notice and
 * other provisions required by the GPL.  If you do not delete the
 * provisions above, a recipient may use your version of this file
 * under either the MPL or the GPL.
 */

#ifndef _LINUX_RICOH_H
#define _LINUX_RICOH_H


#define RF5C_MODE_CTL		0x1f	/* Mode control */
#define RF5C_PWR_CTL		0x2f	/* Mixed voltage control */
#define RF5C_CHIP_ID		0x3a	/* Chip identification */
#define RF5C_MODE_CTL_3		0x3b	/* Mode control 3 */

/* I/O window address offset */
#define RF5C_IO_OFF(w)		(0x36+((w)<<1))

/* Flags for RF5C_MODE_CTL */
#define RF5C_MODE_ATA		0x01	/* ATA mode */
#define RF5C_MODE_LED_ENA	0x02	/* IRQ 12 is LED */
#define RF5C_MODE_CA21		0x04
#define RF5C_MODE_CA22		0x08
#define RF5C_MODE_CA23		0x10
#define RF5C_MODE_CA24		0x20
#define RF5C_MODE_CA25		0x40
#define RF5C_MODE_3STATE_BIT7	0x80

/* Flags for RF5C_PWR_CTL */
#define RF5C_PWR_VCC_3V		0x01
#define RF5C_PWR_IREQ_HIGH	0x02
#define RF5C_PWR_INPACK_ENA	0x04
#define RF5C_PWR_5V_DET		0x08
#define RF5C_PWR_TC_SEL		0x10	/* Terminal Count: irq 11 or 15 */
#define RF5C_PWR_DREQ_LOW	0x20
#define RF5C_PWR_DREQ_OFF	0x00	/* DREQ steering control */
#define RF5C_PWR_DREQ_INPACK	0x40
#define RF5C_PWR_DREQ_SPKR	0x80
#define RF5C_PWR_DREQ_IOIS16	0xc0

/* Values for RF5C_CHIP_ID */
#define RF5C_CHIP_RF5C296	0x32
#define RF5C_CHIP_RF5C396	0xb2

/* Flags for RF5C_MODE_CTL_3 */
#define RF5C_MCTL3_DISABLE	0x01	/* Disable PCMCIA interface */
#define RF5C_MCTL3_DMA_ENA	0x02

/* Register definitions for Ricoh PCI-to-CardBus bridges */

/* Extra bits in CB_BRIDGE_CONTROL */
#define RL5C46X_BCR_3E0_ENA		0x0800
#define RL5C46X_BCR_3E2_ENA		0x1000

/* Bridge Configuration Register */
#define RL5C4XX_CONFIG			0x80	/* 16 bit */
#define  RL5C4XX_CONFIG_IO_1_MODE	0x0200
#define  RL5C4XX_CONFIG_IO_0_MODE	0x0100
#define  RL5C4XX_CONFIG_PREFETCH	0x0001

/* Misc Control Register */
#define RL5C4XX_MISC			0x0082	/* 16 bit */
#define  RL5C4XX_MISC_HW_SUSPEND_ENA	0x0002
#define  RL5C4XX_MISC_VCCEN_POL		0x0100
#define  RL5C4XX_MISC_VPPEN_POL		0x0200
#define  RL5C46X_MISC_SUSPEND		0x0001
#define  RL5C46X_MISC_PWR_SAVE_2	0x0004
#define  RL5C46X_MISC_IFACE_BUSY	0x0008
#define  RL5C46X_MISC_B_LOCK		0x0010
#define  RL5C46X_MISC_A_LOCK		0x0020
#define  RL5C46X_MISC_PCI_LOCK		0x0040
#define  RL5C47X_MISC_IFACE_BUSY	0x0004
#define  RL5C47X_MISC_PCI_INT_MASK	0x0018
#define  RL5C47X_MISC_PCI_INT_DIS	0x0020
#define  RL5C47X_MISC_SUBSYS_WR		0x0040
#define  RL5C47X_MISC_SRIRQ_ENA		0x0080
#define  RL5C47X_MISC_5V_DISABLE	0x0400
#define  RL5C47X_MISC_LED_POL		0x0800

/* 16-bit Interface Control Register */
#define RL5C4XX_16BIT_CTL		0x0084	/* 16 bit */
#define  RL5C4XX_16CTL_IO_TIMING	0x0100
#define  RL5C4XX_16CTL_MEM_TIMING	0x0200
#define  RL5C46X_16CTL_LEVEL_1		0x0010
#define  RL5C46X_16CTL_LEVEL_2		0x0020

/* 16-bit IO and memory timing registers */
#define RL5C4XX_16BIT_IO_0		0x0088	/* 16 bit */
#define RL5C4XX_16BIT_MEM_0		0x008a	/* 16 bit */
#define  RL5C4XX_SETUP_MASK		0x0007
#define  RL5C4XX_SETUP_SHIFT		0
#define  RL5C4XX_CMD_MASK		0x01f0
#define  RL5C4XX_CMD_SHIFT		4
#define  RL5C4XX_HOLD_MASK		0x1c00
#define  RL5C4XX_HOLD_SHIFT		10
#define  RL5C4XX_MISC_CONTROL           0x2F /* 8 bit */
#define  RL5C4XX_ZV_ENABLE              0x08

/* Misc Control 3 Register */
#define RL5C4XX_MISC3			0x00A2 /* 16 bit */
#define  RL5C47X_MISC3_CB_CLKRUN_DIS	BIT(1)

#ifdef __YENTA_H

#define rl_misc(socket)		((socket)->private[0])
#define rl_ctl(socket)		((socket)->private[1])
#define rl_io(socket)		((socket)->private[2])
#define rl_mem(socket)		((socket)->private[3])
#define rl_config(socket)	((socket)->private[4])

static void ricoh_zoom_video(struct pcmcia_socket *sock, int onoff)
{
        u8 reg;
	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);

        reg = config_readb(socket, RL5C4XX_MISC_CONTROL);
        if (onoff)
                /* Zoom zoom, we will all go together, zoom zoom, zoom zoom */
                reg |=  RL5C4XX_ZV_ENABLE;
        else
                reg &= ~RL5C4XX_ZV_ENABLE;
	
        config_writeb(socket, RL5C4XX_MISC_CONTROL, reg);
}

static void ricoh_set_zv(struct yenta_socket *socket)
{
        if(socket->dev->vendor == PCI_VENDOR_ID_RICOH)
        {
                switch(socket->dev->device)
                {
                        /* There may be more .. */
		case  PCI_DEVICE_ID_RICOH_RL5C478:
			socket->socket.zoom_video = ricoh_zoom_video;
			break;  
                }
        }
}

static void ricoh_set_clkrun(struct yenta_socket *socket, bool quiet)
{
	u16 misc3;

	/*
	 * RL5C475II likely has this setting, too, however no datasheet
	 * is publicly available for this chip
	 */
	if (socket->dev->device != PCI_DEVICE_ID_RICOH_RL5C476 &&
	    socket->dev->device != PCI_DEVICE_ID_RICOH_RL5C478)
		return;

	if (socket->dev->revision < 0x80)
		return;

	misc3 = config_readw(socket, RL5C4XX_MISC3);
	if (misc3 & RL5C47X_MISC3_CB_CLKRUN_DIS) {
		if (!quiet)
			dev_dbg(&socket->dev->dev,
				"CLKRUN feature already disabled\n");
	} else if (disable_clkrun) {
		if (!quiet)
			dev_info(&socket->dev->dev,
				 "Disabling CLKRUN feature\n");
		misc3 |= RL5C47X_MISC3_CB_CLKRUN_DIS;
		config_writew(socket, RL5C4XX_MISC3, misc3);
	}
}

static void ricoh_save_state(struct yenta_socket *socket)
{
	rl_misc(socket) = config_readw(socket, RL5C4XX_MISC);
	rl_ctl(socket) = config_readw(socket, RL5C4XX_16BIT_CTL);
	rl_io(socket) = config_readw(socket, RL5C4XX_16BIT_IO_0);
	rl_mem(socket) = config_readw(socket, RL5C4XX_16BIT_MEM_0);
	rl_config(socket) = config_readw(socket, RL5C4XX_CONFIG);
}

static void ricoh_restore_state(struct yenta_socket *socket)
{
	config_writew(socket, RL5C4XX_MISC, rl_misc(socket));
	config_writew(socket, RL5C4XX_16BIT_CTL, rl_ctl(socket));
	config_writew(socket, RL5C4XX_16BIT_IO_0, rl_io(socket));
	config_writew(socket, RL5C4XX_16BIT_MEM_0, rl_mem(socket));
	config_writew(socket, RL5C4XX_CONFIG, rl_config(socket));
	ricoh_set_clkrun(socket, true);
}


/*
 * Magic Ricoh initialization code..
 */
static int ricoh_override(struct yenta_socket *socket)
{
	u16 config, ctl;

	config = config_readw(socket, RL5C4XX_CONFIG);

	/* Set the default timings, don't trust the original values */
	ctl = RL5C4XX_16CTL_IO_TIMING | RL5C4XX_16CTL_MEM_TIMING;

	if(socket->dev->device < PCI_DEVICE_ID_RICOH_RL5C475) {
		ctl |= RL5C46X_16CTL_LEVEL_1 | RL5C46X_16CTL_LEVEL_2;
	} else {
		config |= RL5C4XX_CONFIG_PREFETCH;
	}

	config_writew(socket, RL5C4XX_16BIT_CTL, ctl);
	config_writew(socket, RL5C4XX_CONFIG, config);

	ricoh_set_zv(socket);
	ricoh_set_clkrun(socket, false);

	return 0;
}

#endif /* CONFIG_CARDBUS */

#endif /* _LINUX_RICOH_H */