1 /*
2  * Sony Programmable I/O Control Device driver for VAIO
3  *
4  * Copyright (C) 2001-2003 Stelian Pop <stelian@popies.net>
5  *
6  * Copyright (C) 2001-2002 Alc�ve <www.alcove.com>
7  *
8  * Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au>
9  *
10  * Copyright (C) 2001 Junichi Morita <jun1m@mars.dti.ne.jp>
11  *
12  * Copyright (C) 2000 Takaya Kinjo <t-kinjo@tc4.so-net.ne.jp>
13  *
14  * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
15  *
16  * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras.
17  *
18  * This program is free software; you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation; either version 2 of the License, or
21  * (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program; if not, write to the Free Software
30  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31  *
32  */
33 
34 #ifndef _SONYPI_PRIV_H_
35 #define _SONYPI_PRIV_H_
36 
37 #ifdef __KERNEL__
38 
39 #define SONYPI_DRIVER_MAJORVERSION	 1
40 #define SONYPI_DRIVER_MINORVERSION	22
41 
42 #define SONYPI_DEVICE_MODEL_TYPE1	1
43 #define SONYPI_DEVICE_MODEL_TYPE2	2
44 
45 #include <linux/config.h>
46 #include <linux/types.h>
47 #include <linux/pci.h>
48 #include <linux/input.h>
49 #include <linux/pm.h>
50 #include <linux/acpi.h>
51 #include "linux/sonypi.h"
52 
53 /* type1 models use those */
54 #define SONYPI_IRQ_PORT			0x8034
55 #define SONYPI_IRQ_SHIFT		22
56 #define SONYPI_BASE			0x50
57 #define SONYPI_G10A			(SONYPI_BASE+0x14)
58 #define SONYPI_TYPE1_REGION_SIZE	0x08
59 #define SONYPI_TYPE1_EVTYPE_OFFSET	0x04
60 
61 /* type2 series specifics */
62 #define SONYPI_SIRQ			0x9b
63 #define SONYPI_SLOB			0x9c
64 #define SONYPI_SHIB			0x9d
65 #define SONYPI_TYPE2_REGION_SIZE	0x20
66 #define SONYPI_TYPE2_EVTYPE_OFFSET	0x12
67 
68 /* battery / brightness addresses */
69 #define SONYPI_BAT_FLAGS	0x81
70 #define SONYPI_LCD_LIGHT	0x96
71 #define SONYPI_BAT1_PCTRM	0xa0
72 #define SONYPI_BAT1_LEFT	0xa2
73 #define SONYPI_BAT1_MAXRT	0xa4
74 #define SONYPI_BAT2_PCTRM	0xa8
75 #define SONYPI_BAT2_LEFT	0xaa
76 #define SONYPI_BAT2_MAXRT	0xac
77 #define SONYPI_BAT1_MAXTK	0xb0
78 #define SONYPI_BAT1_FULL	0xb2
79 #define SONYPI_BAT2_MAXTK	0xb8
80 #define SONYPI_BAT2_FULL	0xba
81 
82 /* ioports used for brightness and type2 events */
83 #define SONYPI_DATA_IOPORT	0x62
84 #define SONYPI_CST_IOPORT	0x66
85 
86 /* The set of possible ioports */
87 struct sonypi_ioport_list {
88 	u16	port1;
89 	u16	port2;
90 };
91 
92 static struct sonypi_ioport_list sonypi_type1_ioport_list[] = {
93 	{ 0x10c0, 0x10c4 },	/* looks like the default on C1Vx */
94 	{ 0x1080, 0x1084 },
95 	{ 0x1090, 0x1094 },
96 	{ 0x10a0, 0x10a4 },
97 	{ 0x10b0, 0x10b4 },
98 	{ 0x0, 0x0 }
99 };
100 
101 static struct sonypi_ioport_list sonypi_type2_ioport_list[] = {
102 	{ 0x1080, 0x1084 },
103 	{ 0x10a0, 0x10a4 },
104 	{ 0x10c0, 0x10c4 },
105 	{ 0x10e0, 0x10e4 },
106 	{ 0x0, 0x0 }
107 };
108 
109 /* The set of possible interrupts */
110 struct sonypi_irq_list {
111 	u16	irq;
112 	u16	bits;
113 };
114 
115 static struct sonypi_irq_list sonypi_type1_irq_list[] = {
116 	{ 11, 0x2 },	/* IRQ 11, GO22=0,GO23=1 in AML */
117 	{ 10, 0x1 },	/* IRQ 10, GO22=1,GO23=0 in AML */
118 	{  5, 0x0 },	/* IRQ  5, GO22=0,GO23=0 in AML */
119 	{  0, 0x3 }	/* no IRQ, GO22=1,GO23=1 in AML */
120 };
121 
122 static struct sonypi_irq_list sonypi_type2_irq_list[] = {
123 	{ 11, 0x80 },	/* IRQ 11, 0x80 in SIRQ in AML */
124 	{ 10, 0x40 },	/* IRQ 10, 0x40 in SIRQ in AML */
125 	{  9, 0x20 },	/* IRQ  9, 0x20 in SIRQ in AML */
126 	{  6, 0x10 },	/* IRQ  6, 0x10 in SIRQ in AML */
127 	{  0, 0x00 }	/* no IRQ, 0x00 in SIRQ in AML */
128 };
129 
130 #define SONYPI_CAMERA_BRIGHTNESS		0
131 #define SONYPI_CAMERA_CONTRAST			1
132 #define SONYPI_CAMERA_HUE			2
133 #define SONYPI_CAMERA_COLOR			3
134 #define SONYPI_CAMERA_SHARPNESS			4
135 
136 #define SONYPI_CAMERA_PICTURE			5
137 #define SONYPI_CAMERA_EXPOSURE_MASK		0xC
138 #define SONYPI_CAMERA_WHITE_BALANCE_MASK	0x3
139 #define SONYPI_CAMERA_PICTURE_MODE_MASK		0x30
140 #define SONYPI_CAMERA_MUTE_MASK			0x40
141 
142 /* the rest don't need a loop until not 0xff */
143 #define SONYPI_CAMERA_AGC			6
144 #define SONYPI_CAMERA_AGC_MASK			0x30
145 #define SONYPI_CAMERA_SHUTTER_MASK 		0x7
146 
147 #define SONYPI_CAMERA_SHUTDOWN_REQUEST		7
148 #define SONYPI_CAMERA_CONTROL			0x10
149 
150 #define SONYPI_CAMERA_STATUS 			7
151 #define SONYPI_CAMERA_STATUS_READY 		0x2
152 #define SONYPI_CAMERA_STATUS_POSITION		0x4
153 
154 #define SONYPI_DIRECTION_BACKWARDS 		0x4
155 
156 #define SONYPI_CAMERA_REVISION 			8
157 #define SONYPI_CAMERA_ROMVERSION 		9
158 
159 /* Event masks */
160 #define SONYPI_JOGGER_MASK			0x00000001
161 #define SONYPI_CAPTURE_MASK			0x00000002
162 #define SONYPI_FNKEY_MASK			0x00000004
163 #define SONYPI_BLUETOOTH_MASK			0x00000008
164 #define SONYPI_PKEY_MASK			0x00000010
165 #define SONYPI_BACK_MASK			0x00000020
166 #define SONYPI_HELP_MASK			0x00000040
167 #define SONYPI_LID_MASK				0x00000080
168 #define SONYPI_ZOOM_MASK			0x00000100
169 #define SONYPI_THUMBPHRASE_MASK			0x00000200
170 #define SONYPI_MEYE_MASK			0x00000400
171 #define SONYPI_MEMORYSTICK_MASK			0x00000800
172 #define SONYPI_BATTERY_MASK			0x00001000
173 
174 struct sonypi_event {
175 	u8	data;
176 	u8	event;
177 };
178 
179 /* The set of possible button release events */
180 static struct sonypi_event sonypi_releaseev[] = {
181 	{ 0x00, SONYPI_EVENT_ANYBUTTON_RELEASED },
182 	{ 0, 0 }
183 };
184 
185 /* The set of possible jogger events  */
186 static struct sonypi_event sonypi_joggerev[] = {
187 	{ 0x1f, SONYPI_EVENT_JOGDIAL_UP },
188 	{ 0x01, SONYPI_EVENT_JOGDIAL_DOWN },
189 	{ 0x5f, SONYPI_EVENT_JOGDIAL_UP_PRESSED },
190 	{ 0x41, SONYPI_EVENT_JOGDIAL_DOWN_PRESSED },
191 	{ 0x1e, SONYPI_EVENT_JOGDIAL_FAST_UP },
192 	{ 0x02, SONYPI_EVENT_JOGDIAL_FAST_DOWN },
193 	{ 0x5e, SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED },
194 	{ 0x42, SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED },
195 	{ 0x1d, SONYPI_EVENT_JOGDIAL_VFAST_UP },
196 	{ 0x03, SONYPI_EVENT_JOGDIAL_VFAST_DOWN },
197 	{ 0x5d, SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED },
198 	{ 0x43, SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED },
199 	{ 0x40, SONYPI_EVENT_JOGDIAL_PRESSED },
200 	{ 0, 0 }
201 };
202 
203 /* The set of possible capture button events */
204 static struct sonypi_event sonypi_captureev[] = {
205 	{ 0x05, SONYPI_EVENT_CAPTURE_PARTIALPRESSED },
206 	{ 0x07, SONYPI_EVENT_CAPTURE_PRESSED },
207 	{ 0x01, SONYPI_EVENT_CAPTURE_PARTIALRELEASED },
208 	{ 0, 0 }
209 };
210 
211 /* The set of possible fnkeys events */
212 static struct sonypi_event sonypi_fnkeyev[] = {
213 	{ 0x10, SONYPI_EVENT_FNKEY_ESC },
214 	{ 0x11, SONYPI_EVENT_FNKEY_F1 },
215 	{ 0x12, SONYPI_EVENT_FNKEY_F2 },
216 	{ 0x13, SONYPI_EVENT_FNKEY_F3 },
217 	{ 0x14, SONYPI_EVENT_FNKEY_F4 },
218 	{ 0x15, SONYPI_EVENT_FNKEY_F5 },
219 	{ 0x16, SONYPI_EVENT_FNKEY_F6 },
220 	{ 0x17, SONYPI_EVENT_FNKEY_F7 },
221 	{ 0x18, SONYPI_EVENT_FNKEY_F8 },
222 	{ 0x19, SONYPI_EVENT_FNKEY_F9 },
223 	{ 0x1a, SONYPI_EVENT_FNKEY_F10 },
224 	{ 0x1b, SONYPI_EVENT_FNKEY_F11 },
225 	{ 0x1c, SONYPI_EVENT_FNKEY_F12 },
226 	{ 0x21, SONYPI_EVENT_FNKEY_1 },
227 	{ 0x22, SONYPI_EVENT_FNKEY_2 },
228 	{ 0x31, SONYPI_EVENT_FNKEY_D },
229 	{ 0x32, SONYPI_EVENT_FNKEY_E },
230 	{ 0x33, SONYPI_EVENT_FNKEY_F },
231 	{ 0x34, SONYPI_EVENT_FNKEY_S },
232 	{ 0x35, SONYPI_EVENT_FNKEY_B },
233 	{ 0x36, SONYPI_EVENT_FNKEY_ONLY },
234 	{ 0, 0 }
235 };
236 
237 /* The set of possible program key events */
238 static struct sonypi_event sonypi_pkeyev[] = {
239 	{ 0x01, SONYPI_EVENT_PKEY_P1 },
240 	{ 0x02, SONYPI_EVENT_PKEY_P2 },
241 	{ 0x04, SONYPI_EVENT_PKEY_P3 },
242 	{ 0x5c, SONYPI_EVENT_PKEY_P1 },
243 	{ 0, 0 }
244 };
245 
246 /* The set of possible bluetooth events */
247 static struct sonypi_event sonypi_blueev[] = {
248 	{ 0x55, SONYPI_EVENT_BLUETOOTH_PRESSED },
249 	{ 0x59, SONYPI_EVENT_BLUETOOTH_ON },
250 	{ 0x5a, SONYPI_EVENT_BLUETOOTH_OFF },
251 	{ 0, 0 }
252 };
253 
254 /* The set of possible back button events */
255 static struct sonypi_event sonypi_backev[] = {
256 	{ 0x20, SONYPI_EVENT_BACK_PRESSED },
257 	{ 0, 0 }
258 };
259 
260 /* The set of possible help button events */
261 static struct sonypi_event sonypi_helpev[] = {
262 	{ 0x3b, SONYPI_EVENT_HELP_PRESSED },
263 	{ 0, 0 }
264 };
265 
266 
267 /* The set of possible lid events */
268 static struct sonypi_event sonypi_lidev[] = {
269 	{ 0x51, SONYPI_EVENT_LID_CLOSED },
270 	{ 0x50, SONYPI_EVENT_LID_OPENED },
271 	{ 0, 0 }
272 };
273 
274 /* The set of possible zoom events */
275 static struct sonypi_event sonypi_zoomev[] = {
276 	{ 0x39, SONYPI_EVENT_ZOOM_PRESSED },
277 	{ 0, 0 }
278 };
279 
280 /* The set of possible thumbphrase events */
281 static struct sonypi_event sonypi_thumbphraseev[] = {
282 	{ 0x3a, SONYPI_EVENT_THUMBPHRASE_PRESSED },
283 	{ 0, 0 }
284 };
285 
286 /* The set of possible motioneye camera events */
287 static struct sonypi_event sonypi_meyeev[] = {
288 	{ 0x00, SONYPI_EVENT_MEYE_FACE },
289 	{ 0x01, SONYPI_EVENT_MEYE_OPPOSITE },
290 	{ 0, 0 }
291 };
292 
293 /* The set of possible memorystick events */
294 static struct sonypi_event sonypi_memorystickev[] = {
295 	{ 0x53, SONYPI_EVENT_MEMORYSTICK_INSERT },
296 	{ 0x54, SONYPI_EVENT_MEMORYSTICK_EJECT },
297 	{ 0, 0 }
298 };
299 
300 /* The set of possible battery events */
301 static struct sonypi_event sonypi_batteryev[] = {
302 	{ 0x20, SONYPI_EVENT_BATTERY_INSERT },
303 	{ 0x30, SONYPI_EVENT_BATTERY_REMOVE },
304 	{ 0, 0 }
305 };
306 
307 struct sonypi_eventtypes {
308 	int			model;
309 	u8			data;
310 	unsigned long		mask;
311 	struct sonypi_event *	events;
312 } sonypi_eventtypes[] = {
313 	{ SONYPI_DEVICE_MODEL_TYPE1, 0, 0xffffffff, sonypi_releaseev },
314 	{ SONYPI_DEVICE_MODEL_TYPE1, 0x70, SONYPI_MEYE_MASK, sonypi_meyeev },
315 	{ SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_LID_MASK, sonypi_lidev },
316 	{ SONYPI_DEVICE_MODEL_TYPE1, 0x60, SONYPI_CAPTURE_MASK, sonypi_captureev },
317 	{ SONYPI_DEVICE_MODEL_TYPE1, 0x10, SONYPI_JOGGER_MASK, sonypi_joggerev },
318 	{ SONYPI_DEVICE_MODEL_TYPE1, 0x20, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
319 	{ SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
320 	{ SONYPI_DEVICE_MODEL_TYPE1, 0x40, SONYPI_PKEY_MASK, sonypi_pkeyev },
321 	{ SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
322 	{ SONYPI_DEVICE_MODEL_TYPE1, 0x40, SONYPI_BATTERY_MASK, sonypi_batteryev },
323 
324 	{ SONYPI_DEVICE_MODEL_TYPE2, 0, 0xffffffff, sonypi_releaseev },
325 	{ SONYPI_DEVICE_MODEL_TYPE2, 0x38, SONYPI_LID_MASK, sonypi_lidev },
326 	{ SONYPI_DEVICE_MODEL_TYPE2, 0x11, SONYPI_JOGGER_MASK, sonypi_joggerev },
327 	{ SONYPI_DEVICE_MODEL_TYPE2, 0x61, SONYPI_CAPTURE_MASK, sonypi_captureev },
328 	{ SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
329 	{ SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
330 	{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_PKEY_MASK, sonypi_pkeyev },
331 	{ SONYPI_DEVICE_MODEL_TYPE2, 0x11, SONYPI_BACK_MASK, sonypi_backev },
332 	{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_HELP_MASK, sonypi_helpev },
333 	{ SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_ZOOM_MASK, sonypi_zoomev },
334 	{ SONYPI_DEVICE_MODEL_TYPE2, 0x20, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev },
335 	{ SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
336 	{ SONYPI_DEVICE_MODEL_TYPE2, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
337 	{ SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
338 
339 	{ 0, 0, 0, 0 }
340 };
341 
342 #define SONYPI_BUF_SIZE	128
343 struct sonypi_queue {
344 	unsigned long head;
345 	unsigned long tail;
346 	unsigned long len;
347 	spinlock_t s_lock;
348 	wait_queue_head_t proc_list;
349 	struct fasync_struct *fasync;
350 	unsigned char buf[SONYPI_BUF_SIZE];
351 };
352 
353 /* We enable input subsystem event forwarding if the input
354  * subsystem is compiled in, but only if sonypi is not into the
355  * kernel and input as a module... */
356 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
357 #if ! (defined(CONFIG_SONYPI) && defined(CONFIG_INPUT_MODULE))
358 #define SONYPI_USE_INPUT
359 #endif
360 #endif
361 
362 /* The name of the Jog Dial for the input device drivers */
363 #define SONYPI_INPUTNAME	"Sony VAIO Jog Dial"
364 
365 struct sonypi_device {
366 	struct pci_dev *dev;
367 	u16 irq;
368 	u16 bits;
369 	u16 ioport1;
370 	u16 ioport2;
371 	u16 region_size;
372 	u16 evtype_offset;
373 	int camera_power;
374 	int bluetooth_power;
375 	struct semaphore lock;
376 	struct sonypi_queue queue;
377 	int open_count;
378 	int model;
379 #ifdef SONYPI_USE_INPUT
380 	struct input_dev jog_dev;
381 #endif
382 #ifdef CONFIG_PM
383 	struct pm_dev *pm;
384 #endif
385 };
386 
387 #define ITERATIONS_LONG		10000
388 #define ITERATIONS_SHORT	10
389 
390 #define wait_on_command(quiet, command, iterations) { \
391 	unsigned int n = iterations; \
392 	while (--n && (command)) \
393 		udelay(1); \
394 	if (!n && (verbose || !quiet)) \
395 		printk(KERN_WARNING "sonypi command failed at %s : %s (line %d)\n", __FILE__, __FUNCTION__, __LINE__); \
396 }
397 
398 #ifdef CONFIG_ACPI
399 #define SONYPI_ACPI_ACTIVE (!acpi_disabled)
400 #else
401 #define SONYPI_ACPI_ACTIVE 0
402 #endif /* CONFIG_ACPI */
403 
404 #endif /* __KERNEL__ */
405 
406 #endif /* _SONYPI_PRIV_H_ */
407